2017-02-13 31 views
8

Tôi gặp sự cố khi phát hiện khu vực vòng tròn. Tôi đã thử nó với hàm HoughCircles từ opencv. Tuy nhiên, mặc dù các hình ảnh khá giống với các tham số cho chức năng phải khác nhau để phát hiện các cirles.python opencv - phát hiện đốm hoặc phát hiện vòng tròn

Một cách tiếp cận khác mà tôi đã thử là lặp qua mọi pixel và kiểm tra xem pixel hiện tại có màu trắng hay không. Nếu đây là trường hợp sau đó kiểm tra xem có một đối tượng blob trong khu vực (khoảng cách đến trung tâm blob nhỏ hơn một ngưỡng). Nếu có, hãy thêm điểm ảnh vào đốm màu, nếu không thì hãy tạo một đốm màu mới. Điều này cũng không hoạt động đúng cách.

Có ai biết cách tôi có thể thực hiện công việc này (phát hiện 90%) không? Tôi đã đính kèm một hình ảnh mẫu và một hình ảnh khác nơi tôi đã đánh dấu các hình tròn. Cảm ơn!

example

example with arrows

UPDATE: Cảm ơn bạn đã giúp đỡ cho đến nay! Đây là mã mà tôi có được các đường bao và lọc chúng theo khu vực:

im = cv2.imread('extract_blue.jpg') 
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) 
im_gauss = cv2.GaussianBlur(imgray, (5, 5), 0) 
ret, thresh = cv2.threshold(im_gauss, 127, 255, 0) 
# get contours 
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 

contours_area = [] 
# calculate area and filter into new array 
for con in contours: 
    area = cv2.contourArea(con) 
    if 1000 < area < 10000: 
     contours_area.append(con) 

Công trình này khá gọn gàng. Tôi đã thu hút họ vào hình ảnh: contours_filtered_area

Đây là phần mà tôi lọc bởi tuần hoàn, nó đi thẳng bên dưới mã nơi tôi lọc theo khu vực:

contours_cirles = [] 

# check if contour is of circular shape 
for con in contours_area: 
    perimeter = cv2.arcLength(con, True) 
    area = cv2.contourArea(con) 
    if perimeter == 0: 
     break 
    circularity = 4*math.pi*(area/perimeter*perimeter) 
    print circularity 
    if 0.8 < circularity < 1.2: 
     contours_cirles.append(con) 

Tuy nhiên, danh sách mới 'contours_cirles' trống. Tôi in 'giấy cáo bạch' trong vòng lặp và các giá trị đều từ 10 đến 000 và 100 000.

CẬP NHẬT # 2: Sau khi sửa ngoặc thiếu nó đang làm việc bây giờ!

contours_cirles = [] 

# check if contour is of circular shape 
for con in contours_area: 
    perimeter = cv2.arcLength(con, True) 
    area = cv2.contourArea(con) 
    if perimeter == 0: 
     break 
    circularity = 4*math.pi*(area/(perimeter*perimeter)) 
    print circularity 
    if 0.7 < circularity < 1.2: 
     contours_cirles.append(con) 

Cảm ơn rất nhiều bạn! :)

example_done

+0

Mã rất cũ. Nhưng bạn có thể kiểm tra điều này. https://github.com/bipul21/Colored-Ball-Tracking –

+0

'(diện tích/chu vi * chu vi)' điều này có vẻ lạ với tôi. Bạn có chắc chắn, bạn đã không quên bất kỳ dấu ngoặc? – Moritz

+0

vâng, bạn nói đúng. circularity = 4 * math.pi * (diện tích/(chu vi * chu vi)) – cmplx96

Trả lời

4

Như một điểm khởi đầu bạn có thể bắt đầu với:

  • Tìm tất cả các đường nét trong hình ảnh được sử dụng cv2.findContours()
  • lặp qua mỗi đường viền:
    • tính diện tích, nếu diện tích đường bao nằm trong phạm vi cho trước là 70 < area < 150. Điều này sẽ lọc ra một số đường viền lớn nhỏ hơn và .
    • Sau khi lọc đường bao với ngưỡng khu vực, bạn cần kiểm tra số cạnh của đường bao, có thể thực hiện bằng cách sử dụng: cv2.approxPolyDP(), cho vòng tròn len (xấp xỉ) phải> 8 nhưng < 23. Hoặc bạn có thể áp dụng một số hoạt động phức tạp hơn để phát hiện vòng kết nối tại đây.

Bạn nên cố gắng thực hiện phương pháp này và cập nhật các câu hỏi với các mã mà bạn sẽ viết từ nay về sau.

EDIT: Theo đề nghị của @Miki, có một cách tốt hơn và sạch hơn để phát hiện nếu một hình dạng hình học là các hình tròn bằng tuần hoàn = 4pi (diện tích/chu vi^2), và quyết định một ngưỡng chẳng hạn như 0.9, để kiểm tra xem hình dạng có tròn không. Đối với vòng tròn hoàn hảo circularity == 1. Bạn có thể tinh chỉnh ngưỡng này theo nhu cầu của bạn.

Bạn có thể tham khảo arcLength để tìm chu vi đường bao và contourArea để nhận diện tích đường bao được yêu cầu tính vòng tròn.

+4

Tôi muốn sử dụng _circularity_ để đo bao nhiêu hình dạng là hình tròn: "Thông tư được định nghĩa là: Một số đo gần vòng tròn hình dạng như thế nào. Ví dụ: hình lục giác thông thường có hình tròn cao hơn hình vuông. (\ frac {4 * \ pi * Diện tích} {chu vi * chu vi}). Điều này có nghĩa là một vòng tròn có hình tròn là 1, hình tròn của hình vuông là 0.785, vân vân. " – Miki

+1

Cảm ơn rất nhiều @Miki – ZdaR

1

Chúng ta có thể thử Hough Transformation quá để phát hiện các vòng tròn trong hình ảnh và chơi với các ngưỡng để có được kết quả mong muốn (vòng tròn được phát hiện trong đường ranh giới xanh với những chấm đỏ như các trung tâm):

import cv2 
import numpy as np 

img = cv2.imread('rbv2g.jpg',0) 
img = cv2.medianBlur(img,5) 
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) 

circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,10, 
          param1=50,param2=12,minRadius=0,maxRadius=20) 

circles = np.uint16(np.around(circles)) 
for i in circles[0,:]: 
    # draw the outer circle 
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2) 
    # draw the center of the circle 
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) 

cv2.imshow('detected circles',cimg) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

enter image description here

Các vấn đề liên quan