天天看點

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

contour在opencv中是一個基礎的資料結構,靈活運用的話,作用很大。以contour為關鍵字,在answerOpenCV中能夠發現很多有趣的東西。

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function
1、無法解決的問題 http://answers.opencv.org/question/195718/how-to-remove-unwanted-areaspixels-from-image/
answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

The problem is that. I just want to take the external contours of the main leaf in the image. Or If it is possible, The image can be cleaned. The second important point is that the process should be standard for all images.

解析:這個提問者希望從上面的葉子圖檔,得到葉子的輪廓。但實際上這是不可能完成的任務,這個圖檔品質達不到要求,關于這一點,是圖像處理的常識。

也就是根本無法輪廓分析,因為沒有穩定的輪廓。

2、如何從圖像中獲得完整輪廓

How to find dimensions of an object in the image

http://answers.opencv.org/question/195807/how-to-find-dimensions-of-an-object-in-the-image/?answer=196027#post-id-196027

這道題厲害了,一看這個需求就是專業的:

I want to find the length of an object in the image (image length not the real physical length). My first idea is was to use

boundingRect

to find the dimensions, but some of the masks I have split in between them so the

boundingRect

method fails. Can someone suggest me a robust method to find the length of the object in the given mask

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

他需要從這個圖中活動輪廓的長度(這個應該是一個腳印),但是因為圖上輪廓可能有多個,是以不知道怎麼辦。

解析:這道題的關鍵,就在于實際上,每張圖的輪廓隻有一個。這是重要的先驗條件。那怎麼辦?把識别出來的輪廓連起來呀。

連的方法有多種,我給出兩種比較保險:

1、形态學變化

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

    dilate(bw,bw,Mat(11,11,CV_8UC1));

    erode(bw,bw,Mat(11,11,CV_8UC1));

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

2、實在距離太遠,靠不上了,直接把中線連起來吧

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

由于這道題目前還沒有比較好的解決方法,是以我實作了一個,應該是可以用的,這是結果:

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

網站代碼也已經送出到網站上了

//程式主要部分

int main( int argc, char** argv )

{

    //讀入圖像,轉換為灰階

    Mat img = imread("e:/sandbox/1234.png");

    Mat bw;

    bool dRet;

    cvtColor(img, bw, COLOR_BGR2GRAY);

    //門檻值處理

    threshold(bw, bw, 150, 255, CV_THRESH_BINARY);

    bitwise_not(bw,bw);

    //形态學變化

    dilate(bw,bw,Mat(11,11,CV_8UC1));

    //尋找輪廓

    vector<vector<Point> > contours;

    vector<Vec4i> hierarchy;

    findContours(bw, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);

    /// 計算矩

    vector<Moments> mu(contours.size() );

    for( int i = 0; i < contours.size(); i++ )

        mu[i] = moments( contours[i], false ); 

    ///  計算中心矩:

    vector<Point2f> mc( contours.size() );

        mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); 

    //connect all contours into ONE

    for (int i = 0; i < contours.size(); ++i)

    {

        Scalar color = Scalar( rng12345.uniform(0, 255), rng12345.uniform(0,255), rng12345.uniform(0,255) );

        drawContours( img, contours, i, color, 2, 8, hierarchy, 0, Point() );

        circle( img, mc[i], 4, color, -1, 8, 0 );

        //connect

        if (i+1 <contours.size())

            line(bw,mc[i],mc[i+1],Scalar(255,255,255));

    }

    contours.clear();

    hierarchy.clear();

    //尋找結果

    for (int i = 0;i<contours.size();i++)

        RotatedRect minRect = minAreaRect( Mat(contours[i]) );

        Point2f rect_points[4];

        minRect.points( rect_points ); 

        for( int j = 0; j < 4; j++ )

            line( img, rect_points[j], rect_points[(j+1)%4],Scalar(255,255,0),2);

        float fshort = std::min(minRect.size.width,minRect.size.height); //short

        float flong = std::max(minRect.size.width,minRect.size.height);  //long

    imshow("img",img);

    waitKey();

    return 0;

}

3、新函數

Orientation of two contours

http://answers.opencv.org/question/113492/orientation-of-two-contours/
answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

這個topic希望能夠獲得兩個輪廓之間的角度。并且後期通過旋轉将兩者重合。

I try to calculate the orientation of 2 contours. At the end i want to rotate one contour, so it is in cover with the other one. With my code I get a result, but it isn't that accurate. Also I get the same orientations although the contours is rotated around 90 degrees.

