OpenCV学习(二十) :分水岭算法:watershed()
参考博客:
OpenCV—分水岭算法
图像处理——分水岭算法
OpenCV学习(7) 分水岭算法(1)
Opencv分水岭算法——watershed自动图像分割用法 -牧野-
分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近(求梯度)的像素点互相连接起来构成一个封闭的轮廓。分水岭算法常用的操作步骤:彩色图像灰度化,然后再求梯度图,最后在梯度图的基础上进行分水岭算法,求得分段图像的边缘线。
1、watershed()函数
void watershed(
InputArray image, // 必须是一个8bit 3通道彩色图像矩阵序列
InputOutputArray markers // markers必须包含了种子点信息:算法会根据markers传入的轮廓作为种子(也就是所谓的注水点),
//对图像上其他的像素点根据分水岭算法规则进行判断,并对每个像素点的区域归属进行划定,
//直到处理完图像上所有像素点。而区域与区域之间的分界处的值被置为“-1”,以做区分。
==markers==
在将图像传递给函数之前,您必须粗略地勾勒出索引为正(>0)的图像标记中的所需区域。
因此,每个区域都表示为一个或多个具有像素值1,2,3的连接组件,以此类推。
可以使用findcontours()和drawcontours()从二进制掩码中检索这些标记。这些标记是未来图像区域的“种子”。
标记中的所有其他像素,如果它们与轮廓区域的关系未知,应该由算法定义,则应该设置为0。
在函数输出中,标记中的每个像素被设置为“seed”组件的值,或者在区域之间的边界处设置为-1。
);
2、示例一:手动添加 markers
watershed图像自动分割的实现步骤:
1)图像灰度化、滤波、Canny边缘检测
2)查找轮廓,并且把轮廓信息按照不同的编号绘制到watershed的第二个入参merkers上,相当于标记注水点。
3)watershed分水岭运算
4)绘制分割出来的区域,视觉控还可以使用随机颜色填充,或者跟原始图像融合以下,以得到更好的显示效果。
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
#define WINDOW_NAME1 "【程序窗口1】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【分水岭算法效果图】" //为窗口标题定义的宏
Mat g_maskImage, g_srcImage;
Point prevPt(-1, -1);
int main()
{
//输出一些帮助信息
printf( "\n\n\n\t欢迎来到【分水岭算法】示例程序~\n\n");
printf( "\t请先用鼠标在图片窗口中标记出大致的区域,\n\n\t然后再按键【1】或者【SPACE】启动算法。"
"\n\n\t按键操作说明: \n\n"
"\t\t键盘按键【1】或者【SPACE】- 运行的分水岭分割算法\n"
"\t\t键盘按键【2】- 恢复原始图片\n"
"\t\t键盘按键【ESC】- 退出程序\n\n\n");
//【1】载入原图并显示,初始化掩膜和灰度图
g_srcImage = imread("F:/C++/2. OPENCV 3.1.0/TEST/1.jpg", 1);
imshow( WINDOW_NAME1, g_srcImage );
Mat srcImage,grayImage;
g_srcImage.copyTo(srcImage);
cvtColor(g_srcImage, g_maskImage, COLOR_BGR2GRAY); // 彩色图转灰度图
cvtColor(g_maskImage, grayImage, COLOR_GRAY2BGR); // 转回三通道图
g_maskImage = Scalar::all(0);
//【2】设置鼠标回调函数
setMouseCallback( WINDOW_NAME1, on_Mouse, 0 );
//【3】轮询按键,进行处理
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 == ' ' )

本文详细介绍了OpenCV中的分水岭算法,包括watershed()函数的使用、手动和自动添加markers的示例,以及基于距离的分水岭算法。通过图像处理步骤,如灰度化、边缘检测和形态学操作,实现图像区域的精确分割。
最低0.47元/天 解锁文章
776

被折叠的 条评论
为什么被折叠?



