用分水岭算法分割图片

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include<iostream>
using namespace cv;
using namespace std;


#define WINDOW_NAME "【程序窗口1】"
Mat g_maskImage, g_srcImage;
Point prevPt(-1,-1);
static void on_Mouse(int event,int x,int y,int flags,void*);

int main(int argc, char**argv)
{
	//【1】载入原图并显示,初始化掩膜和灰度图
	g_srcImage = imread("2.jpg",1); 
	imshow(WINDOW_NAME,g_srcImage);
	Mat srcImage, grayImage;
	g_srcImage.copyTo(srcImage);
	cvtColor(g_srcImage, g_maskImage,COLOR_BGR2GRAY);
	cvtColor(g_maskImage, grayImage, COLOR_GRAY2BGR);//也是灰度图啊,和上面那个g_maskImage没什么区别好像
	g_maskImage = Scalar:: all(0);
	//【2】设置鼠标回调函数
	setMouseCallback(WINDOW_NAME,on_Mouse,0);
	//waitKey(0);//这里要加这一个,不然不知道为什么上面的函数就不会运行了,不响应了,因为这样才能把窗口保持住,才能进行操作啊
	while (1)
	{
		//获取键值
		int c = waitKey(0);//当然这里有的话上面那个也可以没有了
		//若按键键值为ESC时,退出
		if ((char)c == 27)  break;
		//若按键值为2时,恢复原图
		if ((char)c == '2')
		{
			g_maskImage = Scalar::all(0);
			srcImage.copyTo(g_srcImage);
			imshow("image",g_srcImage);
		}
		//若检测到按键值为1或者空格,则进行处理
		if ((char)c == '1' || (char)c == ' ')
		{
			//定义一些参数
			int i, j, comCount = 0;
			vector<vector<Point>> contours;
			vector<Vec4i> hierarchy;
			//寻找轮廓
			findContours(g_maskImage,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE);
			//轮廓为空时的处理
			if (contours.empty())
			{
				continue;
			}
			//复制掩模
			Mat maskImage(g_maskImage.size(),CV_32S);
			maskImage = Scalar::all(0);
			//循环绘制轮廓
			for (int index = 0; index >= 0; index = hierarchy[index][0], comCount++)
			{
				drawContours(maskImage, contours, index, Scalar::all(comCount+1), -1, 8, hierarchy, INT_MAX);
			}
			//comCount为0时的处理
			if (comCount == 0) continue;
			//生成随机颜色
			vector<Vec3b> colorTab;
			for (i = 0; i < comCount; i++)
			{
				int b = theRNG().uniform(0,255);
				int g = theRNG().uniform(0, 255);
				int r = theRNG().uniform(0, 255);
				colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
			}
			//计算处理时间并输出到窗口中
			double dTime = (double)getTickCount();
			watershed(srcImage,maskImage);
			dTime = (double)getTickCount() - dTime;
			printf("\t处理时间=%gms\n",dTime*1000./getTickFrequency());
			//双层循环,将分水岭图像遍历存入watershedImage中
			Mat watershedImage(maskImage.size(),CV_8UC3);
			for (i = 0; i < maskImage.rows; i++)
				for (j = 0; j < maskImage.cols; j++)
				{
					int index = maskImage.at<int>(i,j);
					if (index == -1)//区域间
					{
						watershedImage.at<Vec3b>(i, j) = Vec3b(255, 255, 255);
					}
					else if (index <= 0 || index > comCount)//应该是为标记的地方,也就是不确定的地方
						watershedImage.at<Vec3b>(i, j) = Vec3b(0,0,0);
					else//种子的位置?
						watershedImage.at<Vec3b>(i, j) = colorTab[index-1];
				}
				//混合灰度图和分水岭效果图并显示最终的窗口
				watershedImage = watershedImage*0.5 + grayImage*0.5;
				imshow("watershed transform", watershedImage);
		}
	}
	return 0;
}

效果图如下:

要转行人工智能的可以加下面这个公众号:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值