Chương trình kiểm tra cạnh trong python

Trong vấn đề này, chúng ta sẽ xem cách Python có thể phát hiện các cạnh của tệp hình ảnh hoặc video. Để đạt được điều này, chúng ta cần thư viện OpenCV. Thư viện OpenCV được thiết kế chủ yếu cho thị giác máy tính. Nó là mã nguồn mở. Ban đầu nó được thiết kế bởi Intel. Điều này là miễn phí để sử dụng theo giấy phép BSD mã nguồn mở

Để sử dụng chức năng OpenCV, chúng tôi cần tải chúng xuống bằng pip. OpenCV sẽ tải xuống mô-đun Numpy. Điều đó cũng sẽ cần thiết

sudo pip3 install opencv-python

Là đầu vào, trong trường hợp này, chúng tôi đã sử dụng một tệp video. Chúng tôi cũng có thể sử dụng webcam của mình để xem hiệu ứng thời gian thực của quy trình phát hiện cạnh này

Ở đây chúng tôi đang sử dụng một tập tin video. Hình ảnh thực tế (khung hình của video) giống như thế này -

Chương trình kiểm tra cạnh trong python

Cách phát hiện cạnh hoạt động?

Để phát hiện các cạnh, có một số quan sát toán học để kiểm tra xem độ sáng của pixel có thay đổi rõ rệt không

Chúng tôi cần tìm độ dốc cho phiên bản thang độ xám của hình ảnh của chúng tôi. Trong thị giác máy tính, khi các pixel chuyển từ đen sang trắng, nó được ghi nhận là độ dốc dương. Đối với quá trình chuyển đổi từ trắng sang đen, đó là độ dốc âm

Phát hiện cạnh bằng cách sử dụng Đạo hàm của hình ảnh

Một hình ảnh được lưu trữ dưới dạng ma trận, trong đó mỗi phần tử của ma trận đó chứa thông tin về tất cả các pixel. Để tìm đạo hàm, chúng ta cần toán tử Laplacian. Vì vậy, để có được Laplacian, đầu tiên chúng ta cần các đạo hàm Sobel. Các dẫn xuất Sobel này được sử dụng để lấy biến thể độ dốc của hình ảnh

Đạo hàm ngang Sobel (Sobel X)

Đạo hàm Sobel này thu được thông qua phép tích chập của ảnh thực tế và một ma trận khác (gọi là kernel). Hạt nhân là ma trận 3x3 cho trường hợp đơn giản

Có một chức năng gọi là sobel(). Sử dụng chức năng này, chúng ta có thể tìm thấy các đạo hàm sobel. Khi chúng tôi đang cố lấy Sobel x, thì phần y phải bằng 0

mã ví dụ

import cv2
import numpy as np
capture = cv2.VideoCapture('sample_video.mp4') #Capture frames from video file.
while(capture.isOpened()): # Run the loop until the video ends
   ret, frame = capture.read() #Fetch the frames from video
   # Convert BGR color to (Hue Saturation Value) mode
   hsv_col = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
   # The Sobelx Method
   sobelx = cv2.Sobel(frame,cv2.CV_64F,1,0,ksize=5)
   cv2.imshow('SobelX',sobelx)
   k = cv2.waitKey(5) & 0xFF
   if k == 27: #27 is the ASCII for ESC key. When ESC is pressed, it will stop
      break
capture.release()
cv2.destroyAllWindows() #Clean memory after removing the windows

đầu ra

Chương trình kiểm tra cạnh trong python

Đạo hàm Sobel Dọc (Sobel Y)

Tương tự, chúng ta có thể tìm đạo hàm Sobel dọc bằng cách sử dụng hàm sobel(). Trong trường hợp này, phần x sẽ là 0

mã ví dụ

import cv2
import numpy as np
capture = cv2.VideoCapture('sample_video.mp4') #Capture frames from video file.
while(capture.isOpened()): # Run the loop until the video ends
   ret, frame = capture.read() #Fetch the frames from video
   # Convert BGR color to (Hue Saturation Value) mode
   hsv_col = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
   # The Sobely Method
   sobely = cv2.Sobel(frame,cv2.CV_64F,0,1,ksize=5)
   cv2.imshow('SobelY',sobely)
   k = cv2.waitKey(5) & 0xFF
   if k == 27: #27 is the ASCII for ESC key. When ESC is pressed, it will stop
      break
capture.release()
cv2.destroyAllWindows() #Clean memory after removing the windows

đầu ra

Chương trình kiểm tra cạnh trong python

Đạo hàm Laplacian

Cuối cùng, chúng ta sẽ thấy Đạo hàm Laplacian của hình ảnh. Có một chức năng gọi là Laplacian(). Nó được sử dụng để lấy đạo hàm

Phát hiện cạnh là một kỹ thuật xử lý ảnh, được sử dụng để xác định ranh giới (các cạnh) của các đối tượng hoặc các vùng trong ảnh. Các cạnh là một trong những tính năng quan trọng nhất liên quan đến hình ảnh. Chúng ta biết về cấu trúc cơ bản của một hình ảnh thông qua các cạnh của nó. Do đó, các đường ống xử lý thị giác máy tính sử dụng rộng rãi tính năng phát hiện cạnh trong các ứng dụng

  1. Các cạnh được phát hiện như thế nào?
  2. Phát hiện cạnh Sobel
  3. Phát hiện cạnh Canny
  4. Bản tóm tắt

Các cạnh được phát hiện như thế nào?

Các cạnh được đặc trưng bởi sự thay đổi đột ngột về cường độ pixel. Để phát hiện các cạnh, chúng ta cần tìm kiếm những thay đổi như vậy trong các pixel lân cận. Nào, hãy khám phá việc sử dụng hai thuật toán phát hiện cạnh quan trọng có sẵn trong OpenCV. Phát hiện cạnh Sobel và Phát hiện cạnh Canny. Chúng ta sẽ thảo luận lý thuyết cũng như trình diễn cách sử dụng từng loại trong OpenCV

Trước tiên, hãy xem đoạn mã sẽ minh họa tính năng phát hiện cạnh. Each line of code will be discussed in detail  so that you understand it fully

con trăn

import cv2

# Read the original image
img = cv2.imread('test.jpg') 
# Display original image
cv2.imshow('Original', img)
cv2.waitKey(0)

# Convert to graycsale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Blur the image for better edge detection
img_blur = cv2.GaussianBlur(img_gray, (3,3), 0) 

# Sobel Edge Detection
sobelx = cv2.Sobel(src=img_blur, ddepth=cv2.CV_64F, dx=1, dy=0, ksize=5) # Sobel Edge Detection on the X axis
sobely = cv2.Sobel(src=img_blur, ddepth=cv2.CV_64F, dx=0, dy=1, ksize=5) # Sobel Edge Detection on the Y axis
sobelxy = cv2.Sobel(src=img_blur, ddepth=cv2.CV_64F, dx=1, dy=1, ksize=5) # Combined X and Y Sobel Edge Detection
# Display Sobel Edge Detection Images
cv2.imshow('Sobel X', sobelx)
cv2.waitKey(0)
cv2.imshow('Sobel Y', sobely)
cv2.waitKey(0)
cv2.imshow('Sobel X Y using Sobel() function', sobelxy)
cv2.waitKey(0)

# Canny Edge Detection
edges = cv2.Canny(image=img_blur, threshold1=100, threshold2=200) # Canny Edge Detection
# Display Canny Edge Detection Image
cv2.imshow('Canny Edge Detection', edges)
cv2.waitKey(0)

cv2.destroyAllWindows()

C++

#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}

Chương trình kiểm tra cạnh trong python

ƯU ĐÃI ĐƯỢC CHỜ NHẤT TRONG NĂM DÀNH CHO CÁC AI ĐAM MÊ LÀ ĐÂY

MUA NGAY

Chúng tôi cho rằng bạn đã có OpenCV trong hệ thống của mình. Nếu bạn cần cài đặt OpenCV, vui lòng truy cập liên kết có liên quan bên dưới

  1. Cài đặt OpenCV trên Windows
  2. Cài đặt OpenCV trên MacOS
  3. Cài đặt OpenCV trên Ubuntu

