加厚一个像素线

时间:2017-10-23 18:05:09

标签: python image numpy opencv

我正在使用OpenCV在Python上进行一些图像处理。我试图在一个图像上叠加轮廓,其中轮廓是从面具制作的。我正在使用cv2.Canny()来获取蒙版的轮廓,然后使用cv2.cvtColor()将其更改为颜色,然后使用outline[np.where((outline == [255,255,255]).all(axis=2))] = [180,105,255]将该边缘转换为青色。我现在的问题是这是一个像素粗线,在大图像上几乎看不到。除了我使用[0,0,0]作为蒙版应用于我的彩色图像的点之外,此轮廓均为cv2.bitwise_or(img, outline

我目前正在通过强制和检查位图中的每个像素来加粗这个轮廓,以检查它的任何邻居是否为[180,105,255],如果是,那么该像素也会改变。这很慢。有没有办法使用numpy或openCV自动执行此操作?我希望有一些条件索引与numpy,但找不到任何东西。

3 个答案:

答案 0 :(得分:2)

根据情况,有两种方法:


示例

使用此输入图像

enter image description here

import cv2
import numpy as np

# Create test image
mask = np.zeros((200,200,3), dtype=np.uint8)
cv2.line(mask, (50, 100), (150, 100), (255,255,255), 1)

方法1

前景中的所有像素(白色)的面积都将增加cv2.dilate()。我们创建一个structuring element并扩张。更多的迭代将生成更粗的线

iterations=1(左),iterations=2(中),iterations=3(右)

enter image description here enter image description here enter image description here

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
dilate = cv2.dilate(mask, kernel, iterations=1)

方法2

当我们只想增强图像的特定部分但不影响其他部分时,可以使用cv2.drawContours()。我们可以使用thickness参数指定颜色并调整大小。结果将类似于cv2.dilate(),并具有选色的优点

enter image description here

gray = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
cnts = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(mask, [c], -1, (255,255,255), thickness=15)

答案 1 :(得分:1)

我来看看形态运算。扩音听起来与您想要的最接近。如果您不想扩大图像的其余部分,则可能需要在行的子区域上进行操作。

答案 2 :(得分:0)

您需要执行dilation。膨胀是一种形态学运算,它会使输入图像中的较亮区域增大。如here所述,通过使用一些 kernel

对输入图像进行卷积来执行膨胀
  

当在图像上扫描内核B时,我们计算出最大值   像素值与B重叠,并替换锚点中的图像像素   点位置具有该最大值。

锚点通常是内核的中心。

在您的情况下,我建议使用您选择大小的椭圆形内核。如果使用1像素粗的线,并且 kernel 的大小为(n,n),则最终的膨胀图像中的线将大约2*n粗。

这是示例代码:

    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    result = cv2.dilate(outline, kernel)

以下是扩张的示例:

enter image description here