Canny邊緣檢測算子是一種多級檢測算法。1986年由John F. Canny提出,同時提出了邊緣檢測的三大准則:
- 低錯誤率的邊緣檢測:檢測算法應該精確地找到圖像中的盡可能多的邊緣,盡可能的減少漏檢和誤檢。
- 最優定位:檢測的邊緣點應該精確地定位於邊緣的中心。
- 圖像中的任意邊緣應該只被標記一次,同時圖像噪聲不應產生偽邊緣。
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 算法思路:
- 初始化參數空間,將參數空間矩陣每一個像素置0;
- 遍歷圖像當中不為0的像素點,記錄所有經過該像素點直線的直線參數,將參數空間中對應該直線參數的像素值加1;
- 根據先驗知識,分析參數矩陣,獲取參數矩陣某些峰值作為檢測結果。
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()