Hình ảnh con hổ này sẽ được sử dụng cho tất cả các ví dụ ở đây.  

Chương trình kiểm tra cạnh trong python
Hình ảnh được sử dụng để phát hiện cạnh

Trước khi đi vào chi tiết từng thuật toán, hãy hoàn thành một số bước sơ bộ cần thiết để phát hiện cạnh. Bắt đầu bằng cách nhập thư viện OpenCV, như được hiển thị trong mã bên dưới.  

con trăn

import cv2

Tải xuống mã Để dễ dàng làm theo hướng dẫn này, vui lòng tải xuống mã bằng cách nhấp vào nút bên dưới. Nó miễn phí.

Tải xuống mã

C++

#include
#include

// Namespace nullifies the use of cv::function(); 
using namespace std;
using namespace cv;

Bước đầu tiên là đọc trong ảnh, sử dụng hàm

#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}
0 trong OpenCV.  

Ở đây, chúng tôi đọc ảnh màu dưới dạng ảnh thang độ xám vì bạn không cần thông tin màu để phát hiện các cạnh. Nếu bạn muốn tìm hiểu thêm về các tùy chọn có sẵn để đọc hình ảnh, vui lòng tham khảo bài viết tại đây

Sau khi đọc hình ảnh, chúng tôi cũng làm mờ nó, sử dụng chức năng

#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}
1. Điều này được thực hiện để giảm nhiễu trong hình ảnh. Trong phát hiện cạnh, các đạo hàm số của cường độ pixel phải được tính toán và điều này thường dẫn đến các cạnh 'nhiễu'. Nói cách khác, cường độ của các pixel lân cận trong ảnh (đặc biệt là các cạnh gần) có thể dao động khá nhiều, dẫn đến các cạnh không đại diện cho cấu trúc cạnh chiếm ưu thế mà chúng tôi đang tìm kiếm.  

Làm mờ làm mịn sự thay đổi cường độ gần các cạnh, giúp dễ dàng xác định cấu trúc cạnh chiếm ưu thế trong hình ảnh. Bạn có thể tham khảo trang tài liệu OpenCV để biết thêm chi tiết về hàm

#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}
1. Chúng tôi cung cấp kích thước của hạt tích chập (trong trường hợp này là 1 hạt nhân 3×3), xác định mức độ mờ

con trăn

import cv2
import numpy as np
capture = cv2.VideoCapture('sample_video.mp4') #Capture frames from video file.
while(capture.isOpened()): # Run the loop until the video ends
   ret, frame = capture.read() #Fetch the frames from video
   # Convert BGR color to (Hue Saturation Value) mode
   hsv_col = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
   # The Sobelx Method
   sobelx = cv2.Sobel(frame,cv2.CV_64F,1,0,ksize=5)
   cv2.imshow('SobelX',sobelx)
   k = cv2.waitKey(5) & 0xFF
   if k == 27: #27 is the ASCII for ESC key. When ESC is pressed, it will stop
      break
capture.release()
cv2.destroyAllWindows() #Clean memory after removing the windows
0

C++

import cv2
import numpy as np
capture = cv2.VideoCapture('sample_video.mp4') #Capture frames from video file.
while(capture.isOpened()): # Run the loop until the video ends
   ret, frame = capture.read() #Fetch the frames from video
   # Convert BGR color to (Hue Saturation Value) mode
   hsv_col = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
   # The Sobelx Method
   sobelx = cv2.Sobel(frame,cv2.CV_64F,1,0,ksize=5)
   cv2.imshow('SobelX',sobelx)
   k = cv2.waitKey(5) & 0xFF
   if k == 27: #27 is the ASCII for ESC key. When ESC is pressed, it will stop
      break
capture.release()
cv2.destroyAllWindows() #Clean memory after removing the windows
1

Phát hiện cạnh Sobel

Sobel Edge Detection là một trong những thuật toán được sử dụng rộng rãi nhất để phát hiện cạnh. Toán tử Sobel phát hiện các cạnh được đánh dấu bằng những thay đổi đột ngột về cường độ pixel, như thể hiện trong hình bên dưới

Chương trình kiểm tra cạnh trong python
Cường độ pixel là một hàm của t (Nguồn)

Sự gia tăng cường độ thậm chí còn rõ ràng hơn, khi chúng ta vẽ đạo hàm bậc nhất của hàm cường độ

Chương trình kiểm tra cạnh trong python
Đạo hàm đầu tiên của cường độ Pixel dưới dạng hàm của t (Nguồn)

Biểu đồ trên chứng minh rằng các cạnh có thể được phát hiện ở những khu vực có độ dốc cao hơn một giá trị ngưỡng cụ thể. Ngoài ra, một sự thay đổi đột ngột trong đạo hàm cũng sẽ cho thấy sự thay đổi về cường độ pixel. Với suy nghĩ này, chúng ta có thể tính gần đúng đạo hàm, sử dụng nhân 3×3. Chúng tôi sử dụng một nhân để phát hiện những thay đổi đột ngột về cường độ pixel theo hướng X và một nhân khác theo hướng Y. (Để tìm hiểu thêm về bộ lọc hình ảnh và hạt tích chập, hãy nhấp vào đây)

Đây là những hạt nhân được sử dụng cho Sobel Edge Detection

(1)  

Chương trình kiểm tra cạnh trong python

Hạt nhân hướng X

(2)  

Chương trình kiểm tra cạnh trong python

Hạt nhân hướng Y

Khi các hạt nhân này được kết hợp với hình ảnh ban đầu, bạn sẽ có được 'Hình ảnh cạnh Sobel'.  

  • Nếu chúng ta chỉ sử dụng Nhân dọc, phép tích chập sẽ tạo ra hình ảnh Sobel, với các cạnh được tăng cường theo hướng X
  • Sử dụng Hạt nhân ngang tạo ra hình ảnh Sobel, với các cạnh được tăng cường theo hướng Y.  

Cho

Chương trình kiểm tra cạnh trong python
Chương trình kiểm tra cạnh trong python
biểu thị độ dốc cường độ trong
Chương trình kiểm tra cạnh trong python
Chương trình kiểm tra cạnh trong python
. Nếu
Chương trình kiểm tra cạnh trong python
Chương trình kiểm tra cạnh trong python
biểu thị các hạt nhân X và Y được xác định ở trên.

(3)  

Chương trình kiểm tra cạnh trong python

(4)  

Chương trình kiểm tra cạnh trong python

trong đó

Chương trình kiểm tra cạnh trong python
biểu thị toán tử tích chập và
Chương trình kiểm tra cạnh trong python
biểu thị hình ảnh đầu vào.

Giá trị gần đúng cuối cùng của  độ lớn của độ dốc,

Chương trình kiểm tra cạnh trong python
có thể được tính như sau.

(5)  

Chương trình kiểm tra cạnh trong python

Và hướng của gradient sau đó có thể được tính gần đúng như

(6)  

Chương trình kiểm tra cạnh trong python

Trong ví dụ mã bên dưới, chúng tôi sử dụng hàm

#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}
3 để tính toán

  • hình ảnh cạnh Sobel riêng lẻ, theo cả hai hướng (x và y),
  • gradient tổng hợp theo cả hai hướng (xy)

Sau đây là cú pháp để áp dụng phát hiện cạnh Sobel bằng OpenCV

#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}
4

Tham số

