vs2015+opencv3.3.1+ maxflow-v3.01 c++实现Yuri Boykov 的Interactive Graph Cuts

出的结果不理想。 感觉是tlink的权重的计算有问题,以及参数的设置。三个可设置参数是后面的 i j k  。如果你找到了一组好参数请告诉我。

下载地址 http://download.csdn.net/download/li_haoren/10232283

 

 

 

 

 Interactive Graph Cuts  for Optimal Boundary & Region Segmentation of Objects in N-D Images  code

#include "opencv2\imgproc\imgproc.hpp"  // Gaussian Blur
#include "opencv2\core\core.hpp"        // Basic OpenCV structures (cv::Mat, Scalar)
#include <opencv2\highgui\highgui.hpp> // OpenCV window I/O
#include <iostream> // for standard I/O
#include <string>   // for strings
#include <iomanip>  // for controlling float print precision
#include <sstream>  // string to number conversion
#include<vector>
#include<cmath>
#include "graph.h"  //maxflow-v3.01   下载地址 http://vision.csd.uwo.ca/code/maxflow-v3.01.zip 
typedef Graph<int, int, int> GraphType;
using namespace  cv;
using namespace  std;
 int ofexp = 5;//Lambda
double BSigma = 2;//the Sigma of B{p,q}   小边缘越清
double RSigma = 3;//the Sigma of Rp		小号
const string filename = "1.jpg";//照片
bool rButtonDown = false;
bool lButtonDown = false;
int numUsedBins = 0;
float varianceSquared = 0;
int scribbleRadius = 10;
Mat inputImg = imread(filename, 3), showImg = imread(filename, 3);

Mat fgScribbleMask;
Mat bgScribbleMask;

static void onMouse(int event, int x, int y, int, void*)
{
	//cout << "On Mouse: (" << x << "," << y << ")" <<endl;


	if (event == CV_EVENT_LBUTTONDOWN)
	{
		lButtonDown = true;

	}
	else if (event == CV_EVENT_RBUTTONDOWN)
	{
		rButtonDown = true;

	}
	else if (event == CV_EVENT_LBUTTONUP)
	{
		lButtonDown = false;
	}
	else if (event == CV_EVENT_RBUTTONUP)
	{
		rButtonDown = false;
	}
	else if (event == CV_EVENT_MOUSEMOVE)
	{
		if (rButtonDown)
		{
			// scribble the background
			circle(bgScribbleMask, Point(x, y), scribbleRadius, 255, -1);
			circle(showImg, Point(x, y), scribbleRadius, CV_RGB(0, 0, 255), -1);

		}
		else if (lButtonDown)
		{
			// scribble the foreground
			circle(showImg, Point(x, y), scribbleRadius, CV_RGB(255, 0, 0), -1);
			circle(fgScribbleMask, Point(x, y), scribbleRadius, 255, -1);
			//fgScribbleMask.at<char>(y,x)=(char)255;
			// set variables using mask
			//showImg.setTo(redColorElement,fgScribbleMask);

			//showImg.at<Vec3b>(y,x)[0] = 0;
			//showImg.at<Vec3b>(y,x)[1] = 0;
			//showImg.at<Vec3b>(y,x)[2] = 255;
		}

	}


	imshow("draw", showImg);
	imshow("fg mask", fgScribbleMask);
	imshow("bg mask", bgScribbleMask);
}
vector<double> slink(inputImg.cols*inputImg.rows),tlink(inputImg.cols*inputImg.rows);
double k=0;

