Tôi đang cố gắng phát hiện số lượng đường ống trong bức tranh này. Đối với điều này, tôi đang sử dụng OpenCV và phát hiện dựa trên Python. Dựa trên các câu trả lời hiện có cho các câu hỏi tương tự, tôi đã có thể đưa ra các bước sau
- Mở hình ảnh
- Lọc nó
- Áp dụng phát hiện cạnh
- Sử dụng đường viền
- Kiểm tra số lượng
Tổng số đường ống là ~ 909 khi chúng ta đếm bằng tay cho hoặc lấy 4.
Sau khi áp dụng bộ lọc
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('images/input-rectpipe-1.jpg')
blur_hor = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((11,1,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
blur_vert = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((1,11,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
mask = ((img[:,:,0]>blur_hor*1.2) | (img[:,:,0]>blur_vert*1.2)).astype(np.uint8)*255
Tôi nhận được hình ảnh đeo mặt nạ này
Điều này có vẻ khá chính xác về số lượng hình chữ nhật có thể nhìn thấy mà nó hiển thị. Tuy nhiên, khi tôi cố gắng đếm và vẽ ô giới hạn ở trên cùng của hình ảnh, nó cũng chọn rất nhiều vùng không mong muốn. Đối với các vòng tròn, HoughCircles có cách xác định bán kính tối đa và tối thiểu. Có một cái gì đó tương tự cho hình chữ nhật có thể cải thiện độ chính xác. Ngoài ra, tôi sẵn sàng đề xuất các phương pháp tiếp cận thay thế cho vấn đề này.
ret,thresh = cv2.threshold(mask,127,255,0)
contours,hierarchy = cv2.findContours(thresh, 1, 2)
count = 0
for i in range(len(contours)):
count = count+1
x,y,w,h = cv2.boundingRect(contours[i])
rect = cv2.minAreaRect(contours[i])
area = cv2.contourArea(contours[i])
box = cv2.boxPoints(rect)
ratio = w/h
M = cv2.moments(contours[i])
if M["m00"] == 0.0:
cX = int(M["m10"] / 1 )
cY = int(M["m01"] / 1 )
if M["m00"] != 0.0:
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
if (area > 50 and area < 220 and hierarchy[0][i][2] < 0 and (ratio > .5 and ratio < 2)):
#cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
cv2.circle(img, (cX, cY), 1, (255, 255, 255), -1)
count = count + 1
print(count)
cv2.imshow("m",mask)
cv2.imshow("f",img)
cv2.waitKey(0)
CẬP NHẬT Dựa trên câu trả lời thứ hai, tôi đã chuyển đổi mã c ++ thành mã python và có kết quả gần hơn nhưng vẫn bỏ lỡ một vài hình chữ nhật rõ ràng.