下面是根據書上103頁,圖4.4(e),分別采用8-連通和4-連通兩種方式進行邊界追跡的簡單示例程序:
void traceEdge(Mat&img,int neighbor=1) { Mat tempImg=img.clone(); cv::cvtColor(tempImg,tempImg,CV_BGR2GRAY); for(int i=1;i<img.rows;i++) { for(int j=1;j<img.cols;j++) { uchar v=tempImg.ptr<uchar>(i)[j]; if(v>0) { uchar p1=tempImg.ptr<uchar>(i-1)[j-1]; uchar p2=tempImg.ptr<uchar>(i-1)[j]; uchar p3=tempImg.ptr<uchar>(i-1)[j+1]; uchar p4=tempImg.ptr<uchar>(i)[j-1]; uchar p5=tempImg.ptr<uchar>(i)[j+1]; uchar p6=tempImg.ptr<uchar>(i+1)[j-1]; uchar p7=tempImg.ptr<uchar>(i+1)[j]; uchar p8=tempImg.ptr<uchar>(i+1)[j+1]; switch(neighbor) { case 0: if(p2*p4*p5*p7==0) img.ptr<Vec3b>(i)[j]=Vec3b(0,0,255); break; case 1: if(p1*p2*p3*p4*p5*p6*p7*p8==0) img.ptr<Vec3b>(i)[j]=Vec3b(0,0,255); break; } } } } } int main() { Mat img(500,500,CV_8UC3,Scalar::all(0)); Point vertices1[6]={Point(30,30),Point(130,30),Point(130,100), Point(160,100),Point(160,230),Point(30,230)}; const Point *pts[2]={vertices1}; int npts[]={6}; int ncontour=1; cv::fillPoly(img,pts,npts,ncontour,Scalar(255,255,0)); imshow("fillPoly image",img); waitKey(); traceEdge(img,0); imshow("trae Edge image",img); waitKey(); return 0; }
運行結果如下,左圖是一個多邊形圖像,背景為黑色。右圖是采用4-連通的方式追跡邊界的結果
為了看得清楚,將上圖拐角處放到如下,從圖中我們可以看到,拐角處是不連續的邊線。
接下來,我們再看看8-連通邊緣追跡結果:
上面左圖是原圖,右圖是8-連通追跡的結果,為了看清楚效果,將上面的右圖拐角處放大如下,從圖中我們看到拐角處是連續的紅色邊線。