女人夜夜春高潮爽A∨片传媒_国产精品VIDEOS麻豆_在线精品亚洲一区二区三区_亚洲熟妇无码av

圖像處理
新聞詳情

OpenCV圖像處理中“找圓技術”的使用

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

特別需(xu)要(yao)注意的是,目(mu)前版本(ben)出現新(xin)參數(shu)“HOUGH_GRADIENT_ALT”,在默認參數下比以前有很大程度(du)的(de)精度(du)提升:

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

2.2BlobDetector 

所謂(wei)Blob就(jiu)是圖像(xiang)(xiang)中一組(zu)具有某些共同屬性(例如(ru),灰度(du)值(zhi))的(de)連(lian)接像(xiang)(xiang)素。OpenCV提供了一種(zhong)方便的方法來檢測(ce)斑(ban)點并根據不同的特征(zheng)對其(qi)進行過(guo)濾。

// 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&nbsp;detector with params
        cv::Ptr<cv::SimpleBlobDetectordetector = cv::SimpleBlobDetector::create(params);
        vector<KeyPointkeypoints;
        detector->detect(screw1keypoints);  
#endif

在OpenCV中實現的(de)(de)叫做SimpleBlobDetector,它基于以(yi)下描述的(de)(de)相(xiang)當簡(jian)單(dan)的(de)(de)算法,并(bing)且(qie)進(jin)一步由參數控制,具有以(yi)下步驟。

SimpleBlobDetector::Params::Params()
{
    thresholdStep = 10;    //二值(zhi)化的閾值(zhi)步長,即公式(shi)1的t
    minThreshold = 50;   //二值(zhi)化的起始閾(yu)值(zhi),即(ji)公(gong)式1的T1
    maxThreshold = 220;    //二值(zhi)(zhi)化(hua)的(de)終止閾值(zhi)(zhi),即公(gong)式1的(de)T2
    //重(zhong)復(fu)的(de)最小次數,只有屬于灰度圖像(xiang)斑(ban)點(dian)的(de)那些二(er)值(zhi)圖像(xiang)斑(ban)點(dian)數量(liang)大于該值(zhi)時,該灰度圖像(xiang)斑(ban)點(dian)才被認(ren)為是特(te)征點(dian)
    minRepeatability = 2;   
    //最(zui)小的斑(ban)點距離,不同(tong)(tong)二值(zhi)圖(tu)像(xiang)的斑(ban)點間(jian)距離小于該值(zhi)時,被認為是同(tong)(tong)一個(ge)位(wei)置(zhi)的斑(ban)點,否則是不同(tong)(tong)位(wei)置(zhi)上(shang)的斑(ban)點
    minDistBetweenBlobs = 10;
 
    filterByColor = true;    //斑點顏(yan)色的限(xian)制變量
    blobColor = 0;    //表示只提取(qu)黑色(se)斑點;如果該(gai)變量為255,表示只提取(qu)白色(se)斑點
 
    filterByArea = true;    //斑點面(mian)積的限(xian)制(zhi)變量
    minArea = 25;    //斑點的(de)最小(xiao)面積
    maxArea = 5000;    //斑點的最大面積
 
    filterByCircularity = false;    //斑點(dian)圓度的限(xian)制變量,默認是(shi)不限(xian)制
    minCircularity = 0.8f;    //斑點的(de)最小圓度(du)
    //斑點的(de)(de)最(zui)大(da)圓度,所(suo)能表(biao)示的(de)(de)float類(lei)型的(de)(de)最(zui)大(da)值
    maxCircularity = std::numeric_limits<float>::max();
 
    filterByInertia = true;    //斑點慣性率(lv)的(de)限制變(bian)量
    minInertiaRatio = 0.1f;    //斑點的最(zui)小慣性率
    maxInertiaRatio = std::numeric_limits<float>::max();    //斑點的最(zui)大慣性率
 
    filterByConvexity = true;    //斑點凸(tu)度的限制(zhi)變量(liang)
    minConvexity = 0.95f;    //斑點的最小(xiao)凸度
    maxConvexity = std::numeric_limits<float>::max();    //斑點的(de)最大凸度
}

  • 閾(yu)(yu)(yu)值(zhi)(zhi):通過(guo)使用(yong)以(yi)minThreshold開始的(de)閾(yu)(yu)(yu)值(zhi)(zhi)對(dui)源圖像進(jin)行閾(yu)(yu)(yu)值(zhi)(zhi)處(chu)理(li),將源圖像轉換為(wei)(wei)多個(ge)二進(jin)制圖像。這些閾(yu)(yu)(yu)值(zhi)(zhi)以(yi)thresholdStep遞增,直到(dao)maxThreshold。因(yin)此,第一個(ge)閾(yu)(yu)(yu)值(zhi)(zhi)為(wei)(wei)minThreshold,第二個(ge)閾(yu)(yu)(yu)值(zhi)(zhi)為(wei)(wei)minThreshold + thresholdStep,第三個(ge)閾(yu)(yu)(yu)值(zhi)(zhi)為(wei)(wei)minThreshold + 2 x thresholdStep,依此類推;
  • 分組:在每個(ge)二(er)進制圖像中,連接的白(bai)色像素被分組在一起。我們稱這些二(er)進制blob;
  • 合并:計算(suan)二進制(zhi)圖像中二進制(zhi)斑(ban)點(dian)(dian)的中心,并合并比minDistBetweenBlob更近的斑(ban)點(dian)(dian);
  • 中(zhong)心(xin)(xin)和半徑計(ji)算:計(ji)算并(bing)返回新合并(bing)的Blob的中(zhong)心(xin)(xin)和半徑。

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

  • 按顏色:首(shou)先需要設置(zhi)filterByColor =True。設置(zhi)blobColor = 0可選擇(ze)較暗(an)的(de)blob,blobColor = 255可以選擇(ze)較淺的(de)blob。
  • 按大(da)小(xiao)(xiao):可以通過設置參數filterByArea = 1以及minArea和(he)maxArea的適當(dang)值來基(ji)于大(da)小(xiao)(xiao)過濾(lv)blob。例如(ru)。設置minArea = 100將濾(lv)除所有少于100個像素的斑點(dian)。
  • 按(an)圓(yuan)(yuan)度(du):這(zhe)只(zhi)是測量斑點距圓(yuan)(yuan)的距離(li)。例如。正六邊形(xing)的圓(yuan)(yuan)度(du)比正方形(xing)高。要按圓(yuan)(yuan)度(du)過濾(lv),請設置(zhi)filterByCircularity =1。然后為(wei)minCircularity和maxCircularity設置(zhi)適當的值(zhi)。圓(yuan)(yuan)度(du)定義為(wei)()。圓(yuan)的(de)為(wei)圓(yuan)度(du)(du)為(wei)1,正(zheng)方形(xing)的(de)圓(yuan)度(du)(du)為(wei)PI/4,依(yi)此類推。
  • 按凸性(xing):凸度定義為(wei)(斑點的面(mian)積/凸包的面(mian)積)。現在,形狀的“凸包”是最緊密的凸形,它完全包圍了該形狀,用不嚴謹的話來講,給定二維平面上的點集,凸包就是將最外層的點連接起來構成的凸多邊形,它能包含點集中所有的點。直觀感受上,凸性越高則里面“奇怪的部分”少。要按凸度過濾,需設置filterByConvexity = true,minConvexity、maxConvexity應該屬于[0,1],而且maxConvexity> minConvexity。
  • 按慣(guan)性比:這(zhe)個詞匯(hui)比較抽象。我們需要知道Ratio可以衡量形(xing)狀的伸長程(cheng)度(du)。簡單(dan)來說。對于(yu)圓,此(ci)值(zhi)是(shi)1,對于(yu)橢圓,它在0到1之間(jian),對于(yu)直(zhi)線,它是(shi)0。按慣(guan)性(xing)比過濾,設置(zhi)filterByInertia = true,并設置(zhi)minInertiaRatio、maxInertiaRatio同樣屬于(yu)[0,1]并且maxConvexity> minConvexity。
    按(an)凸性(左低右高)按慣性比(左低右高)
     

