zoukankan      html  css  js  c++  java
  • 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 "opencv2imgprocimgproc.hpp"  // Gaussian Blur
    #include "opencv2corecore.hpp"        // Basic OpenCV structures (cv::Mat, Scalar)
    #include <opencv2highguihighgui.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
    ", 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;
    
    }
    

      

  • 相关阅读:
    C#使用Selenium实现QQ空间数据抓取 说说抓取
    C#使用Selenium实现QQ空间数据抓取 登录QQ空间
    [bug系列]Method not found: 'Void Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommandBuilderFactory
    【原创】CA证书申请+IIS配置HTTPS+默认访问https路径
    【原创】MVC项目中使用JQuery的upladify图片上传插件相关问题的解决方案
    Jquery中$.ajax()方法参数详解
    开发IOS应用真的一定要买苹果电脑设备吗?
    vim全选内容命令
    配置jdk环境变量
    mysql联查中使用if和group by会让你的结果不是你想要的
  • 原文地址:https://www.cnblogs.com/l2017/p/8386583.html
Copyright © 2011-2022 走看看