【问题标题】:Normalizing curved lines to form a rectangle using opencv使用opencv规范化曲线以形成矩形
【发布时间】:2019-12-20 19:09:24
【问题描述】:

我有一个水下摄像头,可以检测Image 1 中的 PVC 框架。我添加了随机在线水效果,以便在预期的恶劣条件下累积。

我尝试了两种方法:

  • Canny Edge 算法。

  • 多种颜色转换、平滑和阈值处理。

最有效的结果是后者的result

我的问题是我无法准备此结果以供进一步处理。

为了更容易处理,结果需要像this one一样为最右边的等宽线形。

我尝试概率霍夫线变换来检测任何线条,但它们都太弯曲而无法检测到。

【问题讨论】:

  • “归一化结果是所有形状都是具有恒定宽度的统一矩形”这不是一个有用的定义,因为任何图像都可以符合这个定义:图像是像素的集合和单个像素是一个矩形。
  • @Julien 我指的是图像中检测到的对象作为结果。
  • 我的评论仍然适用。任何检测到的形状,无论多么摆动,最终都由矩形像素组成。换句话说,您的问题定义不明确。您基本上需要确定“矩形”的“比例”或“粒度”。
  • @Julien 矩形像素的图像是常识。我唯一的问题是摆脱所有的摆动并拥有线形物体。但是,我将编辑问题以澄清更多。
  • @Julien 图片已添加以澄清这一点。

标签: python opencv image-processing


【解决方案1】:

要从图像中提取线条,您可以在阈值处理后过滤水平和垂直线条,并通过中心绘制具有恒定宽度的矩形,然后删除交叉点周围的小物体:

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

closure_result.png

horizo​​ntal_tubes.png

vertical_tubes.png

all_lines.png

result.png

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 2017-08-29
    相关资源
    最近更新 更多