版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/PinkRiverside/article/details/72604326
提取輪廓
Canny邊緣檢測算子是John F. Canny於 1986 年開發出來的一個多級邊緣檢測算法。更爲重要的是 Canny 創立了邊緣檢測計算理論(Computational theory of edge detection)解釋這項技術如何工作。
Canny 的目標是找到一個最優的邊緣檢測算法,最優邊緣檢測的含義是: 好的檢測- 算法能夠儘可能多地標識出圖像中的實際邊緣。 好的定位- 標識出的邊緣要儘可能與實際圖像中的實際邊緣儘可能接近。 最小響應- 圖像中的邊緣只能標識一次,並且可能存在的圖像噪聲不應標識爲邊緣。 爲了滿足這些要求 Canny 使用了變分法,這是一種尋找滿足特定功能的函數的方法。最優檢測使用四個指數函數項的和表示,但是它非常近似於高斯函數的一階導數。
Canny 算法包含許多可以調整的參數,它們將影響到算法的計算的時間與實效。
高斯濾波器的大小:第一步所用的平滑濾波器將會直接影響 Canny 算法的結果。較小的濾波器產生的模糊效果也較少,這樣就可以檢測較小、變化明顯的細線。較大的濾波器產生的模糊效果也較多,將較大的一塊圖像區域塗成一個特定點的顏色值。這樣帶來的結果就是對於檢測較大、平滑的邊緣更加有用,例如彩虹的邊緣。
閾值:使用兩個閾值比使用一個閾值更加靈活,但是它還是有閾值存在的共性問題。設置的閾值過高,可能會漏掉重要信息;閾值過低,將會把枝節信息看得很重要。很難給出一個適用於所有圖像的通用閾值。目前還沒有一個經過驗證的實現方法。
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
using namespace std;
int main(){
Mat srcImage = imread("banana0.jpg");
imshow("banana0原始圖", srcImage);
Mat dstImage, edge, grayImage;
dstImage.create(srcImage.size(), srcImage.type());
//轉換爲灰度圖像
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
//使用 3x3內核來降噪
blur(grayImage, edge, Size(13,13));
Canny(edge, edge, 5,20, 3);
imshow("邊緣檢測", edge);
waitKey(0);
return 0;
}
使用該方法提取所有輪廓並存儲在對應文件夾中
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
using namespace std;
int main(){
for (int i = 0; i < 5; i++){
char srcname[20];
sprintf(srcname, "apple/apple%d.jpg",i);
char desname[20];
sprintf(desname, "appleCanny/apple%d.jpg", i);
Mat srcImage = imread(srcname);
//imshow("banana0原始圖", srcImage);
Mat dstImage, edge, grayImage;
dstImage.create(srcImage.size(), srcImage.type());
//轉換爲灰度圖像
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
////使用 3x3內核來降噪
blur(grayImage, edge, Size(5, 5));
Canny(edge, edge, 15,35, 3);
imwrite(desname, edge);
}
for (int i = 0; i < 5; i++){
char srcname[20];
sprintf(srcname, "banana/banana%d.jpg", i);
char desname[20];
sprintf(desname, "bananaCanny/banana%d.jpg", i);
Mat srcImage = imread(srcname);
//imshow("banana0原始圖", srcImage);
Mat dstImage, edge, grayImage;
dstImage.create(srcImage.size(), srcImage.type());
//轉換爲灰度圖像
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
////使用 3x3內核來降噪
blur(grayImage, edge, Size(9, 9));
Canny(edge, edge, 5, 20, 3);
imwrite(desname, edge);
}
//imshow("邊緣檢測", edge);
waitKey(0);
return 0;
}