OpenCV  4.10.0
开源计算机视觉库
加载中...
搜索中...
无匹配项
samples/cpp/watershed.cpp

使用 watershed 算法的示例

#include <cstdio>
#include <iostream>
using namespace cv;
using namespace std;
static void help(char** argv)
{
cout << "\n本程序演示了 OpenCV 中著名的 watershed 分割算法:watershed()\n"
"使用方法:\n" << argv[0] <<" [图像名称 - 默认是 fruits.jpg]\n" << endl;
cout << "热键:\n"
"\tESC - 退出程序\n"
"\tr - 恢复原始图像\n"
"\tw 或 SPACE - 运行 watershed 分割算法\n"
"\t\t(在运行之前,*大致* 在图像上标记要分割的区域)\n"
"\t (在此之前,在图像上大致勾勒出几个标记)\n";
}
Mat markerMask, img;
Point prevPt(-1, -1);
static void onMouse( int event, int x, int y, int flags, void* )
{
if( x < 0 || x >= img.cols || y < 0 || y >= img.rows )
return;
if( event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON) )
prevPt = Point(-1,-1);
else if( event == EVENT_LBUTTONDOWN )
prevPt = Point(x,y);
else if( event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON) )
{
Point pt(x, y);
if( prevPt.x < 0 )
prevPt = pt;
line( markerMask, prevPt, pt, Scalar::all(255), 5, 8, 0 );
line( img, prevPt, pt, Scalar::all(255), 5, 8, 0 );
prevPt = pt;
imshow("image", img);
}
}
int main( int argc, char** argv )
{
cv::CommandLineParser parser(argc, argv, "{help h | | }{ @input | fruits.jpg | }");
if (parser.has("help"))
{
help(argv);
return 0;
}
string filename = samples::findFile(parser.get<string>("@input"));
Mat img0 = imread(filename, IMREAD_COLOR), imgGray;
if( img0.empty() )
{
cout << "无法打开图像 ";
help(argv);
return 0;
}
help(argv);
namedWindow( "image", 1 );
img0.copyTo(img);
cvtColor(img, markerMask, COLOR_BGR2GRAY);
cvtColor(markerMask, imgGray, COLOR_GRAY2BGR);
markerMask = Scalar::all(0);
imshow( "image", img );
setMouseCallback( "image", onMouse, 0 );
for(;;)
{
char c = (char)waitKey(0);
if( c == 27 )
break;
if( c == 'r' )
{
markerMask = Scalar::all(0);
img0.copyTo(img);
imshow( "image", img );
}
if( c == 'w' || c == ' ' )
{
int i, j, compCount = 0;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(markerMask, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
if( contours.empty() )
continue;
Mat markers(markerMask.size(), CV_32S);
markers = Scalar::all(0);
int idx = 0;
for( ; idx >= 0; idx = hierarchy[idx][0], compCount++ )
drawContours(markers, contours, idx, Scalar::all(compCount+1), -1, 8, hierarchy, INT_MAX);
if( compCount == 0 )
continue;
vector<Vec3b> 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 t = (double)getTickCount();
watershed( img0, markers );
t = (double)getTickCount() - t;
printf( "执行时间 = %gms\n", t*1000./getTickFrequency() );
Mat wshed(markers.size(), CV_8UC3);
// 绘制 watershed 图像
for( i = 0; i < markers.rows; i++ )
for( j = 0; j < markers.cols; j++ )
{
int index = markers.at<int>(i,j);
if( index == -1 )
wshed.at<Vec3b>(i,j) = Vec3b(255,255,255);
else if( index <= 0 || index > compCount )
wshed.at<Vec3b>(i,j) = Vec3b(0,0,0);
else
wshed.at<Vec3b>(i,j) = colorTab[index - 1];
}
wshed = wshed*0.5 + imgGray*0.5;
imshow( "watershed transform", wshed );
}
}
return 0;
}
用于命令行解析的类。
定义 utility.hpp:820
n 维密集数组类
定义 mat.hpp:812
MatSize size
定义 mat.hpp:2160
void copyTo(OutputArray m) const
将矩阵复制到另一个矩阵。
int cols
定义 mat.hpp:2138
bool empty() const
如果数组没有元素,则返回 true。
int rows
行和列的数量,或当矩阵具有超过 2 个维度时为 (-1, -1)
定义 mat.hpp:2138
int uniform(int a, int b)
返回 [a,b) 范围内的均匀分布的整数随机数
用于短数值向量的模板类,它是 Matx 的一个特例。
定义 matx.hpp:369
RNG & theRNG()
返回默认的随机数生成器。
#define CV_32S
定义 interface.h:77
unsigned char uchar
定义 interface.h:51
#define CV_8UC3
定义 interface.h:90
double getTickFrequency()
返回每秒的滴答次数。
int64 getTickCount()
返回滴答次数。
@ index
定义 gr_skig.hpp:77
void imshow(const String &winname, InputArray mat)
在指定的窗口中显示图像。
int waitKey(int delay=0)
等待按键按下。
void namedWindow(const String &winname, int flags=WINDOW_AUTOSIZE)
创建一个窗口。
void setMouseCallback(const String &winname, MouseCallback onMouse, void *userdata=0)
为指定的窗口设置鼠标处理程序。
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR)
从文件加载图像。
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
将图像从一个颜色空间转换为另一个颜色空间。
void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar &color, int thickness=1, int lineType=LINE_8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point())
绘制轮廓外框或填充轮廓。
void watershed(InputArray image, InputOutputArray markers)
使用 watershed 算法执行基于标记的图像分割。
void findContours(InputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
在二值图像中查找轮廓。
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
与磁盘上的文件关联的文件存储的“黑盒”表示。
定义 core.hpp:102
STL 命名空间。