4.1.2 鄰接性、連通性、區域和邊界


 下面是根據書上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-連通追跡的結果,為了看清楚效果,將上面的右圖拐角處放大如下,從圖中我們看到拐角處是連續的紅色邊線。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM