2013-06-14 66 views
23

hãy có một cái nhìn tại các mã sauSự khác nhau giữa "Edge Detection" và "Hình ảnh Contours"

#include <iostream> 
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 

using namespace std; 
using namespace cv; 

Mat src, grey; 
int thresh = 10; 

const char* windowName = "Contours"; 

void detectContours(int,void*); 

int main() 
{ 
    src = imread("C:/Users/Public/Pictures/Sample Pictures/Penguins.jpg"); 

    //Convert to grey scale 
    cvtColor(src,grey,CV_BGR2GRAY); 

    //Remove the noise 
    cv::GaussianBlur(grey,grey,Size(3,3),0); 

    //Create the window 
    namedWindow(windowName); 

    //Display the original image 
    namedWindow("Original"); 
    imshow("Original",src); 

    //Create the trackbar 
    cv::createTrackbar("Thresholding",windowName,&thresh,255,detectContours); 

    detectContours(0,0); 
    waitKey(0); 
    return 0; 

} 

void detectContours(int,void*) 
{ 
    Mat canny_output,drawing; 

    vector<vector<Point>> contours; 
    vector<Vec4i>heirachy; 

    //Detect edges using canny 
    cv::Canny(grey,canny_output,thresh,2*thresh); 

    namedWindow("Canny"); 
    imshow("Canny",canny_output); 

    //Find contours 
    cv::findContours(canny_output,contours,heirachy,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,Point(0,0)); 

    //Setup the output into black 
    drawing = Mat::zeros(canny_output.size(),CV_8UC3); 



    //Draw contours 
    for(int i=0;i<contours.size();i++) 
    { 
     cv::drawContours(drawing,contours,i,Scalar(255,255,255),1,8,heirachy,0,Point()); 
    } 

    imshow(windowName,drawing); 

} 

Về mặt lý thuyết, Contours phương tiện phát hiện đường cong. Edge detection có nghĩa là phát hiện các cạnh. Trong mã trên của tôi, tôi đã thực hiện phát hiện cạnh bằng cách sử dụng Canny và phát hiện đường cong theo findContours(). Sau đây là kết quả hình ảnh

Canny ảnh

enter image description here

Contours ảnh

enter image description here

OK, vì vậy bây giờ, như bạn có thể thấy, không có sự khác biệt! Vì vậy, sự khác biệt thực sự giữa 2 là gì? Trong hướng dẫn OpenCV, chỉ có mã được đưa ra. Tôi đã tìm thấy giải thích về những gì là Contours nhưng nó không giải quyết được vấn đề này.

Vui lòng trợ giúp!

+0

tôi đề nghị bạn sử dụng cv :: GaussianBlur() trước khi cv :: Canny(). Điều này có thể loại bỏ phần lớn sự lộn xộn trong khi vẫn giữ các cạnh chính. – Bull

Trả lời

38

Cạnh được tính là các điểm được extrema của độ dốc hình ảnh theo hướng của độ dốc. nếu nó giúp, bạn có thể coi chúng là điểm min và max trong hàm 1D. Vấn đề là, các pixel cạnh là một khái niệm cục bộ: chúng chỉ ra một sự khác biệt đáng kể giữa các pixel lân cận.

Đường bao thường được lấy từ các cạnh, nhưng chúng nhằm mục đích là đường nét đối tượng. Vì vậy, chúng cần phải được đóng đường cong. Bạn có thể coi chúng là các đường biên (một số thuật toán Xử lý hình ảnh & các dây tóc gọi chúng như thế). Khi chúng được lấy từ các cạnh, bạn cần kết nối các cạnh để thu được đường bao khép kín.

+0

Cảm ơn bạn rất nhiều vì đã trả lời. Tôi thực sự đánh giá cao nó :) –

+0

Bạn đang chào đón :) – sansuiso

3

