少高潮爽了在观看奂费_奶水无码专区_欧美亚洲三级日韩_91精品国产综合香蕉_秋霞伦理电影在线_GOGO亚洲肉体艺术欣赏图片_一本一道a√无码中文字幕_免费看一级毛片无码区_内射视频网站在线观看_国产激情视频精品中文

圖像處理
新聞詳情

OpenCV圖像處理中“找圓技術(shù)”的使用

發(fā)布時間:2021-07-14 18:37:49 最后更新:2021-07-14 18:45:16 瀏覽次數(shù):6663
一、為什么“找圓”
    圓是基本圖形的一種,更為重要的是,自然情況下采集的圖像,很少大量存在“圓”;但凡存在的,大都是人工的,那么就必然代表特定的意義,從而方便定位、分割和識別。
    OpenCV現(xiàn)有代碼中能夠直接“找圓”,主要有2個,一個是“HoughCircle ”,另一個是“BlobDetector ”,此外基本的輪廓分析也能夠用于圓的尋找。但是這些基礎(chǔ)的方法,涉及到的參數(shù)比較多,一方面我們需要深入理解、一方面需要融合運用,才能夠有效提高識別準確率。因此結(jié)合實踐,整理相關(guān)內(nèi)容如下:
1. “找圓”在圖像處理中的價值和應(yīng)用案例;
2. 深入理解“HoughCircle ”的參數(shù)設(shè)置和優(yōu)缺點;
3. 深入理解 “BlobDetector”的參數(shù)設(shè)置和應(yīng)用實踐;
4. 進一步理解”閾值-輪廓-分割“的分割方法和在“找圓”上的運用;
5. 融合目前技術(shù),提出”找圓算法鏈“,提高識別準確率。
6. 對圓度、凸性、慣性比等基礎(chǔ)知識的進一步認識。
希望能夠為圖像處理工程師、愛好者提供一些啟發(fā)。
二、有效“找圓”的方法
OpenCV現(xiàn)有代碼中,設(shè)計“找圓”算法的,主要有2個,一個是“HoughCircle ”,另一個是“BlobDetector ”,此外基本的輪廓分析也能夠用于圓的尋找。
 2.1HoughCircle  霍夫圓變換

代碼: 

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    Mat img, gray;
    if( argc != 2 || !(img=imread(argv[1], 1)).data)
        return -1;
    cvtColor(img, gray, COLOR_BGR2GRAY);
    // smooth it, otherwise a lot of false circles may be detected
    GaussianBlur( gray, gray, Size(99), 22 );
    vector<Vec3f> circles;
    HoughCircles(gray, circles, HOUGH_GRADIENT,2, gray.rows/4200100 );
    for( size_t i = 0; i < circles.size(); i++ )
    {
         Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
         int radius = cvRound(circles[i][2]);
         // draw the circle center
         circle( img, center, 3, Scalar(0,255,0), -180 );
         // draw the circle outline
         circle( img, center, radius, Scalar(0,0,255), 380 );
    }
    namedWindow( "circles"1 );
    imshow( "circles", img );
    waitKey(0);
    return 0;
}

特別需要注意的是,目前版本出現(xiàn)新參數(shù)“HOUGH_GRADIENT_ALT”,在默認參數(shù)下比以前有很大程度的精度提升:

file

但是HoughCircle的缺點也是顯而易見的,簡單來說,在默認參數(shù)下,它非常容易丟目標。

2.2BlobDetector 

所謂Blob就是圖像中一組具有某些共同屬性(例如,灰度值)的連接像素。OpenCV提供了一種方便的方法來檢測斑點并根據(jù)不同的特征對其進行過濾。

// Setup SimpleBlobDetector parameters.
SimpleBlobDetector::Params params;
// Change thresholds
params.minThreshold = 10;
params.maxThreshold = 200;
// Filter by Area.
params.filterByArea = true;
params.minArea = 1500;
// Filter by Circularity
params.filterByCircularity = true;
params.minCircularity = 0.1;
// Filter by Convexity
params.filterByConvexity = true;
params.minConvexity = 0.87;
// Filter by Inertia
params.filterByInertia = true;
params.minInertiaRatio = 0.01;
#if CV_MAJOR_VERSION < 3   // If you are using OpenCV 2
  // Set up detector with params
  SimpleBlobDetector detector(params);
  // You can use the detector this way
  // detector.detect( im, keypoints);
#else
 
        // Set up detector with params
        cv::Ptr<cv::SimpleBlobDetectordetector = cv::SimpleBlobDetector::create(params);
        vector<KeyPointkeypoints;
        detector->detect(screw1keypoints);  
#endif

在OpenCV中實現(xiàn)的叫做SimpleBlobDetector,它基于以下描述的相當簡單的算法,并且進一步由參數(shù)控制,具有以下步驟。