#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}
5 chỉ định độ chính xác của hình ảnh đầu ra, trong khi
#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}
6 và
#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}
7 chỉ định thứ tự của đạo hàm theo mỗi hướng. Ví dụ

  • Nếu
    #include 
    #include 
    // using namespaces to nullify use of cv::function(); syntax and std::function();
    using namespace std;
    using namespace cv;
    
    int main()
    {
        // Reading image
        Mat img = imread("test.jpg");
        // Display original image
        imshow("original Image", img);
        waitKey(0);
    
        // Convert to graycsale
        Mat img_gray;
        cvtColor(img, img_gray, COLOR_BGR2GRAY);
        // Blur the image for better edge detection
        Mat img_blur;
        GaussianBlur(img_gray, img_blur, Size(3,3), 0);
        
        // Sobel edge detection
        Mat sobelx, sobely, sobelxy;
        Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
        Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
        Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
        // Display Sobel edge detection images
        imshow("Sobel X", sobelx);
        waitKey(0);
        imshow("Sobel Y", sobely);
        waitKey(0);
        imshow("Sobel XY using Sobel() function", sobelxy);
        waitKey(0);
    
        // Canny edge detection
        Mat edges;
        Canny(img_blur, edges, 100, 200, 3, false);
        // Display canny edge detected image
        imshow("Canny edge detection", edges);
        waitKey(0);
        
        destroyAllWindows();
        return 0;
    }
    
    8 và
    #include 
    #include 
    // using namespaces to nullify use of cv::function(); syntax and std::function();
    using namespace std;
    using namespace cv;
    
    int main()
    {
        // Reading image
        Mat img = imread("test.jpg");
        // Display original image
        imshow("original Image", img);
        waitKey(0);
    
        // Convert to graycsale
        Mat img_gray;
        cvtColor(img, img_gray, COLOR_BGR2GRAY);
        // Blur the image for better edge detection
        Mat img_blur;
        GaussianBlur(img_gray, img_blur, Size(3,3), 0);
        
        // Sobel edge detection
        Mat sobelx, sobely, sobelxy;
        Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
        Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
        Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
        // Display Sobel edge detection images
        imshow("Sobel X", sobelx);
        waitKey(0);
        imshow("Sobel Y", sobely);
        waitKey(0);
        imshow("Sobel XY using Sobel() function", sobelxy);
        waitKey(0);
    
        // Canny edge detection
        Mat edges;
        Canny(img_blur, edges, 100, 200, 3, false);
        // Display canny edge detected image
        imshow("Canny edge detection", edges);
        waitKey(0);
        
        destroyAllWindows();
        return 0;
    }
    
    9, chúng ta tính ảnh Sobel đạo hàm thứ nhất theo hướng x

Nếu cả

#include 
#include 
// using namespaces to nullify use of cv::function(); syntax and std::function();
using namespace std;
using namespace cv;

int main()
{
    // Reading image
    Mat img = imread("test.jpg");
    // Display original image
    imshow("original Image", img);
    waitKey(0);

    // Convert to graycsale
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    // Blur the image for better edge detection
    Mat img_blur;
    GaussianBlur(img_gray, img_blur, Size(3,3), 0);
    
    // Sobel edge detection
    Mat sobelx, sobely, sobelxy;
    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);
    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);
    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);
    // Display Sobel edge detection images
    imshow("Sobel X", sobelx);
    waitKey(0);
    imshow("Sobel Y", sobely);
    waitKey(0);
    imshow("Sobel XY using Sobel() function", sobelxy);
    waitKey(0);

    // Canny edge detection
    Mat edges;
    Canny(img_blur, edges, 100, 200, 3, false);
    // Display canny edge detected image
    imshow("Canny edge detection", edges);
    waitKey(0);
    
    destroyAllWindows();
    return 0;
}
8 và
import cv2
1, chúng tôi tính toán ảnh Sobel đạo hàm thứ nhất theo cả hai hướng

con trăn

import cv2
import numpy as np
capture = cv2.VideoCapture('sample_video.mp4') #Capture frames from video file.
while(capture.isOpened()): # Run the loop until the video ends
   ret, frame = capture.read() #Fetch the frames from video
   # Convert BGR color to (Hue Saturation Value) mode
   hsv_col = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
   # The Sobely Method
   sobely = cv2.Sobel(frame,cv2.CV_64F,0,1,ksize=5)
   cv2.imshow('SobelY',sobely)
   k = cv2.waitKey(5) & 0xFF
   if k == 27: #27 is the ASCII for ESC key. When ESC is pressed, it will stop
      break
capture.release()
cv2.destroyAllWindows() #Clean memory after removing the windows
1

C++

