我有一个水下摄像头,可以检测PVC框架,如图1所示。我添加了随机的在线水的效果,所以它会在预期的粗糙条件下积累。 我尝试了两种方法: 最有效的结果是后者的结果。 我的问题是我在准备进一步处理的结果时遇到了麻烦。 为了便于处理,结果需要与最右边的部分一样具有等宽的线形。 我尝试了概率霍夫线变换来检测任何线,但它们都太弯曲了,无法检测。 问题来源StackOverflow 地址:/questions/59384117/normalizing-curved-lines-to-form-a-rectangle-using-opencv
要从图像中提取直线,可以对阈值化后的横线和垂线进行过滤,在中心画出等宽的矩形,然后去除交叉点周围的小物体:
import cv2
import numpy as np
from skimage.io import imread
from skimage.morphology import remove_small_objects
rgb = imread('https://i.stack.imgur.com/QPz8W.jpg')
# convert to HSV for thresholding
hsv = cv2.cvtColor(rgb, cv2.COLOR_RGB2HSV)
# threshold hue channel for purple tubes, value channel for blue tubes
thresh_hue = cv2.threshold(hsv[..., 0], 127, 255, cv2.THRESH_BINARY)[1]
thresh_val = cv2.threshold(hsv[..., 2], 200, 255, cv2.THRESH_BINARY)[1]
# combine purple tubes with blue tubes
thresh = thresh_hue | thresh_val
cv2.imwrite('threshold_result.png', thresh)
# morphologically close the gaps between purple and blue tubes
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((5, 5), np.uint8))
cv2.imwrite('closing_result.png', thresh)
# morphological opening with horizontal and vertical kernels
h_kernel = np.zeros((11, 11), dtype=np.uint8)
h_kernel[5, :] = 1
v_kernel = np.zeros((11, 11), dtype=np.uint8)
v_kernel[:, 5] = 1
h_tubes = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, h_kernel, iterations=6)
v_tubes = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, v_kernel, iterations=7)
cv2.imwrite('horizontal_tubes.png', h_tubes)
cv2.imwrite('vertical_tubes.png', v_tubes)
# find contours and draw rectangles with constant widths through centers
h_contours = cv2.findContours(h_tubes, cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)[0]
h_lines = np.zeros(thresh.shape, np.uint8)
for cnt in h_contours:
x, y, w, h = cv2.boundingRect(cnt)
y += int(np.floor(h / 2) - 4)
cv2.rectangle(h_lines, (x, y), (x + w, y + 8), 255, -1)
v_contours = cv2.findContours(v_tubes, cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)[0]
v_lines = np.zeros(thresh.shape, np.uint8)
for cnt in v_contours:
x, y, w, h = cv2.boundingRect(cnt)
x += int(np.floor(w / 2) - 4)
cv2.rectangle(v_lines, (x, y), (x + 8, y + h), 255, -1)
# combine horizontal and vertical lines
all_lines = h_lines | v_lines
cv2.imwrite('all_lines.png', all_lines)
# remove small objects around the intersections
xor = np.bool8(h_lines ^ v_lines)
removed = xor ^ remove_small_objects(xor, 350)
result = all_lines & ~removed * 255
cv2.imwrite('result.png', result)
threshold_result.png
closing_result.png
horizontal_tubes.png
vertical_tubes.png
all_lines.png
result.png
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。