//////////////////////////////////////////////////////////////////////////////// // Uses spatially varying smoothness terms. That is // V(p1,p2,l1,l2) = w_{p1,p2}*[min((l1-l2)*(l1-l2),4)], with // w_{p1,p2} = p1+p2 if |p1-p2| == 1 and w_{p1,p2} = p1*p2 if |p1-p2| is not 1 void GridGraph_DArraySArraySpatVarying(int width,int height,int num_pixels,int num_labels) { int *result = new int[num_pixels]; // stores result of optimization // first set up the array for data costs int *data = new int[num_pixels*num_labels]; for ( int i = 0; i < num_pixels; i++ ) for (int l = 0; l < num_labels; l++ ) if (i < 25 ){ if( l == 0 ) data[i*num_labels+l] = 0; else data[i*num_labels+l] = 10; } else { if( l == 5 ) data[i*num_labels+l] = 0; else data[i*num_labels+l] = 10; } // next set up the array for smooth costs int *smooth = new int[num_labels*num_labels]; for ( int l1 = 0; l1 < num_labels; l1++ ) for (int l2 = 0; l2 < num_labels; l2++ ) smooth[l1+l2*num_labels] = (l1-l2)*(l1-l2) <= 4 ? (l1-l2)*(l1-l2):4; // next set up spatially varying arrays V and H int *V = new int[num_pixels]; int *H = new int[num_pixels]; for ( int i = 0; i < num_pixels; i++ ){ H[i] = i+(i+1)%3; V[i] = i*(i+width)%7; } try{ GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width,height,num_labels); gc->setDataCost(data); gc->setSmoothCostVH(smooth,V,H); printf("\nBefore optimization energy is %d",gc->compute_energy()); gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations); printf("\nAfter optimization energy is %d",gc->compute_energy()); for ( int i = 0; i < num_pixels; i++ ) result[i] = gc->whatLabel(i); delete gc; } catch (GCException e){ e.Report(); } delete [] result; delete [] smooth; delete [] data; }
//////////////////////////////////////////////////////////////////////////////// // in this version, set data and smoothness terms using arrays // grid neighborhood structure is assumed // void GridGraph_DfnSfn(int width,int height,int num_pixels,int num_labels) { int *result = new int[num_pixels]; // stores result of optimization // first set up the array for data costs int *data = new int[num_pixels*num_labels]; for ( int i = 0; i < num_pixels; i++ ) for (int l = 0; l < num_labels; l++ ) if (i < 25 ){ if( l == 0 ) data[i*num_labels+l] = 0; else data[i*num_labels+l] = 10; } else { if( l == 5 ) data[i*num_labels+l] = 0; else data[i*num_labels+l] = 10; } try{ GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width,height,num_labels); // set up the needed data to pass to function for the data costs ForDataFn toFn; toFn.data = data; toFn.numLab = num_labels; gc->setDataCost(&dataFn,&toFn); // smoothness comes from function pointer gc->setSmoothCost(&smoothFn); printf("\nBefore optimization energy is %d",gc->compute_energy()); gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations); printf("\nAfter optimization energy is %d",gc->compute_energy()); for ( int i = 0; i < num_pixels; i++ ) result[i] = gc->whatLabel(i); delete gc; } catch (GCException e){ e.Report(); } delete [] result; delete [] data; }
//////////////////////////////////////////////////////////////////////////////// // smoothness and data costs are set up one by one, individually // grid neighborhood structure is assumed // void GridGraph_Individually(int width,int height,int num_pixels,int num_labels) { int *result = new int[num_pixels]; // stores result of optimization try{ GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width,height,num_labels); // first set up data costs individually for ( int i = 0; i < num_pixels; i++ ) for (int l = 0; l < num_labels; l++ ) if (i < 25 ){ if( l == 0 ) gc->setDataCost(i,l,0); else gc->setDataCost(i,l,10); } else { if( l == 5 ) gc->setDataCost(i,l,0); else gc->setDataCost(i,l,10); } // next set up smoothness costs individually for ( int l1 = 0; l1 < num_labels; l1++ ) for (int l2 = 0; l2 < num_labels; l2++ ){ int cost = (l1-l2)*(l1-l2) <= 4 ? (l1-l2)*(l1-l2):4; gc->setSmoothCost(l1,l2,cost); } printf("\nBefore optimization energy is %d",gc->compute_energy()); gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations); printf("\nAfter optimization energy is %d",gc->compute_energy()); for ( int i = 0; i < num_pixels; i++ ) result[i] = gc->whatLabel(i); delete gc; } catch (GCException e){ e.Report(); } delete [] result; }
void graphcut(Mat& featureVec, Mat& im, int num_lables) { Mat lables, centers; cout << "Kmeans: #centers = "<<num_lables<<",#tries = 2..."; kmeans(featureVec, num_lables, lables, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,200,0.0001), 2, KMEANS_PP_CENTERS, ¢ers); cout << "Done" << endl; for(int i=0; i<num_lables; i++) { cout << "center "<<i<<": "; for(int j=0; j<centers.cols; j++) cout << centers.at<float>(i,j)<<","; cout << endl; } #ifdef BTM_DEBUG { Mat _tmp = lables.reshape(1,im.rows); Mat _tmpUC; _tmp.convertTo(_tmpUC,CV_8UC1,255.0/(double)num_lables); imshow("tmp", _tmpUC); waitKey(); } #endif GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(im.cols,im.rows,num_lables); Mat _d(featureVec.size(),CV_32FC1); for(int center = 0; center < num_lables; center++) { _d.setTo(Scalar(0)); int count = 0; for(int i=0,ii=0; i<featureVec.rows; i++) { if(((int*)lables.data)[i] == center) { float* dptr = (float*)(_d.data + _d.step * (ii++)); float* fptr = (float*)(featureVec.data + featureVec.step * i); for(int j=0; j<featureVec.cols; j++) { dptr[j] = fptr[j]; } count++; } } Mat d = _d(Rect(0,0,_d.cols,count)); Mat covar; calcCovarMatrix(d,covar,Mat(),CV_COVAR_NORMAL+CV_COVAR_ROWS,CV_32F); Mat icv = covar.inv(); Mat centerRepeat; repeat(centers(Rect(0,center,centers.cols,1)),featureVec.rows,1,centerRepeat); Mat diff = featureVec - centerRepeat; //difference between each pixel's value and it's center's value Mat A = (diff*icv).mul(diff) * 0.5f; for(int i=0; i<A.rows; i++) { float* _ptr = (float*)(A.data + A.step * i); float cost = 0; for(int j=0; j<A.cols; j++) { cost += _ptr[j]; } int icost = MAX(0,(int)floor(-log(cost))); gc->setDataCost(i,center+1,icost); } } //int *smooth = new int[num_lables*num_lables]; //int cost; //for ( int l1 = 0; l1 < num_lables; l1++ ) // for (int l2 = 0; l2 < num_lables; l2++ ){ // cost = (l1-l2)*(l1-l2) <= 4 ? (l1-l2)*(l1-l2):4; // //Mat _a = centers(Rect(0,l1,centers.cols,1)) - centers(Rect(0,l2,centers.cols,1)); // //float n = (float)norm(_a); // //if(n==0) cost = 0; // //else cost = (int)ceil(-log(n)); // smooth[l1+l2*num_lables] = cost; // } //Mat gk = getGaussianKernel(3,-1,CV_32F); //gk = gk * gk.t(); //cv::Sobel(gk,gk,-1,1,0); Mat gray; cvtColor(im,gray,CV_RGB2GRAY); //imshow("tmp",gray); waitKey(); gray.convertTo(gray,CV_32FC1,1.0f/255.0f); //imshow("tmp",gray); waitKey(); Mat grayInt,grayInt1; { Mat _tmp; //filter2D(gray,_tmp,CV_32F,gk); Sobel(gray,_tmp,-1,1,0); //sobel for dx //Canny(gray,_tmp,50.0,150.0); _tmp = abs(_tmp); #ifdef BTM_DEBUG imshow("tmp",_tmp); waitKey(); #endif double maxVal,minVal; minMaxLoc(_tmp,&minVal,&maxVal); cv::log((_tmp - minVal) / (maxVal - minVal),_tmp); _tmp = -_tmp * 0.35; _tmp.convertTo(grayInt,CV_32FC1); //grayInt = grayInt * 5; //filter2D(gray,_tmp,CV_32F,gk.t()); Sobel(gray,_tmp,-1,0,1); //sobel for dy //Canny(gray,_tmp,50.0,150.0); _tmp = abs(_tmp); #ifdef BTM_DEBUG imshow("tmp",_tmp); waitKey(); #endif minMaxLoc(_tmp,&minVal,&maxVal); cv::log((_tmp - minVal) / (maxVal - minVal),_tmp); _tmp = -_tmp * 0.35; _tmp.convertTo(grayInt1,CV_32FC1); //grayInt1 = grayInt1 * 5; } //// next set up spatially varying arrays V and H //int *V = new int[featureVec.rows]; //int *H = new int[featureVec.rows]; // //for ( int i = 0; i < featureVec.rows; i++ ){ // //H[i] = i+(i+1)%im.rows; // //V[i] = i*(i+im.cols)%im.cols; // H[i] = 1; // V[i] = 1; //} Mat Sc = 10.0 * (Mat::ones(num_lables,num_lables,CV_32FC1) - Mat::eye(num_lables,num_lables,CV_32FC1)); gc->setSmoothCostVH((float*)(Sc.data),(float*)grayInt.data,(float*)grayInt1.data); //gc->setSmoothCost((int*)(Sc.data)); while(true) { printf("\nBefore optimization energy is %d",gc->compute_energy()); gc->expansion(1);// run expansion for 2 iterations. For swap use gc->swap(num_iterations); printf("\nAfter optimization energy is %d",gc->compute_energy()); for ( int i = 0; i < featureVec.rows; i++ ) ((int*)(lables.data + lables.step * i))[0] = gc->whatLabel(i); { Mat _tmp = lables.reshape(1,im.rows); #ifdef BTM_DEBUG { Mat _tmpUC; _tmp.convertTo(_tmpUC,CV_8UC1,255.0/(double)num_lables); vector<Mat> chns; split(im,chns); for(unsigned int ch=0; ch<chns.size(); ch++) { chns[ch] = /*chns[ch] + */(_tmp == ch)/**0.5*/; } cv::merge(chns,_tmpUC); imshow("tmp", _tmpUC); int c = waitKey(); if(c=='q') break; } #endif } } delete gc; //delete[] smooth; //delete[] V; //delete[] H; //printf("%d\n",reshaped.rows); }
void mexFunctionReal( int nlhs, /* number of expected outputs */ mxArray *plhs[], /* mxArray output pointer array */ int nrhs, /* number of inputs */ const mxArray *prhs[] /* mxArray input pointer array */) { // // Get input // ASSERT( nlhs == 2 && nrhs == 10); matrix<double> mxC1 = prhs[0]; matrix<double> mxC2 = prhs[1]; matrix<float> mxKP1 = prhs[2]; matrix<float> mxKP2 = prhs[3]; matrix<double> mxKPSize1 = prhs[4]; matrix<double> mxKPSize2 = prhs[5]; matrix<double> mxIrange = prhs[6]; matrix<double> mxJrange = prhs[7]; matrix<int> mxShiftI = prhs[8]; matrix<int> mxShiftJ = prhs[9]; ASSERT( mxC1.O == 3 ); ASSERT( mxC2.O == 3 ); ASSERT( mxKPSize1.numel() == 2 ); ASSERT( mxKPSize2.numel() == 2 ); ASSERT( mxIrange.numel() == 2 ); ASSERT( mxJrange.numel() == 2 ); M1 = mxKPSize1[0]; N1 = mxKPSize1[1]; M2 = mxKPSize2[0]; N2 = mxKPSize2[1]; ASSERT( mxC1.M == M1 && mxC1.N == N1); // fulhack ASSERT( mxC2.M == M2 && mxC2.N == N2); ASSERT( mxShiftI.M == M1 && mxShiftI.N == N1); ASSERT( mxShiftJ.M == M1 && mxShiftJ.N == N1); ASSERT( mxKP1.numel() == kpLength*M1*N1); ASSERT( mxKP2.numel() == kpLength*M2*N2); // // Range of shifts to consider // ASSERT(mxIrange[0]>=-std::max(M1,M2)+1 && mxIrange[1]<=std::max(M1,M2)-1); ASSERT(mxJrange[0]>=-std::max(N1,N2)+1 && mxJrange[1]<=std::max(N1,N2)-1); max_shift_i = mxIrange[1]; min_shift_i = mxIrange[0]; max_shift_j = mxJrange[1]; min_shift_j = mxJrange[0]; // Compute number of labels const int num_labels = (max_shift_i-min_shift_i+1)*(max_shift_j-min_shift_j+1); mexPrintf("Shift-map %d x %d with %d labels\n",M1,N1,num_labels); mexPrintf("I-range %d ... %d \n",min_shift_i,max_shift_i); mexPrintf("J-range %d ... %d \n",min_shift_j,max_shift_j); // // Create graph // GCoptimizationGridGraph gc_obj(M1,N1,num_labels); GCoptimizationGridGraph* gc = &gc_obj; // set up the needed data to pass to function for the data costs ForDataFn toFn; toFn.c1 = mxC1; toFn.c2 = mxC2; toFn.kp1 = mxKP1; toFn.kp2 = mxKP2; toFn.shiftI = mxShiftI; toFn.shiftJ = mxShiftJ; gc->setDataCost(&dataFn,&toFn); gc->setSmoothCost(&smoothFn, &toFn); // Initialize shift-map to 0 mexPrintf("Starting shift-map: di=0, dj=0\n"); int zero_label = shift2lab(0,0); for (int i=0;i<M1*N1;++i) { gc->setLabel(i,zero_label); } // Print energy informaion double energy = gc->compute_energy(); double dataEnergy = gc->giveDataEnergy(); double smoothEnergy = gc->giveSmoothEnergy(); mexPrintf("Start energy : %16.0f\n",energy); mexPrintf("Start data : %16.0f\n",dataEnergy); mexPrintf("Start smooth : %16.0f\n",smoothEnergy); mexPrintf("Stopping when old_energy*%f < new_energy.\n",cutoff); flush_output(); double old_energy = energy/cutoff + 1; int iter = 1; startTime(); while ( cutoff*old_energy > energy && iter <= 100) { old_energy = energy; //energy = gc->expansion(1); for (int lab=0; lab < num_labels; lab++ ) { gc->alpha_expansion(lab); } energy = gc->compute_energy(); dataEnergy = gc->giveDataEnergy(); smoothEnergy = gc->giveSmoothEnergy(); double time_taken = endTime(); // Measure the time taken since last call to endtime mexPrintf("Iteration %3d: T:%16.0f D:%16.0f S:%16.0f time: %.2f sec\n",iter,energy,dataEnergy,smoothEnergy,time_taken); iter++; endTime(); //Don't measure the time taken by the output } mexPrintf("Final energy : %16.0f\n",gc->compute_energy()); // // Create output // matrix<int> shiftI_out(M1,N1); matrix<int> shiftJ_out(M1,N1); plhs[0] = shiftI_out; plhs[1] = shiftJ_out; for ( int ind = 0; ind < M1*N1; ind++ ) { int di,dj; int lab = gc->whatLabel(ind); lab2shift(lab,di,dj); shiftI_out[ind] = di + mxShiftI[ind]; shiftJ_out[ind] = dj + mxShiftJ[ind]; } }
void GraphCut::GridGraph_Individually(int width,int height,int num_pixels,int num_labels) { int *result = new int[num_pixels]; // stores result of optimization try{ GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width,height,num_labels); std::vector<cv::Vec3b>::iterator it; for ( int i = 0; i < num_pixels; i++ ){ int currentRow = i/this->rawImage.cols; int currentCol = i%this->rawImage.cols; //////////////////////////直接使用initGuess,start cv::Vec3b currentValue = this->initGuess.at<cv::Vec3b>(currentRow,currentCol); it = std::find(this->label2Value.begin(), this->label2Value.end(), currentValue); int label = it - this->label2Value.begin(); for(int labelIndex = 0; labelIndex < this->CLASS_NUMBER; labelIndex++){ if(label == labelIndex){ gc->setDataCost(i,labelIndex,1); }else{ gc->setDataCost(i,labelIndex,4); } } //////////////////////////直接使用initGuess,end //////////////////////////使用GMM,start /*for(int labelIndex = 0; labelIndex < this->CLASS_NUMBER; labelIndex++){ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// double gmmProbability = this->GMMProbability.at<cv::Vec<double,3> >(currentRow,currentCol)[labelIndex]; gc->setDataCost(i,labelIndex,1*-log(gmmProbability)); }*/ //////////////////////////使用GMM,end } // next set up smoothness costs individually for ( int l1 = 0; l1 < num_labels; l1++ ){ for (int l2 = 0; l2 < num_labels; l2++ ){ int cost = (l1-l2)*(l1-l2) <= 32 ? 2*(l1-l2)*(l1-l2):32; gc->setSmoothCost(l1,l2,5*cost); } } //printf("\nBefore optimization energy is %d",static_cast<int>(gc->compute_energy())); //gc->expansion(5);// run expansion for 2 iterations. For swap use gc->swap(num_iterations); gc->swap(5); //printf("\nAfter optimization energy is %d\n",static_cast<int>(gc->compute_energy())); for ( int i = 0; i < num_pixels; i++ ){ result[i] = gc->whatLabel(i); this->resultLabel.at<cv::Vec3b>(i/this->resultLabel.cols, i%this->resultLabel.cols) = this->label2Value.at(result[i]); } delete gc; } catch (GCException e){ e.Report(); } delete [] result; }
//////////////////////////////////////////////////////////////////////////////// // smoothness and data costs are set up one by one, individually // grid neighborhood structure is assumed // Mat GridGraph_Individually(int num_labels,Mat img,int lambda) { int height=img.rows;//HEIGHT int width=img.cols;//width int num_pixels=height*width; int *result = new int[num_pixels]; // stores result of optimization int rw; int col; Mat opimage =img.clone(); //image is transformed int 1 drow in row major order try{ GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width,height,num_labels); // first set up data costs individually for ( int i = 0; i < num_pixels; i++ ) { if((i+1)%width==0 ) { rw=((i+1)/width)-1; col=width-1; } else { rw=(i+1)/width; col=((i+1)%width)-1; } int blue=img.at<cv::Vec3b>(rw,col)[0]; int green=img.at<cv::Vec3b>(rw,col)[1]; int red=img.at<cv::Vec3b>(rw,col)[2]; for (int l = 0; l < num_labels; l++ ) { if(l==0) gc->setDataCost(i,l,(255-blue)/*+red+green*/); if(l==1) gc->setDataCost(i,l,(255-green)/*+red+blue*/); if(l==2) gc->setDataCost(i,l,(255-red)/*+blue+green*/); } } // next set up smoothness costs individually for ( int l1 = 0; l1 < num_labels; l1++ ) for (int l2 = 0; l2 < num_labels; l2++ ) { if(l1==l2) //int cost = (l1-l2)*(l1-l2) <= 4 ? (l1-l2)*(l1-l2):4; gc->setSmoothCost(l1,l2,0); else gc->setSmoothCost(l1,l2,lambda); } //printf("\nBefore optimization energy is %d",gc->compute_energy()); gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations); //printf("\nAfter optimization energy is %d",gc->compute_energy()); for ( int i = 0; i < num_pixels; i++ ) { result[i] = gc->whatLabel(i); if((i+1)%width==0 ) { rw=((i+1)/width)-1; col=width-1; } else { rw=(i+1)/width; col=((i+1)%width)-1; } if(result[i]==0) //sky { //cout<<"label 0 \n"; opimage.at<cv::Vec3b>(rw,col)[0]=255;//blue opimage.at<cv::Vec3b>(rw,col)[1]=0; opimage.at<cv::Vec3b>(rw,col)[2]=0; } if(result[i]==1) // grass { opimage.at<cv::Vec3b>(rw,col)[0]=0; opimage.at<cv::Vec3b>(rw,col)[1]=255; opimage.at<cv::Vec3b>(rw,col)[2]=0; //cout<<"label 1 \n"; } if(result[i]==2) //third object { opimage.at<cv::Vec3b>(rw,col)[0]=0; opimage.at<cv::Vec3b>(rw,col)[1]=0; opimage.at<cv::Vec3b>(rw,col)[2]=255;//red } } //imwrite( "outputimage.png", opimage ); delete gc; } catch (GCException e) { e.Report(); } delete [] result; return opimage; }