GraphType *g = new GraphType(inputImg.cols*inputImg.rows, inputImg.cols*inputImg.rows*4);
inline int node1n(int i, int j) { return i*inputImg.cols + j; }
void computnlink() { 

	double weight0=0; double weight1=0; double weight2=0; double weight3=0;
	for (int i = 0; i < inputImg.rows; ++i)
		for (int j = 0; j < inputImg.cols; ++j)
		{
			g->add_node();
		}
	for (int i = 0; i < inputImg.rows; ++i)
		for (int j = 0; j < inputImg.cols; ++j)
		{	
			
			if (i  == 0);
			else {
				 weight0 =
						ofexp*exp(-(pow(inputImg.at<Vec3b>(i, j)[0] - inputImg.at<Vec3b>(i - 1, j)[0], 2) +
						pow(inputImg.at<Vec3b>(i, j)[1] - inputImg.at<Vec3b>(i - 1, j)[1], 2) +
						pow(inputImg.at<Vec3b>(i, j)[2] - inputImg.at<Vec3b>(i - 1, j)[2], 2)) / 6.0 / BSigma / BSigma);
				 g->add_edge(node1n(i, j), node1n(i - 1, j), weight0, weight0);
			}
			if (i + 1 ==inputImg.rows);
			else {
				weight2 =
					ofexp*exp(-(pow(inputImg.at<Vec3b>(i, j)[0] - inputImg.at<Vec3b>(i + 1, j)[0], 2) +
						pow(inputImg.at<Vec3b>(i, j)[1] - inputImg.at<Vec3b>(i + 1, j)[1], 2) +
						pow(inputImg.at<Vec3b>(i, j)[2] - inputImg.at<Vec3b>(i + 1, j)[2], 2)) / 6.0 / BSigma / BSigma);
				g->add_edge(node1n(i, j), node1n(i + 1, j), weight2, weight2);
			}
			if (j==0);
			else {
				weight3 =
					ofexp*exp(-(pow(inputImg.at<Vec3b>(i, j)[0] - inputImg.at<Vec3b>(i , j-1)[0], 2) +
						pow(inputImg.at<Vec3b>(i, j)[1] - inputImg.at<Vec3b>(i , j-1)[1], 2) +
						pow(inputImg.at<Vec3b>(i, j)[2] - inputImg.at<Vec3b>(i , j-1)[2], 2)) / 6.0 / BSigma / BSigma);
				g->add_edge(node1n(i, j), node1n(i , j-1), weight3, weight3);
			}
			if (j + 1 == inputImg.cols);
			else {
				weight1 =
					ofexp*exp(-(pow(inputImg.at<Vec3b>(i, j)[0] - inputImg.at<Vec3b>(i, j +1)[0], 2) +
						pow(inputImg.at<Vec3b>(i, j)[1] - inputImg.at<Vec3b>(i, j + 1)[1], 2) +
						pow(inputImg.at<Vec3b>(i, j)[2] - inputImg.at<Vec3b>(i, j + 1)[2], 2)) / 6.0 / BSigma / BSigma);
				g->add_edge(node1n(i, j), node1n(i, j + 1), weight1, weight1);
			}
			if (k < weight1+ weight0+ weight3+ weight2)
				k = weight1 + weight0 + weight3 + weight2;
		}
	k += 1;
}

Mat greyimg = imread(filename, 0); double gray[256]; double Bgray[256]; double Fgray[256]; double weight1 = 0; double weight2 = 0;
/*weight有问题改动*/void computtlink() {
	 
	for (int i = 0; i < greyimg.rows*greyimg.cols; i++) { 
		++gray[greyimg.at<uchar>(i)];
		if(bgScribbleMask.at<uchar>(i))
		++Bgray[greyimg.at<uchar>(i)];
		if (fgScribbleMask.at<uchar>(i))
		++Fgray[greyimg.at<uchar>(i)];
	}
	cout << greyimg.rows*greyimg.cols<<endl;
	for (int i = 0; i < greyimg.rows*greyimg.cols; i++) {
		
		weight1 = 0; weight2 = 0;
		for (int j = 0; j < 256; j++) {
			weight1 += (!gray[j]) ? 0 : ((Fgray[j] / gray[j])*exp(-1 * (pow(greyimg.at<uchar>(i) - j, 2))/2 / RSigma));
			weight2 += (!gray[j]) ? 0 : ((Bgray[j] / gray[j])*exp(-1 * (pow(greyimg.at<uchar>(i) - j, 2))/2/ RSigma));
			
		}
		if (bgScribbleMask.at<uchar>(i))
			{g->add_tweights(i,   /* capacities */ k, 0); continue;}
		if (fgScribbleMask.at<uchar>(i))
			{g->add_tweights(i,   /* capacities */ 0, k); continue;}

		g->add_tweights(i,   /* capacities */weight2 ,weight1   );
		
	}
}

int main() {
	cout << "在draw上画前景背景,左键红前景,右键蓝背景。然后在input输入s 开始运算" << endl;
	bgScribbleMask.create(2, inputImg.size, CV_8UC1);
	bgScribbleMask = 0; 
	fgScribbleMask.create(2, inputImg.size, CV_8UC1);
	Mat result;
	result.create(2, inputImg.size, CV_8UC1);
	result = 0;
	fgScribbleMask = 0;
	namedWindow("draw");
	imshow("draw", showImg);
	namedWindow("input");
	imshow("input", inputImg); string ii[250];
	for (int i = 1; i < 250; i++)
		ii[i] = i;
	
		setMouseCallback("draw", onMouse, 0); 
		while (1) {
			char key = waitKey(0);
			if (key == 's') {
				double j = 5; int k = 13;for (int i = 1; i < 10; ++++i)
				{
					ofexp = i;//Lambda                               三个可变动参数
					BSigma = j;//the Sigma of B{p,q}   小边缘越清
					RSigma = k;
					computnlink(); computtlink(); int flow = g->maxflow(); printf("Flow = %d\n", flow);
					cout << k;
					for (int i = 0; i < inputImg.rows*inputImg.cols; i++) {
						if (g->what_segment(i)) {

							result.at<uchar>(i) = 255; result.at<uchar>(i) = 255; result.at<uchar>(i) = 255;
						}

					}
					
					namedWindow(ii[i+k*6]);
					imshow(ii[i+k * 6], result);
				}
			}
		}

		return 0;

}

  

posted @ 2018-01-30 18:48  ff_d  阅读(1125)  评论(3编辑  收藏  举报