import cv2
import numpy as np
capture = cv2.VideoCapture('sample_video.mp4') #Capture frames from video file.
while(capture.isOpened()): # Run the loop until the video ends
   ret, frame = capture.read() #Fetch the frames from video
   # Convert BGR color to (Hue Saturation Value) mode
   hsv_col = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
   # The Sobely Method
   sobely = cv2.Sobel(frame,cv2.CV_64F,0,1,ksize=5)
   cv2.imshow('SobelY',sobely)
   k = cv2.waitKey(5) & 0xFF
   if k == 27: #27 is the ASCII for ESC key. When ESC is pressed, it will stop
      break
capture.release()
cv2.destroyAllWindows() #Clean memory after removing the windows
2

Kết quả được thể hiện trong các hình dưới đây. Xem cách hình ảnh Sobel theo hướng x xác định chủ yếu các cạnh dọc (i. e. những người có độ dốc lớn nhất theo hướng x, nằm ngang). Và theo hướng y xác định cạnh ngang (i. e. những người có độ dốc lớn nhất theo hướng y, dọc). Nhìn kỹ vào các sọc của hổ trong cả hai hình ảnh. Note how the strong vertical edges of the stripes are more evident in the Sobel image in the x-direction

Chương trình kiểm tra cạnh trong python
Hình ảnh cạnh Sobel, với cạnh được tăng cường theo hướng X

Chương trình kiểm tra cạnh trong python
Hình ảnh Sobel Edge, với cạnh được tăng cường theo hướng Y

Hình bên dưới hiển thị hình ảnh Sobel cho độ dốc theo cả hai hướng, giúp chắt lọc hình ảnh gốc thành biểu diễn cấu trúc cạnh, sao cho tính toàn vẹn cấu trúc của nó vẫn còn nguyên vẹn

Chương trình kiểm tra cạnh trong python
Hình ảnh Sobel Edge, với cạnh được tăng cường theo hướng XY

Phát hiện cạnh Canny

Canny Edge Detection là một trong những phương pháp phát hiện cạnh phổ biến nhất được sử dụng hiện nay vì nó rất mạnh mẽ và linh hoạt. Bản thân thuật toán tuân theo quy trình ba giai đoạn để trích xuất các cạnh từ một hình ảnh. Thêm vào đó làm mờ hình ảnh, một bước tiền xử lý cần thiết để giảm nhiễu. Điều này làm cho nó trở thành một quá trình bốn giai đoạn, bao gồm

  1. Giảm tiếng ồn
  2. Tính độ dốc cường độ của hình ảnh
  3. Suppression of False Edges
  4. Ngưỡng trễ

Giảm tiếng ồn

Pixel hình ảnh thô thường có thể dẫn đến các cạnh nhiễu, do đó, điều quan trọng là phải giảm nhiễu trước khi tính toán các cạnh Trong Canny Edge Detection, bộ lọc làm mờ Gaussian được sử dụng để loại bỏ hoặc giảm thiểu chi tiết không cần thiết có thể dẫn đến các cạnh không mong muốn. Hãy quan sát con hổ trong hai hình ảnh bên dưới, Gaussian blur đã được áp dụng cho hình ảnh bên phải. Như bạn có thể thấy, nó có vẻ hơi mờ, nhưng vẫn giữ được một lượng chi tiết đáng kể mà từ đó các cạnh có thể được tính toán. Để tìm hiểu thêm về làm mờ, vui lòng nhấp vào đây

Chương trình kiểm tra cạnh trong python
So sánh hình ảnh gốc và hình ảnh mờ

Tính độ dốc cường độ của hình ảnh

Khi hình ảnh đã được làm mịn (làm mờ), nó được lọc bằng nhân Sobel, theo cả chiều ngang và chiều dọc. Sau đó, kết quả từ các thao tác lọc này được sử dụng để tính cả độ lớn của gradient cường độ (

Chương trình kiểm tra cạnh trong python
) và hướng (
Chương trình kiểm tra cạnh trong python
) cho mỗi pixel, như minh họa bên dưới.

(7)  

Chương trình kiểm tra cạnh trong python

(8)  

Chương trình kiểm tra cạnh trong python

Hướng gradient sau đó được làm tròn đến góc 45 độ gần nhất. Hình bên dưới (bên phải) cho thấy kết quả của bước xử lý kết hợp này

