OpenCV 4.12.0
開源計算機視覺
載入中...
搜尋中...
無匹配項
samples/cpp/watershed.cpp

使用分水嶺演算法的示例

#include <cstdio>
#include <iostream>
using namespace cv;
using namespace std;
static void help(char** argv)
{
cout << "\n此程式演示了 OpenCV 中著名的分水嶺分割演算法:watershed()\n"
"用法:\n" << argv[0] <<" [image_name -- 預設為 fruits.jpg]\n" << endl;
cout << "熱鍵: \n"
"\tESC - 退出程式\n"
"\tr - 恢復原始影像\n"
"\tw 或 空格 - 執行分水嶺分割演算法\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);
// 繪製分水嶺影像
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( "分水嶺變換", wshed );
}
}
return 0;
}
如果陣列沒有元素,則返回 true。
int64_t int64
n 維密集陣列類
定義 mat.hpp:830
MatSize size
定義 mat.hpp:2187
void copyTo(OutputArray m) const
將矩陣複製到另一個矩陣。
int cols
定義 mat.hpp:2165
cv::getTickFrequency
double getTickFrequency()
int rows
行數和列數,如果矩陣的維數超過 2,則為 (-1, -1)
定義 mat.hpp:2165
int uniform(int a, int b)
返回 [a,b) 範圍內均勻分佈的整數隨機數
短數值向量的模板類,是 Matx 的一個特例。
定義 matx.hpp:369
RNG & theRNG()
返回預設的隨機數生成器。
CV_32S
#define CV_32S
I.at<uchar>(y, x) = saturate_cast<uchar>(r);
uchar
unsigned char uchar
CV_8UC3
#define CV_8UC3
ximgproc.hpp
返回時鐘週期數。
@ 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_BGR)
從檔案載入影像。
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0, AlgorithmHint hint=cv::ALGO_HINT_DEFAULT)
將影像從一個顏色空間轉換為另一個顏色空間。
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)
使用分水嶺演算法執行基於標記的影像分割。
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:107
STL 名稱空間。