Computer >> Máy Tính >  >> Lập trình >> Python

Phát hiện dòng trong python với OpenCV?

Trong bài đăng này, chúng ta sẽ tìm hiểu cách phát hiện các đường trong một hình ảnh, với sự trợ giúp của một kỹ thuật gọi là biến đổi Hough.

Biến đổi nhanh?

Biến đổi Hough là một phương pháp trích xuất đối tượng địa lý để phát hiện bất kỳ hình dạng đơn giản nào, nếu bạn có thể biểu diễn hình dạng đó dưới dạng toán học. Bằng cách nào đó, nó quản lý để phát hiện hình dạng ngay cả khi nó bị hỏng hoặc bị bóp méo một chút. Chúng ta sẽ xem nó hoạt động như thế nào đối với một dòng.

Hình dạng "đơn giản" là hình dạng chỉ có thể được biểu diễn bằng một vài tham số. Ví dụ:một đường chỉ có thể được biểu diễn bằng hai tham số (độ dốc, điểm giao nhau) và một đường tròn có ba tham số - tọa độ của tâm và bán kính (x, y, r).

Phát hiện các đường từ một hình ảnh bằng cách sử dụng biến đổi Hough

Một đường có thể được biểu diễn bằng một phương trình - hoặc ở dạng tham số, nó có thể được biểu diễn dưới dạng, trong đó (ρ) là khoảng cách vuông góc từ điểm gốc đến đường thẳng và ϴ là góc tạo bởi đường vuông góc này và trục hoành được đo bằng máy đếm -theo chiều kim đồng hồ (Biểu diễn này được sử dụng trong OpenCV). Kiểm tra hình ảnh bên dưới


Phát hiện dòng trong python với OpenCV?

Vì vậy, nếu đường thẳng đi qua phía dưới gốc tọa độ, nó sẽ có giá trị dương và góc nhỏ hơn 180. Nếu nó đi qua điểm gốc, thay vì lấy góc lớn hơn 180, góc được lấy nhỏ hơn 180 và rho được lấy âm. Mọi đường thẳng đứng sẽ có 0 độ và các đường ngang sẽ có 90 độ.

Bộ tích lũy

Bất kỳ dòng nào cũng có thể được biểu diễn bằng hai thuật ngữ này (ρ, ϴ). Vì vậy, trước tiên nó tạo một mảng hoặc bộ tích lũy 2D (để giữ các giá trị của hai tham số) và ban đầu nó được đặt thành 0. Trong đó các hàng biểu thị ρ và các cột biểu thị ϴ. Kích thước của mảng phụ thuộc vào độ chính xác mà chúng ta cần, ví dụ, nếu chúng ta cần độ chính xác của các góc là 1 độ, bạn cần 180 cột và ρ, khoảng cách tối đa có thể là độ dài đường chéo của hình ảnh và ρ là khoảng cách tối đa có thể là độ dài đường chéo của hình ảnh. Vì vậy, lấy độ chính xác một pixel và số hàng có thể là chiều dài đường chéo của hình ảnh.

Hãy xem xét chúng ta có một hình ảnh 100 * 100 với một đường ngang ở giữa. Lấy điểm đầu tiên của đoạn thẳng và chúng ta biết các giá trị (x, y) của nó. Bây giờ trong phương trình, pu các giá trị ϴ =0,1,2,3… 180 và kiểm tra giá trị ρ mà bạn nhận được. Đối với mọi cặp (ρ, ϴ), giá trị gia tăng của từng cặp là bộ tích lũy của chúng ta trong các ô (ρ, ϴ) tương ứng của nó. Vì vậy, bây giờ trong bộ tích lũy, ô (50,90) =1 cùng với một số ô khác. Bây giờ lấy vị trí thứ hai trên dòng. Lặp lại quy trình tương tự như chúng tôi đã làm cho vị trí đầu tiên. Tăng giá trị trong các ô tương ứng với (ρ, ϴ) mà bạn nhận được. Lần này, ô (50,90) =2. Vì vậy, chúng tôi thực sự đang biểu quyết các giá trị (ρ, ϴ). Chúng tôi tiếp tục quá trình này cho mọi điểm trên đường dây. Tại mỗi vị trí, ô (50,90) sẽ được tăng dần hoặc được bỏ phiếu, trong khi các ô khác có thể không được bỏ phiếu. Bằng cách này, ở cuối ô (50,90) sẽ có số phiếu bầu tối đa. Vì vậy, nếu bạn tìm kiếm bộ tích lũy cho số phiếu bầu tối đa, bạn sẽ nhận được giá trị (50,90) cho biết, có một dòng trong hình ảnh này ở khoảng cách 50 từ điểm gốc và ở góc 90 độ. Đây là cách hoạt động của phép biến đổi hough cho các đường.

Hough Transform trong OpenCV

Mọi thứ được giải thích ở trên được gói gọn trong hàm OpenCV, cv2.HoughLines (). Nó chỉ trả về một mảng các giá trị (ρ, ϴ) trong đó ρ được đo bằng pixel và ϴ được đo bằng radian.

Dưới đây là chương trình phát hiện dòng sử dụng openCV và biến đổi dòng hough.

Dưới đây là hình ảnh thực tế của một bãi đậu xe và chúng tôi sẽ thực hiện phát hiện đường trên hình ảnh này bằng cách sử dụng biến đổi đường hough và thư viện OpenCV.

Phát hiện dòng trong python với OpenCV?

Ví dụ

import cv2
import numpy as np
img = cv2.imread("parkingLot1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 75, 150)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 30, maxLineGap=250)
for line in lines:
   x1, y1, x2, y2 = line[0]
   cv2.line(img, (x1, y1), (x2, y2), (0, 0, 128), 1)
cv2.imshow("linesEdges", edges)
cv2.imshow("linesDetected", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Kết quả

Phát hiện dòng trong python với OpenCV?

Và các dòng được phát hiện−

Phát hiện dòng trong python với OpenCV?