解析:如果是我,一定會直接使用pca分别求出兩個輪廓的角度,然後算差。但是原文中使用了,并且提出了獨特的解決方法。

Shape Distance and Common Interfaces

https://docs.opencv.org/3.0-beta/modules/shape/doc/shape_distances.html#shapecontextdistanceextractor

Shape Distance algorithms in OpenCV are derivated from a common interface that allows you toswitch between them in a practical way for solving the same problem with different methods.Thus, all objects that implement shape distance measures inherit the

ShapeDistanceExtractor

interface.

當然,有了這個函數,做輪廓比對也是非常友善:

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

http://answers.opencv.org/question/28489/how-to-compare-two-contours-translated-from-one-another/

4、發現opencv的不足

I need a maxEnclosingCircle function

http://answers.opencv.org/question/958/i-need-a-maxenclosingcircle-function/?answer=196029#post-id-196029

opencv目前是沒有最大内接圓函數的(當然它還沒有很多函數),但是這個隻有研究要一定程度的人才會發現。這裡他提問了,我幫助解決下:

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

#

include

 "stdafx.h"

 <iostream>

using namespace

 std;

 cv;

VP FindBigestContour(Mat src){    

int

 imax = 0; //代表最大輪廓的序号

 imaxcontour = -1; //代表最大輪廓的大小

    std::vector<std::vector<cv::Point>>contours;    

    findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);

for

 (

 i=0;i<contours.size();i++){

 itmp =  contourArea(contours[i]);//這裡采用的是輪廓大小

if

 (imaxcontour < itmp ){

            imax = i;

            imaxcontour = itmp;

        }

return

 contours[imax];

 main(

 argc, 

char

* argv[])

    Mat src = imread("e:/template/cloud.png");

    Mat temp;

    cvtColor(src,temp,COLOR_BGR2GRAY);

    threshold(temp,temp,100,255,THRESH_OTSU);

    imshow("src",temp);

    //尋找最大輪廓

    VP VPResult = FindBigestContour(temp);

    //尋找最大内切圓

 dist = 0;

 maxdist = 0;

    Point center;

(

 i=0;i<src.cols;i++)

 j=0;j<src.rows;j++)

        {

            dist = pointPolygonTest(VPResult,cv::Point(i,j),

true

);

(dist>maxdist)

            {

                maxdist=dist;

                center=cv::Point(i,j);

            }

    //繪制結果

    circle(src,center,maxdist,Scalar(0,0,255));

    imshow("dst",src);

另過程中,發現了pyimagesearch上的一些不錯文章,感謝這個blog的作者的長期、高品質的付出,向他學習。

1、Removing contours from an image using Python and OpenCV

https://www.pyimagesearch.com/2015/02/09/removing-contours-image-using-python-opencv/

2、Sorting Contours using Python and OpenCV

https://www.pyimagesearch.com/2015/04/20/sorting-contours-using-python-and-opencv/

3、Finding extreme points in contours with OpenCV

https://www.pyimagesearch.com/2016/04/11/finding-extreme-points-in-contours-with-opencv/

結語:

實際上,最近我正在做關于輪廓的事情,這也是今天我做這個研究的直接原因。

我的問題是:如何識别出輪廓準确的長和寬

比如這張,其中2的這個外輪廓明顯是識别錯誤的,這樣它的長寬也是錯誤的(注意裡面我标紅的1和2)

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

代碼:

    //read the image

    Mat img = imread("e:/sandbox/leaf.jpg");

    //resize

    pyrDown(img,img);

    //morphology operation    

    //bitwise_not(bw,bw);

    //find and draw contours

我們要得到這樣的結果

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

當然,這個代碼我已經差不多寫出來了,如何獲得輪廓的真實的長寬?這個問題很實際,opencv沒有實作,目前看來answeropencv也人問?

就是這張圖檔?想看看大家的想法。也可以直接在answeropencv上進行讨論。

answerOpenCV輪廓類問題解析How to find dimensions of an object in the imageOrientation of two contoursI need a maxEnclosingCircle function

answerOpencv的讨論位址為:

http://answers.opencv.org/question/196032/how-to-find-the-real-width-and-height-of-contours/

感謝閱讀至此,希望有所幫助。

來自為知筆記(Wiz)

目前方向:圖像拼接融合、圖像識别

聯系方式:[email protected]

繼續閱讀