SimpleBlobDetector::Params::Params()
{
    thresholdStep = 10;    //二值化的閾值步長,即公式1的t
    minThreshold = 50;   //二值化的起始閾值,即公式1的T1
    maxThreshold = 220;    //二值化的終止閾值,即公式1的T2
    //重復(fù)的最小次數(shù),只有屬于灰度圖像斑點的那些二值圖像斑點數(shù)量大于該值時,該灰度圖像斑點才被認為是特征點
    minRepeatability = 2;   
    //最小的斑點距離,不同二值圖像的斑點間距離小于該值時,被認為是同一個位置的斑點,否則是不同位置上的斑點
    minDistBetweenBlobs = 10;
 
    filterByColor = true;    //斑點顏色的限制變量
    blobColor = 0;    //表示只提取黑色斑點;如果該變量為255,表示只提取白色斑點
 
    filterByArea = true;    //斑點面積的限制變量
    minArea = 25;    //斑點的最小面積
    maxArea = 5000;    //斑點的最大面積
 
    filterByCircularity = false;    //斑點圓度的限制變量,默認是不限制
    minCircularity = 0.8f;    //斑點的最小圓度
    //斑點的最大圓度,所能表示的float類型的最大值
    maxCircularity = std::numeric_limits<float>::max();
 
    filterByInertia = true;    //斑點慣性率的限制變量
    minInertiaRatio = 0.1f;    //斑點的最小慣性率
    maxInertiaRatio = std::numeric_limits<float>::max();    //斑點的最大慣性率
 
    filterByConvexity = true;    //斑點凸度的限制變量
    minConvexity = 0.95f;    //斑點的最小凸度
    maxConvexity = std::numeric_limits<float>::max();    //斑點的最大凸度
}

  • 閾值:通過使用以minThreshold開始的閾值對源圖像進行閾值處理,將源圖像轉(zhuǎn)換為多個二進制圖像。這些閾值以thresholdStep遞增,直到maxThreshold。因此,第一個閾值為minThreshold,第二個閾值為minThreshold + thresholdStep,第三個閾值為minThreshold + 2 x thresholdStep,依此類推;
  • 分組:在每個二進制圖像中,連接的白色像素被分組在一起。我們稱這些二進制blob;
  • 合并:計算二進制圖像中二進制斑點的中心,并合并比minDistBetweenBlob更近的斑點;
  • 中心和半徑計算:計算并返回新合并的Blob的中心和半徑。

并且可以進一步設(shè)置SimpleBlobDetector的參數(shù)來過濾所需的Blob類型。

  • 按顏色:首先需要設(shè)置filterByColor =True。設(shè)置blobColor = 0可選擇較暗的blob,blobColor = 255可以選擇較淺的blob。
  • 按大?。嚎梢酝ㄟ^設(shè)置參數(shù)filterByArea = 1以及minArea和maxArea的適當值來基于大小過濾blob。例如。設(shè)置minArea = 100將濾除所有少于100個像素的斑點。
  • 圓度:這只是測量斑點距圓的距離。例如。正六邊形的圓度比正方形高。要按圓度過濾,請設(shè)置filterByCircularity =1。然后為minCircularity和maxCircularity設(shè)置適當?shù)闹?。圓度定義為()。圓的為圓度為1,正方形的圓度為PI/4,依此類推。
  • 按凸性:凸度定義為(斑點的面積/凸包的面積)。現(xiàn)在,形狀的“凸包”是最緊密的凸形,它完全包圍了該形狀,用不嚴謹?shù)脑拋碇v,給定二維平面上的點集,凸包就是將最外層的點連接起來構(gòu)成的凸多邊形,它能包含點集中所有的點。直觀感受上,凸性越高則里面“奇怪的部分”少。要按凸度過濾,需設(shè)置filterByConvexity = true,minConvexity、maxConvexity應(yīng)該屬于[0,1],而且maxConvexity> minConvexity。
  • 按慣性比:這個詞匯比較抽象。我們需要知道Ratio可以衡量形狀的伸長程度。簡單來說。對于圓,此值是1,對于橢圓,它在0到1之間,對于直線,它是0。按慣性比過濾,設(shè)置filterByInertia = true,并設(shè)置minInertiaRatio、maxInertiaRatio同樣屬于[0,1]并且maxConvexity> minConvexity。
    按凸性(左低右高)按慣性比(左低右高)
    Concave versus Convex Shape Inertia Ratio

這里的基礎(chǔ)知識可能比較復(fù)雜,關(guān)鍵是默認參數(shù)下,識別的效果應(yīng)該說出奇的好。
cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create();

但是存在的主要問題是由于blob分析的配置參數(shù)太多,優(yōu)化起來存在困難。同時對于某些情況,明顯識別錯誤。

2.3 基本輪廓分析
更普通的情況下,我們還是需要從輪廓分析開始,通過上面提出的“圓度”來尋找圓,主要是用來“查漏補缺”,或者是用于特殊情況的查找。

三、算法融合、協(xié)作增效
在前面已經(jīng)詳細分析3種主要算法的基礎(chǔ)上,本文的重點創(chuàng)造一個“算法鏈”找到的目標有效地融合起來,并且進一步橫向分析研究算法間的關(guān)系,希望多少能夠給關(guān)注這個方向、有類似需求的創(chuàng)作者一些思考。
算法流程
首先對于自然圖片,通過blod detection獲得準確的半徑;而后基于準確的半徑,分別調(diào)用HoughCircle以查漏補缺;最后,以上獲得的結(jié)果,需要進行融合篩選。這個方法,我在“鋼管識別”項目上得到了突出的成功應(yīng)用,最終能夠?qū)崿F(xiàn)非常高的準確識別。主要是基于以下幾點:
1、blobdetector能夠找到準確的圓的半徑,但是會找錯、找漏;
2、HoughCircle在有“準確的圓的半徑”的加持下,能夠很大程度上提高準確識別效率;
3、目標物體是有“固有特征”的,比如這里需要尋找的鋼管,他們的“半徑”基本上是一致的。


在線客服 雙翌客服
客服電話
  • 0755-23712116
  • 13822267203