opencv圖像特征檢測之斑點檢測


  前面說過,圖像特征點檢測包括角點和斑點,今天來說說斑點,斑點是指二維圖像中和周圍顏色有顏色差異和灰度差異的區域,因為斑點代表的是一個區域,所以其相對於單純的角點,具有更好的穩定性和更好的抗干擾能力.

  視覺領域的斑點檢測的主要思路是檢測出圖像中比周圍像素灰度打或者比周圍區域灰度值小的區域,一般來說,有兩種基本方法

  1.基於求導的微分方法,這成為微分檢測器

  2.基於局部極值的分水嶺算法,OPENCV中提供了simpleBlobDetector特征檢測器來實現這種基本的斑點檢測算法.

  

  LOG斑點檢測

  使用高斯拉普拉斯算子檢測圖像斑點是一種比較常見的辦法,對一個二維的高斯函數G(x,y,o),進過規范化的拉普拉斯變換以后,結果在二維圖像上呈現為一個圓對稱函數,我們可以用這個函數來檢測圖像的斑點,並且可以通過改動o的值

來檢測不同尺寸的二維斑點.圖像如下

  

  對上面這段話的直觀理解是:一個圖像和一個二維函數進行卷積運算,實際上就是求取圖像和這個函數的相似性,同理,圖像與高斯拉普拉斯函數進行卷積,就是求取圖像和高斯拉普拉斯函數的相似性,當圖像中的斑點尺寸與高斯拉普拉斯函數的形

狀趨於一致的時候,圖像對應位置的拉普拉斯響應達到最大.

  實際上,lapacian算子本身可以檢測圖像的極值點,設其為L算子,但是因為L算子並不能消除干擾,圖像M中的噪聲會影響求取到的結果,所以對圖像M進行名為G的高斯濾波去除干擾,得到圖像M',公式如下M' = M*G*L=M*(G*L);括號里面就是

高斯拉普拉斯算子.

  通過上面的那種算法,我們可以得到斑點,但是沒有多尺度的斑點,當高斯協方差o一定的時候,我們只能檢測對應o的半徑的斑點,具體的半徑通過對標准化的高斯拉普拉斯算子進行求導得到,當o=r/根號2時,響應最大,圖像黑白反相時,響應最小,因

此將高斯拉普拉斯算子響應達到峰值的o值,成為特征尺度.

  對應二維圖像,計算圖像在不同尺度下的離散高斯拉普拉斯響應值,然后檢查不同尺度位置中的每個值,如果某個尺度下的高斯拉普拉斯響應值,都小於或者大於其他尺度的值,那么該點就是被檢測到的圖像斑點位置.

 

  2.基於局部極值的分水嶺算法斑點檢測simpleBlobDetector

  這種檢測方法分為以下幾步

  a.對一張圖片,設定一個低閾值,設定一個高閾值,在設定一個閾值步進,然后從低閾值到高閾值按照閾值步進取一系列的閾值

  b.用每一個閾值對圖像進行二值化,然后使用findcontours查找邊,並計算每一個輪廓的中心

  c.對應每一個圖片的輪廓的中心,進行抑制,定義一個最小距離,在這個距離區域內的特征中心被定義為一個blob,得到特征點集合

  d.對特征點進行相應的過濾,例如顏色過濾,面積過濾等

  API:Ptr<smpleBlobDetector>create(simpleBlobDetector::params 參數集合)

  參數集合里面包括 minthreshold 低閾值 maxthreshold 高閾值 thresholdStep 閾值步進 minDistanceBetweenBlob  blob分塊最小距離 filterColor 顏色過濾 filterArea 面積過濾

          filterByCircularrty 圓度過濾 還有兩個是邊界長度過濾和凸度過濾,這五種過濾方式任選且只能選一種,默認使用黑色顏色過濾

  具體使用代碼如下

  

int main(int argc,char* argv[])
{
    Mat srcImage = imread("F:\\opencv\\OpenCVImage\\FeatureDetectSrc1.jpg");
    Mat srcGrayImage;
    if (srcImage.channels() == 3)
    {
        cvtColor(srcImage,srcGrayImage,CV_RGB2GRAY);
    }
    else
    {
        srcImage.copyTo(srcGrayImage);
    }
    vector<KeyPoint>detectKeyPoint;
    Mat keyPointImage1,keyPointImage2;

    SimpleBlobDetector::Params params;
    params.minArea = 10;
    params.maxArea = 1000;
    params.filterByCircularity = true;
    Ptr<SimpleBlobDetector> sbd = SimpleBlobDetector::create(params);
    sbd->detect(srcGrayImage,detectKeyPoint);
    drawKeypoints(srcImage,detectKeyPoint,keyPointImage1,Scalar(0,0,255),DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    drawKeypoints(srcImage,detectKeyPoint,keyPointImage2,Scalar(0,0,255),DrawMatchesFlags::DEFAULT);

    imshow("src image",srcImage);
    imshow("keyPoint image1",keyPointImage1);
    imshow("keyPoint image2",keyPointImage2);

    imwrite("F:\\opencv\\OpenCVImage\\FeatureDetectSrc1SimpleBlobDetectorKeyPointImageDefault.jpg",keyPointImage2);

    waitKey(0);
    return 0;
}

處理圖片

可以看到,檢測到了攝像頭那里的斑塊

 

  


免責聲明!

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



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