我正在使用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,但找不到任何东西。
答案 0 :(得分:2)
根据情况,有两种方法:
cv2.dilate()
-增强所有白色像素cv2.drawContours()
-增强特定像素示例
使用此输入图像
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
(右)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
dilate = cv2.dilate(mask, kernel, iterations=1)
方法2
当我们只想增强图像的特定部分但不影响其他部分时,可以使用cv2.drawContours()
。我们可以使用thickness
参数指定颜色并调整大小。结果将类似于cv2.dilate()
,并具有选色的优点
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)
以下是扩张的示例: