圖像求導、邊緣檢測、分割


Canny邊緣檢測算子是一種多級檢測算法。1986年由John F. Canny提出,同時提出了邊緣檢測的三大准則:

  1. 低錯誤率的邊緣檢測:檢測算法應該精確地找到圖像中的盡可能多的邊緣,盡可能的減少漏檢和誤檢。
  2. 最優定位:檢測的邊緣點應該精確地定位於邊緣的中心。
  3. 圖像中的任意邊緣應該只被標記一次,同時圖像噪聲不應產生偽邊緣。

 

 

1.sobel算子

Sobel導數並不是真正的導數,因為Sobel算子定義在一個離散的空間上。Sobel算子真正表示的是多項式擬合。

 

Sobel(imGray,imgSobeled,-1,0,1);

 

 

2.Priwitt濾波器

 

 

3.Scharr濾波器:相較於Sobel精度更高

 

Scharr(imGray,imScharred,-1,0,1);

 

4.拉普拉斯核——真正的輪廓識別

 

Laplacian(imGray,imLaped,-1,1);

 

 

 

 

 分別對應:原圖,Sobel/Scharr濾波,Laplacian變換

 

 

 

5.Canny邊緣檢測

 

Canny邊緣檢測算法可以分為以下5個步驟:

  • 1) 高斯模糊 - GaussianBlur
  • 2) 灰度轉換 - cvtColor
  • 3) 計算梯度 - Sobel/Scharr
  • 4) 非最大信號抑制
  • 5) 高低閾值輸出二值圖像

 

 

    Mat dx,dy;
    blur(imGray,blurImage,cv::Size(3,3));
    Scharr(blurImage,dx,CV_16S,1,0);
    Scharr(blurImage,dy,CV_16S,0,1);
    Canny(dx,dy,imCannyed,100,150);

 

6.hough變換

6.1 算法思路:

  1. 初始化參數空間,將參數空間矩陣每一個像素置0;
  2. 遍歷圖像當中不為0的像素點,記錄所有經過該像素點直線的直線參數,將參數空間中對應該直線參數的像素值加1;
  3. 根據先驗知識,分析參數矩陣,獲取參數矩陣某些峰值作為檢測結果。

6.2 OpenCV接口:

  • Hough變換主要優點是能容忍特征邊界描述中的間隙,並且相對不受圖像噪聲的影響。
  • SHT,標准hough變換
  • MHT,多尺度hough變換,對SHT的細化,精度更高
  • PPHT,漸進概率hough變換,計算直線及其延長線——只要峰值夠高,只要花很少的時間即可,可大幅提高速度
void HoughLines( InputArray image,   // image:輸入圖像
                 OutputArray lines,  //lines:檢測到的直線(表示其實為直線參數(θ,p)集合)
                 double rho,       //rho:像素每次迭代的大小(即每一次選取像素的過程跳躍多少,一般設置為1)
                 double theta,     //theta:角度累加器的大小(即選取的直線參數θ的變化),一般為CV_PI/180
                 int threshold,    //thresold:閾值大小(即每個參數對至少經過的像素點數)   
                 double srn = 0, double stn = 0,
                 double min_theta = 0, double max_theta = CV_PI );

 C++程序實現參考:https://github.com/ljwcdtj/HoughTransform

6.3 缺點

  • 巨量的計算,難以達到實時性
  • 解決思路:
  • 裁剪原始圖像,縮小搜索范圍
  • 平方根,正弦,余弦計算的查表化
  • “多尺度”搜索策略,即先對原圖抽樣數據進行粗搜索定位,再對原圖在一定的角度范圍內進行搜索
  • 先驗知識(直線走向,長度等限制)的使用以及一些多線程/並行計算策略

6.4 參考:https://blog.csdn.net/ljwcdtj/article/details/89091060

 

7.距離變換(有標記、無標記)

  • 用於細化字符的輪廓和查找物體質心(中心)。參考:https://blog.csdn.net/z827997640/article/details/80461240

 7.1 算法思路

按照某種距離(如:D4距離或D8距離)對大小為M×N的圖像中的區域塊作距離變換,算法過程如下:

 

 

 

  • 1、建立一個大小為M×N的數組F,作如下的初始化:將區域塊中的元素設置為0,其余元素設置為無窮;
  • 2、利用掩模1(mask1),左上角開始,從左往右,從上往下遍歷數組,將掩模中P點對應的元素的值作如下更新:

  • 3、利用掩模2(mask2),右下角開始,從右往左,從下往上遍歷數組,將掩模中P點對應的元素的值作如下更新:

  • 4、最終得到的更新后的數組即為距離變換的結果。

7.2 opencv接口

void distanceTransform( InputArray src, 
              OutputArray dst,
                        int distanceType,
               int maskSize,
               int dstType=CV_32F);

InputArray src:輸入圖像,一般為二值圖像;
OutputArray dst:輸出的圖像,距離變換結果;
int distanceType:用於距離變換的距離類型(歐氏距離:DIST_L2 = 2;$D_4$距離:DIST_L1 = 1;$D_8$距離:DIST_C = 3等);
int mask_size:距離變換掩模的大小,一般為3或5;
int dstType:輸出圖像的數據類型,可以為CV_8U或CV_32F。

7.3 應用 

  • 骨架抽取
  • 用距離變換的方式來實現匹配,配合倒角距離變換(Chamfer Distance Transform)可以達到快速匹配的效果。(對旋轉、縮放是無效的)

 

 7.4 參考:

https://zhuanlan.zhihu.com/p/38917770

https://www.2cto.com/kf/201701/586976.html

 

8.分割

8.1 漫水填充

  • cv::floodFill()

8.2 分水嶺算法

  • 無單獨背景蒙版時,需要分割圖像:圖中的線轉化成“山”,平坦區域轉化成“谷”用以分割
  • 使用者/算法先標記對象或背景的一部分
  • cv::watershed()

8.3 Grabcuts算法

  • 使用者/算法在待分割對象周圍提供一個矩形框,其外部即為背景
  • cv::grabCut()

8.4 Mean-shift分割

  • 基於顏色分布峰值進行分割
  • 通過滑動窗口找到最高密度塊,
  • cv::pyrMeanShiftFiltering()

 


免責聲明!

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



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