Đường nét thực sự có thể làm nhiều hơn một chút so với "chỉ" phát hiện các cạnh. Thuật toán thực sự tìm thấy các cạnh của hình ảnh, nhưng cũng đặt chúng trong một hệ thống phân cấp. Điều này có nghĩa là bạn có thể yêu cầu các đường viền ngoài của các đối tượng được phát hiện trong hình ảnh của bạn. Một điều như vậy sẽ không (trực tiếp) có thể nếu bạn chỉ kiểm tra các cạnh.

Như có thể đọc trong tài liệu, các đường bao được sử dụng chủ yếu để nhận dạng đối tượng, tại đó máy dò cạnh canny là hoạt động "toàn cầu" hơn. Tôi sẽ không ngạc nhiên nếu các thuật toán đường viền sử dụng một số loại phát hiện cạnh khó chịu.

+0

vì findContours() hoạt động trên hình ảnh nhị phân, tôi sẽ vô cùng ngạc nhiên nếu nó sử dụng máy dò cạnh Canny. – Bull

+0

Cảm ơn bạn rất nhiều vì đã trả lời, tôi đã tặng cho bạn +1 –

6

Sự khác biệt chính giữa việc tìm các cạnh và số đếm là nếu bạn chạy tìm các cạnh, đầu ra là hình ảnh mới. Trong hình ảnh mới (cạnh hình ảnh), bạn sẽ có các cạnh được đánh dấu. Có rất nhiều thuật toán để phát hiện các cạnh look at wiki see also.

Ví dụ: toán tử Sobel cho kết quả "sương mù" mượt mà. Trong trường hợp cụ thể của bạn, bắt là bạn đang sử dụng máy dò cạnh Canny. Điều này làm cho một vài bước xa hơn các máy dò khác. Nó thực sự chạy các bước tinh chỉnh cạnh hơn nữa. Đầu ra của máy dò Canny là hình ảnh nhị phân, với các đường rộng 1 px thay cho các cạnh.

Mặt khác, thuật toán Contours xử lý hình ảnh nhị phân tùy ý. Vì vậy, nếu bạn đặt trong hình vuông đầy màu trắng trên nền đen. Sau khi chạy thuật toán Contours, bạn sẽ có hình vuông trống màu trắng, chỉ các đường viền.

Tiền thưởng bổ sung khác của phát hiện đường viền là, nó thực sự trả về tập hợp các điểm! Điều đó thật tuyệt, bởi vì bạn có thể sử dụng những điểm này hơn nữa để xử lý một số.

Trong trường hợp cụ thể của bạn, chỉ trùng hợp ngẫu nhiên là cả hai hình ảnh đều phù hợp. Nó không quy định, và trong trường hợp của bạn, đó là vì thuộc tính duy nhất của thuật toán Canny.

+2

Sobel không thực sự là một máy dò cạnh, nó chỉ cung cấp cho gradient. Tuy nhiên, Canny tìm thấy gradient tối đa, tức là các đỉnh trong gradient. Việc thực thi OpenCV của Canny() trong thực tế sử dụng Sobel() trong giao diện người dùng của nó. – Bull

+0

Cảm ơn bạn rất nhiều vì đã trả lời, tôi đã gửi cho bạn +1 –

2

Khái niệm đường bao được sử dụng như một công cụ để làm việc trên dữ liệu cạnh. Không phải tất cả các cạnh đều giống nhau. Nhưng trong nhiều trường hợp, ví dụ: đối tượng có phân phối màu đơn sắc (tức là một màu), các cạnh là các đường bao thực tế (đường viền, hình dạng).

  1. Phát hiện không chỉ đường cong, nhưng bất cứ điều gì được kết nối trên bản đồ cạnh. (phân tích thành phần được kết nối) [1]
  2. Hữu ích cho các đối tượng có phân phối màu đơn sắc (mặt nạ tiền cảnh có thể dễ dàng tìm thấy với một ngưỡng đơn giản). Hình ảnh mẫu của bạn không phù hợp.

[1] tôpô Phân tích kết cấu của số hoá nhị phân Images bằng cách Border Sau bởi Satoshi Suzuki, năm 1985.

+0

Cảm ơn bạn rất nhiều vì đã trả lời, tôi đã cung cấp cho bạn +1 –