這里(li)的基礎知識可能比較復雜(za),關鍵是默認參數下,識別的效果應該說出奇(qi)的好。
cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create();

但是存在(zai)的主要問題是由(you)于(yu)blob分析的配置(zhi)參數太多(duo),優化起來存在(zai)困(kun)難(nan)。同(tong)時對于(yu)某些(xie)情(qing)況,明顯識(shi)別(bie)錯誤。

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

三、算法融合、協作增效
在前面已經詳(xiang)細分析3種(zhong)主要算法的(de)基礎上(shang),本文的(de)重點創(chuang)造一(yi)(yi)個“算法鏈”找到的(de)目標有效地融合起來(lai),并且進一(yi)(yi)步橫向(xiang)分析研究算法間的(de)關系,希望多(duo)少(shao)能夠給關注這個方(fang)向(xiang)、有類似需求的(de)創(chuang)作者一(yi)(yi)些思考。
算法流程
首先對于自然圖片,通過blod detection獲得準確的半徑;而后基于準確的半(ban)徑,分別調用HoughCircle以查漏補缺;最后,以上獲(huo)得的(de)結果,需要(yao)進行融(rong)合篩選。這個方法,我在(zai)“鋼管(guan)識(shi)別”項目上得到了突出的(de)成功應用,最終(zhong)能夠實現非常高的(de)準確識(shi)別。主要(yao)是(shi)基于以下(xia)幾點:
1、blobdetector能夠找到準(zhun)確的(de)圓的(de)半徑,但是會找錯(cuo)、找漏;
2、HoughCircle在有“準確的(de)圓的(de)半徑”的(de)加(jia)持下,能夠很大程度上(shang)提高準確識別效率;
3、目(mu)標物體是(shi)有“固有特(te)征”的,比(bi)如這(zhe)里(li)需要尋找的鋼(gang)管,他們的“半徑”基本上(shang)是(shi)一致的。


在線客服
客服電話
  • 0755-23712116
  • 13310869691