Chương trình kiểm tra cạnh trong python
So sánh hình ảnh Bộ lọc gốc và Sobel

Suppression of False Edges

Sau khi giảm nhiễu và tính toán độ dốc cường độ, thuật toán trong bước này sử dụng một kỹ thuật gọi là triệt tiêu không tối đa các cạnh để lọc ra các pixel không mong muốn (có thể không thực sự tạo thành một cạnh). Để thực hiện điều này, mỗi pixel được so sánh với các pixel lân cận của nó, theo hướng gradient dương và âm. Nếu độ dốc của pixel hiện tại lớn hơn các pixel lân cận, thì nó không thay đổi. Mặt khác, độ lớn của pixel hiện tại được đặt thành 0. Hình ảnh sau đây minh họa một ví dụ. Như bạn có thể thấy, nhiều 'góc cạnh' liên quan đến bộ lông của hổ đã được làm dịu đi đáng kể

Chương trình kiểm tra cạnh trong python
So sánh hình ảnh Bộ lọc Sobel với hình ảnh triệt tiêu không tối đa

Ngưỡng trễ

Trong bước cuối cùng này của Canny Edge Detection, độ dốc được so sánh với hai giá trị ngưỡng, một giá trị nhỏ hơn giá trị kia.  

  • Nếu giá trị độ dốc cao hơn giá trị ngưỡng lớn hơn, thì các pixel đó được liên kết với các cạnh mạnh và được bao gồm trong bản đồ cạnh cuối cùng
  • Nếu các giá trị độ dốc thấp hơn giá trị ngưỡng nhỏ hơn, thì các pixel sẽ bị chặn và loại trừ khỏi bản đồ cạnh cuối cùng
  • Tất cả các pixel khác, có độ dốc nằm giữa hai ngưỡng này, được đánh dấu là các cạnh 'yếu' (i. e. họ trở thành ứng cử viên để được đưa vào bản đồ cạnh cuối cùng).  
  • Nếu các pixel 'yếu' được kết nối với các pixel được liên kết với các cạnh mạnh, thì chúng cũng được đưa vào bản đồ cạnh cuối cùng.  

Sau đây là cú pháp áp dụng phát hiện cạnh Canny bằng OpenCV

import cv2
2

Trong mã ví dụ bên dưới, hàm 

import cv2
3 triển khai phương pháp được mô tả ở trên. Chúng tôi chỉ cung cấp hai ngưỡng được sử dụng bởi thuật toán Canny Edge Detection và OpenCV xử lý tất cả các chi tiết triển khai. Đừng quên làm mờ hình ảnh, trước khi gọi hàm
import cv2
3. Đây là bước tiền xử lý rất được khuyến khích. Để tìm hiểu thêm về các đối số tùy chọn, vui lòng tham khảo trang tài liệu OpenCV

con trăn

import cv2
import numpy as np
capture = cv2.VideoCapture('sample_video.mp4') #Capture frames from video file.
while(capture.isOpened()): # Run the loop until the video ends
   ret, frame = capture.read() #Fetch the frames from video
   # Convert BGR color to (Hue Saturation Value) mode
   hsv_col = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
   # The Sobely Method
   sobely = cv2.Sobel(frame,cv2.CV_64F,0,1,ksize=5)
   cv2.imshow('SobelY',sobely)
   k = cv2.waitKey(5) & 0xFF
   if k == 27: #27 is the ASCII for ESC key. When ESC is pressed, it will stop
      break
capture.release()
cv2.destroyAllWindows() #Clean memory after removing the windows
6

C++

import cv2
import numpy as np
capture = cv2.VideoCapture('sample_video.mp4') #Capture frames from video file.
while(capture.isOpened()): # Run the loop until the video ends
   ret, frame = capture.read() #Fetch the frames from video
   # Convert BGR color to (Hue Saturation Value) mode
   hsv_col = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
   # The Sobely Method
   sobely = cv2.Sobel(frame,cv2.CV_64F,0,1,ksize=5)
   cv2.imshow('SobelY',sobely)
   k = cv2.waitKey(5) & 0xFF
   if k == 27: #27 is the ASCII for ESC key. When ESC is pressed, it will stop
      break
