我們將在本文中介紹以下高級圖像處理操作:
Canny 邊緣檢測 :Canny 邊緣檢測是一種流行的邊緣檢測算法。它是由 John F. Canny 在 1986 年開發的。它是一個多階段算法,我們將按如下方式經歷每個階段:
- 噪聲抑制: 第一步是使用高斯平滑從圖像中去除噪聲,這涉及使用高斯核,其中靠近核中心的像素被賦予比遠處像素更多的權重。
- 梯度計算 :應用Sobel 濾波器計算圖像的梯度以計算邊緣強度和方向,該濾波器突出顯示 x 和 y 軸上的強度變化。
- Non-Maximum Suppression: Non-Maximum Suppression通過遍歷上一步生成的梯度矩陣中的所有值來尋找邊緣方向強度更大的像素,從而減少邊緣的厚度。
- 雙閾值滯后: 最后一步使用輸入參數下閾值和上限閾值來過濾掉潛在邊緣,根據以下標準丟棄不相關的邊緣:
如果像素梯度值高于上限閾值,則像素被接受為邊緣。
如果像素梯度值低于下限閾值,則像素被拒絕。
如果像素梯度值介于兩個閾值之間,則僅當它連接到高于閾值上限的像素時才會被接受。
ImgProc類為 Canny 邊緣檢測提供了一個Canny方法,該方法采用以下參數:
- Source Image: Mat
- Output edges: Mat
- Lower Threshold: double
- Upper Threshold: double
public static Mat cannyEdges(Mat img){
Mat canny = new Mat();
Imgproc.Canny(img,canny,30,100);
return canny;
}
Canny 邊緣檢測
原始圖像
Canny 邊緣檢測
雙邊濾波圖像上的 Canny 邊緣檢測
注意:Canny 邊緣檢測算法基于梯度,因此對圖像噪聲高度敏感。因此,在灰度圖像上應用 Canny 邊緣檢測是一種很好的做法。
**輪廓:**輪廓可以定義為連接沿邊界具有相同強度的所有連續點的曲線。它們對于形狀分析和對象檢測很有用。
使用二值圖像查找輪廓是一種很好的做法。二值圖像是這樣的圖像,其中每個像素只能有兩個可能的強度值(0 表示黑色,1 或 255 表示白色)。
ImgProc 類提供了一種用于生成二值圖像的閾值方法,該方法使用以下參數:
- Source Image: Mat - grayscale image
- Output Image: Mat
- Threshold : double: 如果像素值小于閾值,則設置為 0。
- Maximum:雙精度 - 分配給超過閾值的像素的最大值。
- Type of threshold:int - OpenCV 提供不同類型的閾值技術,如 OTSU 、TOZERO等。
public static Mat convertToBinary(Mat img){
Mat binImg = new Mat();
Imgproc.threshold(img,binImg,125 ,255,Imgproc.THRESH_BINARY);
return binImg;
}
圖像轉換為二進制
二進制圖像
尋找輪廓:ImgProc 類提供了一個findContours方法,該方法接受以下輸入參數:
- Image:Mat - 二進制圖像
- Contours : List- 檢測到的輪廓存儲在這個列表中
- Hierarchy : Mat - 存儲有關圖像拓撲的信息
- Contour Retrieval Mode:int - OpenCV 提供以下檢索模式:
- RETR_LIST(0) :檢索所有輪廓而不保持層次關系。
- RETR_EXTERNAL(1): 僅檢索所有極端外輪廓。
- RETR_CCOMP(2): 檢索所有輪廓并將它們排列到 2 級層次結構中。對象的外部輪廓放置在層次 1 中,對象內部的孔的輪廓放置在層次 2 中。
- RETR_TREE(3): 檢索所有輪廓并創建完整的層次結構列表。
- Contour Approximation Method : int - 近似方法指定存儲邊界坐標的方式。
- CHAIN_APPROX_NONE: 存儲所有邊界點。
- CHAIN_APPROX_SIMPLE :去除冗余點并壓縮輪廓;例如:對于一條線,存儲兩個端點。
public static void findAndDrawContours(Mat binImg,Mat org){
List
Imgproc.findContours(binImg,contourList,new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
Imgproc.drawContours(org, contourList, -1, new Scalar(50, 205, 50), 2);
HighGui.imshow("Contours",org);
HighGui.waitKey();
}
查找和繪制輪廓
繪制輪廓: ImgProc 類提供了一個drawContours方法,該方法使用以下參數:
- Image:Mat - 目標圖像
- Contour List:List< MatOfPoint>
- Contour Index: int - 要繪制的輪廓索引,負值表示所有輪廓都已繪制。
- Color:Scalar - 輪廓的顏色。
- Thickness:int - 邊界線的厚度。
輪廓
使用輪廓進行形狀檢測: 我們可以使用輪廓來根據近似曲線中的周長、面積和陣列點的數量來檢測形狀。ImgProc 類提供了一個approxPolyDP方法,該方法返回基于輪廓的近似曲線并使用以下參數:
- curve:MatOfPoint2f
- approxCurve: MatOfPoint2f - 輸出曲線
- epsilon: double - Epsilon 指定近似精度。這是原始曲線與其近似值之間的最大距離,我們可以使用 ImgProc arcLength 方法(返回曲線長度或周長)進行優化。
- closed:布爾值 - 如果近似曲線是閉合的,則為 true,否則為 false。
public static void shapeDetection(Mat binImg,Mat org){
List
List
Imgproc.findContours(binImg,contourList,new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
for(int i=0;i
point.fromList(contourList.get(i).toList());
MatOfPoint2f approxCurve = new MatOfPoint2f();
double parameter = Imgproc.arcLength(point, true);
Imgproc.approxPolyDP(point, approxCurve, parameter * 0.02, true);
long total = approxCurve.total();
//Detecting Rectangle Shape
if (total == 4) {
double area = Imgproc.contourArea(contourList.get(i));
//rectangle with area greater than 500
if(area>500)
selectedContours.add(contourList.get(i));
}
}
Imgproc.drawContours(org, selectedContours, -1, new Scalar(50, 205, 50), 3);
HighGui.imshow("Contours",org);
HighGui.waitKey();
}
使用輪廓進行形狀檢測
-
圖像處理
+關注
關注
27文章
1292瀏覽量
56747 -
邊緣檢測
+關注
關注
0文章
92瀏覽量
18211 -
噪聲抑制
+關注
關注
0文章
29瀏覽量
12177
發布評論請先 登錄
相關推薦
評論