static CvMat* extractEdges( IplImage* img, image_type_t source ) { CvMat* temp_16sc; CvMat* temp_8uc; CvMat* edges; edges = cvCreateMat( img->height, img->width, CV_8UC1 ); temp_16sc = cvCreateMat( img->height, img->width, CV_16SC1 ); temp_8uc = cvCreateMat( img->height, img->width, CV_8UC1 ); cvZero(edges); void accumulateEdgesFromChannel( int channel ) { if( channel > 0 ) cvSetImageCOI( img, channel ); cvCopy(img, temp_8uc, NULL); // needed only becaues cvLaplace() doesn't support COI if( source == PHOTO ) cvSmooth(temp_8uc, temp_8uc, CV_GAUSSIAN, PHOTO_PRESMOOTH, PHOTO_PRESMOOTH, 0.0, 0.0); cvLaplace(temp_8uc, temp_16sc, 3); cvAbs( temp_16sc, temp_16sc ); cvAdd( edges, temp_16sc, edges, NULL); } if( img->nChannels == 1 ) accumulateEdgesFromChannel( -1 ); else if( source != PHOTO ) accumulateEdgesFromChannel( 1 ); else for(int i = 0; i < 3; i++) accumulateEdgesFromChannel( i+1 ); cvReleaseMat(&temp_16sc); cvReleaseMat(&temp_8uc); return edges; }
//------------------------------------------------------------------------------ // Color Similarity Matrix Calculation //------------------------------------------------------------------------------ CvMat *colorsim(int nbins, double sigma) { CvMat *xc=cvCreateMat(1,nbins, CV_32FC1); CvMat *yr=cvCreateMat(nbins,1, CV_32FC1); CvMat *x=cvCreateMat(nbins,nbins, CV_32FC1); CvMat *y=cvCreateMat(nbins,nbins, CV_32FC1); CvMat *m=cvCreateMat(x->rows,x->rows, CV_32FC1); // Set x,y directions for (int j=0;j<nbins;j++) { cvSetReal2D(xc,0,j,(j+1-0.5)/nbins); cvSetReal2D(yr,j,0,(j+1-0.5)/nbins); } // Set u,v, meshgrids for (int i=0;i<x->rows;i++) { cvRepeat(xc,x); cvRepeat(yr,y); } CvMat *sub = cvCreateMat(x->rows,y->cols,CV_32FC1); cvSub(x,y,sub); cvAbs(sub,sub); cvMul(sub,sub,sub); cvConvertScale(sub,sub,-1.0/(2*sigma*sigma)); cvExp(sub,sub); cvSubRS(sub,cvScalar(1.0),m); cvReleaseMat(&xc); cvReleaseMat(&yr); cvReleaseMat(&x); cvReleaseMat(&y); cvReleaseMat(&sub); return m; }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ CvMat *tgso (CvMat &tmap, int ntex, double sigma, double theta, CvMat &tsim, int useChi2) { CvMat *roundTmap=cvCreateMat(tmap.rows,tmap.cols,CV_32FC1); CvMat *comp=cvCreateMat(tmap.rows,tmap.cols,CV_32FC1); for (int i=0;i<tmap.rows;i++) for (int j=0;j<tmap.cols;j++) cvSetReal2D(roundTmap,i,j,cvRound(cvGetReal2D(&tmap,i,j))); cvSub(&tmap,roundTmap,comp); if (cvCountNonZero(comp)) { printf("texton labels not integral"); cvReleaseMat(&roundTmap); cvReleaseMat(&comp); exit(1); } double min,max; cvMinMaxLoc(&tmap,&min,&max); if (min<1 && max>ntex) { char *msg=new char[50]; printf(msg,"texton labels out of range [1,%d]",ntex); cvReleaseMat(&roundTmap); cvReleaseMat(&comp); exit(1); } cvReleaseMat(&roundTmap); cvReleaseMat(&comp); double wr=floor(sigma); //sigma=radius (Leo) CvMat *x=cvCreateMat(1,wr-(-wr)+1, CV_64FC1); CvMat *y=cvCreateMat(wr-(-wr)+1,1, CV_64FC1); CvMat *u=cvCreateMat(wr-(-wr)+1,wr-(-wr)+1, CV_64FC1); CvMat *v=cvCreateMat(wr-(-wr)+1,wr-(-wr)+1, CV_64FC1); CvMat *gamma=cvCreateMat(u->rows,v->rows, CV_64FC1); // Set x,y directions for (int j=-wr;j<=wr;j++) { cvSetReal2D(x,0,(j+wr),j); cvSetReal2D(y,(j+wr),0,j); } // Set u,v, meshgrids for (int i=0;i<u->rows;i++) { cvRepeat(x,u); cvRepeat(y,v); } // Compute the gamma matrix from the grid for (int i=0;i<u->rows;i++) for (int j=0;j<u->cols;j++) cvSetReal2D(gamma,i,j,atan2(cvGetReal2D(v,i,j),cvGetReal2D(u,i,j))); cvReleaseMat(&x); cvReleaseMat(&y); CvMat *sum=cvCreateMat(u->rows,u->cols, CV_64FC1); cvMul(u,u,u); cvMul(v,v,v); cvAdd(u,v,sum); CvMat *mask=cvCreateMat(u->rows,u->cols, CV_8UC1); cvCmpS(sum,sigma*sigma,mask,CV_CMP_LE); cvConvertScale(mask,mask,1.0/255); cvSetReal2D(mask,wr,wr,0); int count=cvCountNonZero(mask); cvReleaseMat(&u); cvReleaseMat(&v); cvReleaseMat(&sum); CvMat *sub=cvCreateMat(mask->rows,mask->cols, CV_64FC1); CvMat *side=cvCreateMat(mask->rows,mask->cols, CV_8UC1); cvSubS(gamma,cvScalar(theta),sub); cvReleaseMat(&gamma); for (int i=0;i<mask->rows;i++){ for (int j=0;j<mask->cols;j++) { double n=cvmGet(sub,i,j); double n_mod = n-floor(n/(2*M_PI))*2*M_PI; cvSetReal2D(side,i,j, 1 + int(n_mod < M_PI)); } } cvMul(side,mask,side); cvReleaseMat(&sub); cvReleaseMat(&mask); CvMat *lmask=cvCreateMat(side->rows,side->cols, CV_8UC1); CvMat *rmask=cvCreateMat(side->rows,side->cols, CV_8UC1); cvCmpS(side,1,lmask,CV_CMP_EQ); cvCmpS(side,2,rmask,CV_CMP_EQ); int count1=cvCountNonZero(lmask), count2=cvCountNonZero(rmask); if (count1 != count2) { printf("Bug: imbalance\n"); } CvMat *rlmask=cvCreateMat(side->rows,side->cols, CV_32FC1); CvMat *rrmask=cvCreateMat(side->rows,side->cols, CV_32FC1); cvConvertScale(lmask,rlmask,1.0/(255*count)*2); cvConvertScale(rmask,rrmask,1.0/(255*count)*2); cvReleaseMat(&lmask); cvReleaseMat(&rmask); cvReleaseMat(&side); int h=tmap.rows; int w=tmap.cols; CvMat *d = cvCreateMat(h*w,ntex,CV_32FC1); CvMat *coltemp = cvCreateMat(h*w,1,CV_32FC1); CvMat *tgL = cvCreateMat(h,w, CV_32FC1); CvMat *tgR = cvCreateMat(h,w, CV_32FC1); CvMat *temp = cvCreateMat(h,w,CV_8UC1); CvMat *im = cvCreateMat(h,w, CV_32FC1); CvMat *sub2 = cvCreateMat(h,w,CV_32FC1); CvMat *sub2t = cvCreateMat(w,h,CV_32FC1); CvMat *prod = cvCreateMat(h*w,ntex,CV_32FC1); CvMat reshapehdr,*reshape; CvMat* tgL_pad = cvCreateMat(h+rlmask->rows-1,w+rlmask->cols-1,CV_32FC1); CvMat* tgR_pad = cvCreateMat(h+rlmask->rows-1,w+rlmask->cols-1,CV_32FC1); CvMat* im_pad = cvCreateMat(h+rlmask->rows-1,w+rlmask->cols-1,CV_32FC1); CvMat *tg=cvCreateMat(h,w,CV_32FC1); cvZero(tg); if (useChi2 == 1){ CvMat* temp_add1 = cvCreateMat(h,w,CV_32FC1); for (int i=0;i<ntex;i++) { cvCmpS(&tmap,i+1,temp,CV_CMP_EQ); cvConvertScale(temp,im,1.0/255); cvCopyMakeBorder(tgL,tgL_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT); cvCopyMakeBorder(tgR,tgR_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT); cvCopyMakeBorder(im,im_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT); cvFilter2D(im_pad,tgL_pad,rlmask,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2)); cvFilter2D(im_pad,tgR_pad,rrmask,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2)); cvGetSubRect(tgL_pad,tgL,cvRect((rlmask->cols-1)/2,(rlmask->rows-1)/2,tgL->cols,tgL->rows)); cvGetSubRect(tgR_pad,tgR,cvRect((rlmask->cols-1)/2,(rlmask->rows-1)/2,tgR->cols,tgR->rows)); cvSub(tgL,tgR,sub2); cvPow(sub2,sub2,2.0); cvAdd(tgL,tgR,temp_add1); cvAddS(temp_add1,cvScalar(0.0000000001),temp_add1); cvDiv(sub2,temp_add1,sub2); cvAdd(tg,sub2,tg); } cvScale(tg,tg,0.5); cvReleaseMat(&temp_add1); } else{// if not chi^2 for (int i=0;i<ntex;i++) { cvCmpS(&tmap,i+1,temp,CV_CMP_EQ); cvConvertScale(temp,im,1.0/255); cvCopyMakeBorder(tgL,tgL_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT); cvCopyMakeBorder(tgR,tgR_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT); cvCopyMakeBorder(im,im_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT); cvFilter2D(im_pad,tgL_pad,rlmask,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2)); cvFilter2D(im_pad,tgR_pad,rrmask,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2)); cvGetSubRect(tgL_pad,tgL,cvRect((rlmask->cols-1)/2,(rlmask->rows-1)/2,tgL->cols,tgL->rows)); cvGetSubRect(tgR_pad,tgR,cvRect((rlmask->cols-1)/2,(rlmask->rows-1)/2,tgR->cols,tgR->rows)); cvSub(tgL,tgR,sub2); cvAbs(sub2,sub2); cvTranspose(sub2,sub2t); reshape=cvReshape(sub2t,&reshapehdr,0,h*w); cvGetCol(d,coltemp,i); cvCopy(reshape,coltemp); } cvMatMul(d,&tsim,prod); cvMul(prod,d,prod); CvMat *sumcols=cvCreateMat(h*w,1,CV_32FC1); cvSetZero(sumcols); for (int i=0;i<prod->cols;i++) { cvGetCol(prod,coltemp,i); cvAdd(sumcols,coltemp,sumcols); } reshape=cvReshape(sumcols,&reshapehdr,0,w); cvTranspose(reshape,tg); cvReleaseMat(&sumcols); } //Smooth the gradient now!! tg=fitparab(*tg,sigma,sigma/4,theta); cvMaxS(tg,0,tg); cvReleaseMat(&im_pad); cvReleaseMat(&tgL_pad); cvReleaseMat(&tgR_pad); cvReleaseMat(&rlmask); cvReleaseMat(&rrmask); cvReleaseMat(&im); cvReleaseMat(&tgL); cvReleaseMat(&tgR); cvReleaseMat(&temp); cvReleaseMat(&coltemp); cvReleaseMat(&sub2); cvReleaseMat(&sub2t); cvReleaseMat(&d); cvReleaseMat(&prod); return tg; }
IplImage* ComputeSaliency(IplImage* image, int thresh, int scale) { //given a one channel image unsigned int size = floor(pow(2,scale)); //the size to do teh saliency @ IplImage* bw_im = cvCreateImage(cvSize(size,size), IPL_DEPTH_8U,1); cvResize(image, bw_im); IplImage* realInput = cvCreateImage( cvGetSize(bw_im), IPL_DEPTH_32F, 1); IplImage* imaginaryInput = cvCreateImage( cvGetSize(bw_im), IPL_DEPTH_32F, 1); IplImage* complexInput = cvCreateImage( cvGetSize(bw_im), IPL_DEPTH_32F, 2); cvScale(bw_im, realInput, 1.0/255.0); cvZero(imaginaryInput); cvMerge(realInput, imaginaryInput, NULL, NULL, complexInput); CvMat* dft_A = cvCreateMat( size, size, CV_32FC2 ); // copy A to dft_A and pad dft_A with zeros CvMat tmp; cvGetSubRect( dft_A, &tmp, cvRect(0,0, size,size)); cvCopy( complexInput, &tmp ); // cvZero(&tmp); cvDFT( dft_A, dft_A, CV_DXT_FORWARD, size ); cvSplit( dft_A, realInput, imaginaryInput, NULL, NULL ); // Compute the phase angle IplImage* image_Mag = cvCreateImage(cvSize(size, size), IPL_DEPTH_32F, 1); IplImage* image_Phase = cvCreateImage(cvSize(size, size), IPL_DEPTH_32F, 1); //compute the phase of the spectrum cvCartToPolar(realInput, imaginaryInput, image_Mag, image_Phase, 0); IplImage* log_mag = cvCreateImage(cvSize(size, size), IPL_DEPTH_32F, 1); cvLog(image_Mag, log_mag); //Box filter the magnitude, then take the difference IplImage* log_mag_Filt = cvCreateImage(cvSize(size, size), IPL_DEPTH_32F, 1); CvMat* filt = cvCreateMat(3,3, CV_32FC1); cvSet(filt,cvScalarAll(1.0/9.0)); cvFilter2D(log_mag, log_mag_Filt, filt); cvReleaseMat(&filt); cvSub(log_mag, log_mag_Filt, log_mag); cvExp(log_mag, image_Mag); cvPolarToCart(image_Mag, image_Phase, realInput, imaginaryInput,0); cvExp(log_mag, image_Mag); cvMerge(realInput, imaginaryInput, NULL, NULL, dft_A); cvDFT( dft_A, dft_A, CV_DXT_INV_SCALE, size); cvAbs(dft_A, dft_A); cvMul(dft_A,dft_A, dft_A); cvGetSubRect( dft_A, &tmp, cvRect(0,0, size,size)); cvCopy( &tmp, complexInput); cvSplit(complexInput, realInput, imaginaryInput, NULL,NULL); IplImage* result_image = cvCreateImage(cvGetSize(image),IPL_DEPTH_32F, 1); double minv, maxv; CvPoint minl, maxl; cvSmooth(realInput,realInput); cvSmooth(realInput,realInput); cvMinMaxLoc(realInput,&minv,&maxv,&minl,&maxl); printf("Max value %lf, min %lf\n", maxv,minv); cvScale(realInput, realInput, 1.0/(maxv-minv), 1.0*(-minv)/(maxv-minv)); cvResize(realInput, result_image); double threshold = thresh/100.0*cvAvg(realInput).val[0]; cvThreshold(result_image, result_image, threshold, 1.0, CV_THRESH_BINARY); IplImage* final_result = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U, 1); cvScale(result_image, final_result, 255.0, 0.0); cvReleaseImage(&result_image); //cvReleaseImage(&realInput); cvReleaseImage(&imaginaryInput); cvReleaseImage(&complexInput); cvReleaseMat(&dft_A); cvReleaseImage(&bw_im); cvReleaseImage(&image_Mag); cvReleaseImage(&image_Phase); cvReleaseImage(&log_mag); cvReleaseImage(&log_mag_Filt); cvReleaseImage(&bw_im); return final_result; //return bw_im; }
UINT WINAPI //DWORD WINAPI #elif defined(POSIX_SYS) // using pthread void * #endif ChessRecognition::HoughLineThread( #if defined(WINDOWS_SYS) LPVOID #elif defined(POSIX_SYS) void * #endif Param) { // 실제로 뒤에서 동작하는 windows용 thread함수. // 함수 인자로 클래스를 받아옴. ChessRecognition *_TChessRecognition = (ChessRecognition *)Param; _TChessRecognition->_HoughLineBased = new HoughLineBased(); CvSeq *_TLineX, *_TLineY; double _TH[] = { -1, -7, -15, 0, 15, 7, 1 }; CvMat _TDoGX = cvMat(1, 7, CV_64FC1, _TH); CvMat* _TDoGY = cvCreateMat(7, 1, CV_64FC1); cvTranspose(&_TDoGX, _TDoGY); // transpose(&DoGx) -> DoGy double _TMinValX, _TMaxValX, _TMinValY, _TMaxValY, _TMinValT, _TMaxValT; int _TKernel = 1; // Hough 사용되는 Image에 대한 Initialize. IplImage *iplTemp = cvCreateImage(cvSize(_TChessRecognition->_Width, _TChessRecognition->_Height), IPL_DEPTH_32F, 1); IplImage *iplDoGx = cvCreateImage(cvGetSize(iplTemp), IPL_DEPTH_32F, 1); IplImage *iplDoGy = cvCreateImage(cvGetSize(iplTemp), IPL_DEPTH_32F, 1); IplImage *iplDoGyClone = cvCloneImage(iplDoGy); IplImage *iplDoGxClone = cvCloneImage(iplDoGx); IplImage *iplEdgeX = cvCreateImage(cvGetSize(iplTemp), 8, 1); IplImage *iplEdgeY = cvCreateImage(cvGetSize(iplTemp), 8, 1); CvMemStorage* _TStorageX = cvCreateMemStorage(0), *_TStorageY = cvCreateMemStorage(0); while (_TChessRecognition->_EnableThread != false) { // 이미지를 받아옴. main루프와 동기를 맞추기 위해서 critical section 사용. _TChessRecognition->_ChessBoardDetectionInternalImageProtectMutex.lock(); //EnterCriticalSection(&(_TChessRecognition->cs)); cvConvert(_TChessRecognition->_ChessBoardDetectionInternalImage, iplTemp); //LeaveCriticalSection(&_TChessRecognition->cs); _TChessRecognition->_ChessBoardDetectionInternalImageProtectMutex.unlock(); // 각 X축 Y축 라인을 검출해 내기 위해서 filter 적용. cvFilter2D(iplTemp, iplDoGx, &_TDoGX); // 라인만 축출해내고. cvFilter2D(iplTemp, iplDoGy, _TDoGY); cvAbs(iplDoGx, iplDoGx); cvAbs(iplDoGy, iplDoGy); // 이미지 내부에서 최댓값과 최소값을 구하여 정규화. cvMinMaxLoc(iplDoGx, &_TMinValX, &_TMaxValX); cvMinMaxLoc(iplDoGy, &_TMinValY, &_TMaxValY); cvMinMaxLoc(iplTemp, &_TMinValT, &_TMaxValT); cvScale(iplDoGx, iplDoGx, 2.0 / _TMaxValX); // 정규화. cvScale(iplDoGy, iplDoGy, 2.0 / _TMaxValY); cvScale(iplTemp, iplTemp, 2.0 / _TMaxValT); cvCopy(iplDoGy, iplDoGyClone); cvCopy(iplDoGx, iplDoGxClone); // NMS진행후 추가 작업 _TChessRecognition->_HoughLineBased->NonMaximumSuppression(iplDoGx, iplDoGyClone, _TKernel); _TChessRecognition->_HoughLineBased->NonMaximumSuppression(iplDoGy, iplDoGxClone, _TKernel); cvConvert(iplDoGx, iplEdgeY); // IPL_DEPTH_8U로 다시 재변환. cvConvert(iplDoGy, iplEdgeX); double rho = 1.0; // distance resolution in pixel-related units. double theta = 1.0; // angle resolution measured in radians. int threshold = 20; if (threshold == 0) threshold = 1; // detecting 해낸 edge에서 hough line 검출. _TLineX = cvHoughLines2(iplEdgeX, _TStorageX, CV_HOUGH_STANDARD, 1.0 * rho, CV_PI / 180 * theta, threshold, 0, 0); _TLineY = cvHoughLines2(iplEdgeY, _TStorageY, CV_HOUGH_STANDARD, 1.0 * rho, CV_PI / 180 * theta, threshold, 0, 0); // cvSeq를 vector로 바꾸기 위한 연산. _TChessRecognition->_Vec_ProtectionMutex.lock(); _TChessRecognition->_HoughLineBased->CastSequence(_TLineX, _TLineY); _TChessRecognition->_Vec_ProtectionMutex.unlock(); Sleep(2); } // mat 할당 해제. cvReleaseMat(&_TDoGY); // 내부 연산에 사용된 이미지 할당 해제. cvReleaseImage(&iplTemp); cvReleaseImage(&iplDoGx); cvReleaseImage(&iplDoGy); cvReleaseImage(&iplDoGyClone); cvReleaseImage(&iplDoGxClone); cvReleaseImage(&iplEdgeX); cvReleaseImage(&iplEdgeY); // houghline2에 사용된 opencv 메모리 할당 해제. cvReleaseMemStorage(&_TStorageX); cvReleaseMemStorage(&_TStorageY); delete _TChessRecognition->_HoughLineBased; #if defined(WINDOWS_SYS) _endthread(); #elif defined(POSIX_SYS) #endif _TChessRecognition->_EndThread = true; return 0; }