capture.release()
cv2.destroyAllWindows() #Clean memory after removing the windows
7

Đây là kết quả cuối cùng. Chúng tôi sử dụng ngưỡng dưới là 100 và ngưỡng trên là 200. Như bạn có thể thấy, thuật toán đã xác định các cạnh chiếm ưu thế trong hình ảnh, trong quá trình loại bỏ những cạnh ít quan trọng hơn đối với cấu trúc tổng thể. Tuy nhiên, kết quả có thể dễ dàng được điều chỉnh, vì vậy hãy thử nghiệm với các hình ảnh khác nhau, thay đổi mức độ mờ và thử các giá trị ngưỡng khác nhau để tự mình cảm nhận mọi thứ

Chương trình kiểm tra cạnh trong python
Hình ảnh cuối cùng sau khi Canny Edge Detection

Khi nói đến hiệu suất, Canny Edge Detection tạo ra kết quả tốt nhất vì nó không chỉ sử dụng Sobel Edge Detection mà còn Ngưỡng triệt tiêu không tối đa và độ trễ. Điều này mang lại sự linh hoạt hơn trong cách xác định và kết nối các cạnh trong giai đoạn cuối của thuật toán.  

Bản tóm tắt

Chúng ta đã thảo luận điều gì làm cho phát hiện cạnh trở thành một kỹ thuật xử lý hình ảnh quan trọng và tập trung vào việc tìm hiểu hai thuật toán quan trọng nhất của nó (Phát hiện cạnh Sobel và Phát hiện cạnh Canny). Trong khi chứng minh việc sử dụng chúng trong OpenCV, chúng tôi đã nhấn mạnh lý do tại sao làm mờ lại là một bước tiền xử lý quan trọng như vậy.  

Bạn cũng đã thấy cách Canny Edge Detection thực sự sử dụng toán tử Sobel để tính đạo hàm số. Và mạnh mẽ và linh hoạt, sử dụng ngay cả Ngưỡng triệt tiêu và trễ không tối đa để đạt được lợi thế tối đa. Cuối cùng, bạn đã hiểu tại sao Canny Edge Detection là phương pháp ưa thích và được sử dụng rộng rãi nhất để thực hiện phát hiện cạnh.  

Bạn có thể tìm thấy tất cả các mã được thảo luận trong bài đăng này tại liên kết này → Phát hiện cạnh bằng OpenCV Colab Notebook

What is edge in python?

Hàm edge() là một hàm sẵn có trong thư viện Python Wand ImageMagick được sử dụng để áp dụng bộ lọc tích chập để phát hiện các cạnh . cú pháp. cạnh (bán kính) Tham số. Hàm này chấp nhận một tham số như đã đề cập ở trên và được xác định bên dưới. bán kính. Tham số này lưu trữ khẩu độ của bộ lọc phát hiện.

Thuật toán nào được sử dụng để phát hiện cạnh?

Canny năm 1986 được coi là thuật toán phát hiện cạnh lý tưởng cho ảnh bị nhiễu. Mục đích của Canny là khám phá thuật toán phát hiện cạnh tối ưu giúp giảm xác suất phát hiện cạnh giả và cho các cạnh sắc nét.

Phát hiện cạnh trong OpenCV là gì?

Phát hiện cạnh là kỹ thuật xử lý hình ảnh, được sử dụng để xác định ranh giới (các cạnh) của đối tượng hoặc vùng trong ảnh . Các cạnh là một trong những tính năng quan trọng nhất liên quan đến hình ảnh. Chúng ta biết về cấu trúc cơ bản của một hình ảnh thông qua các cạnh của nó.

EDGE có thể được phát hiện như thế nào?

Các phương pháp dựa trên tìm kiếm phát hiện các cạnh bằng cách tính toán trước tiên một phép đo cường độ cạnh, thường là biểu thức đạo hàm bậc nhất chẳng hạn như độ lớn của gradient, sau đó tìm kiếm cực đại định hướng cục bộ của cường độ gradient bằng cách sử dụng ước tính được tính toán về hướng cục bộ của