建网站收费吗,技能培训有哪些科目,四川外国语大学网站建设系,北京公司注册在哪个网站【OpenCV#xff08;C#xff09;】分水岭算法 分水岭算法概述实现分水岭算法#xff1a;watershed()函数程序#xff1a;分水岭算法 分水岭算法概述
在许多实际运用中#xff0c;我们需要分割图像#xff0c;但无法从背景图像中获得有用信息。分水岭算法#xff08;wa… 【OpenCVC】分水岭算法 分水岭算法概述实现分水岭算法watershed()函数程序分水岭算法 分水岭算法概述
在许多实际运用中我们需要分割图像但无法从背景图像中获得有用信息。分水岭算法watershed algorithm在这方面往往是非常有效的。此算法可以将图像中的边缘转化为“山脉”将均匀区域转化为“山谷”这样有助于分割目标。 该算法是一种基于拓扑理论的数学形态学的分割方法其基本思想是把图像看作测地学上的拓扑地貌图像中每一点像素的灰度值表示该点的海拔高度每一个局部极小值及其影响区域称为集水盆而集水盆的边界则形成分水岭。
实现分水岭算法watershed()函数
在把图像传给函数之前我们需要大致勾画标记出图像中的期望进行分割的区域它们被标记为正指数。所以每一个区域都会被标记为像素值1、2、3等表示成为一个或者多个连接组件。这些标记值可以使用findContours函数和drawContours函数由二进制的掩码检索出来。
void watershed(InputArray image, InputOutputArray markers)程序分水岭算法
#include opencv2/core/core.hpp
#include opencv2/imgproc/imgproc.hpp
#include opencv2/highgui/highgui.hpp
#include iostreamusing namespace cv;
using namespace std;#define WINDOW_NAME1 【程序窗口1】
#define WINDOW_NAME2 【分水岭算法效果图】 Mat g_maskImage, g_srcImage;
Point prevPt(-1, -1);static void ShowHelpText();
static void on_Mouse(int event, int x, int y, int flags, void*);int main(int argc, char** argv)
{system(color 6F);ShowHelpText();g_srcImage imread(fg.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);setMouseCallback(WINDOW_NAME1, on_Mouse, 0);while (1){int c waitKey(0);if ((char)c 27)break;if ((char)c 2){g_maskImage Scalar::all(0);srcImage.copyTo(g_srcImage);imshow(image, g_srcImage);}if ((char)c 1 || (char)c ){int i, j, compCount 0;vectorvectorPoint contours;vectorVec4i 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], compCount)drawContours(maskImage, contours, index, Scalar::all(compCount 1), -1, 8, hierarchy, INT_MAX);if (compCount 0)continue;vectorVec3b colorTab;for (i 0; i compCount; 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());Mat watershedImage(maskImage.size(), CV_8UC3);for (i 0; i maskImage.rows; i)for (j 0; j maskImage.cols; j){int index maskImage.atint(i, j);if (index -1)watershedImage.atVec3b(i, j) Vec3b(255, 255, 255);else if (index 0 || index compCount)watershedImage.atVec3b(i, j) Vec3b(0, 0, 0);elsewatershedImage.atVec3b(i, j) colorTab[index - 1];}watershedImage watershedImage * 0.5 grayImage * 0.5;imshow(WINDOW_NAME2, watershedImage);}}return 0;
}static void on_Mouse(int event, int x, int y, int flags, void*)
{if (x 0 || x g_srcImage.cols || y 0 || y g_srcImage.rows)return;if (event CV_EVENT_LBUTTONUP || !(flags CV_EVENT_FLAG_LBUTTON))prevPt Point(-1, -1);else if (event CV_EVENT_LBUTTONDOWN)prevPt Point(x, y);else if (event CV_EVENT_MOUSEMOVE (flags CV_EVENT_FLAG_LBUTTON)){Point pt(x, y);if (prevPt.x 0)prevPt pt;line(g_maskImage, prevPt, pt, Scalar::all(255), 5, 8, 0);line(g_srcImage, prevPt, pt, Scalar::all(255), 5, 8, 0);prevPt pt;imshow(WINDOW_NAME1, g_srcImage);}
}static void ShowHelpText()
{printf(\n\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);
}运行效果如下