Esempio n. 1
0
////////////////////////////////////////////////////////////////////////////////
// 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;


}
Esempio n. 2
0
////////////////////////////////////////////////////////////////////////////////
// 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;

}
Esempio n. 3
0
////////////////////////////////////////////////////////////////////////////////
// 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;
}
Esempio n. 4
0
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,
           &centers);
    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];
	}
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
////////////////////////////////////////////////////////////////////////////////
// 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;
}