0

我有一个类似于下图(左侧)的图像:

在此处输入图像描述

我只想提取右侧的红色像素:属于 1px 垂直线的像素,但提取任何较粗的线或具有超过 1 个相邻黑色像素的其他区域。图像是双色的。

到目前为止,我已经尝试了一个OPEN具有垂直(10px,这是为了我的目的)和水平内核的形态并采取了差异,但这需要一个尴尬的转变并留下一些“斑点”:


    vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 10))
    vertical_mask1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel,
                                      iterations=1)

    horz_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 1))
    horz_mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horz_kernel,
                                      iterations=1)

    M = np.float32([[1,0,-1],[0,1,1]])
    rows, cols = horz_mask.shape
    vertical_mask = cv2.warpAffine(horz_mask, M, (cols, rows))

    result = cv2.bitwise_and(thresh, cv2.bitwise_not(horz_mask))

隔离 1px 线(并且只有 1px 线)的正确方法是什么?

在一般情况下,对于其他内核,这个问题是:如何找到图像中位于内核“适合内部”的区域中的所有像素(然后减法以获得我想要的结果)?

4

1 回答 1

1

这基本上是(二进制)模板匹配。您需要从您的“内核”派生适当的模板。对于较大的“内核”,可能还需要为这些模板使用掩码,参见。cv2.matchTemplate.

单像素垂直线最重要的特征是什么?当前像素的左右邻居必须是0。所以,要匹配的模板是[0, 1, 0]. 通过使用,完美匹配将导致接近数组中的值。TemplateMatchMode cv2.TM_SQDIFF_NORMED0result

您可以屏蔽这些位置,并根据模板的大小进行扩展。然后,您使用bitwise_and提取属于您的模板的实际像素。

这是一些带有一些模板(“内核”)的代码:

import cv2
import numpy as np

img = cv2.imread('AapJk.png', cv2.IMREAD_GRAYSCALE)[:, :50]

vert_line = np.array([[0, 1, 0]], np.uint8)
cross = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]], np.uint8)
corner = np.array([[0, 0, 1], [0, 0, 1], [1, 1, 1]], np.uint8)

for i_k, k in enumerate([vert_line, cross, corner]):
    m, n = k.shape
    img_tmp = 1 - img // 255
    mask = cv2.matchTemplate(img_tmp, k, cv2.TM_SQDIFF_NORMED) < 10e-6
    mask = cv2.dilate(mask.astype(np.uint8), np.ones((m, n)), anchor=(n-1, m-1))
    m, n = mask.shape
    mask = cv2.bitwise_and(img_tmp[:m, :n], mask)
    out = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    roi = out[:m, :n]
    roi[mask.astype(bool), :] = [0, 0, 255]
    cv2.imwrite('{}.png'.format(i_k), out)

垂线:

垂线

叉:

叉

右下角3 x 3

右下角

较大的模板(“内核”)很可能需要额外的掩码,具体取决于应考虑多少或哪些相邻像素。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.19041-SP0
Python:        3.9.1
PyCharm:       2021.1.3
NumPy:         1.20.3
OpenCV:        4.5.2
----------------------------------------
于 2021-07-06T14:46:55.697 回答