如何通过特定数量的像素来扩展轮廓(不迭代每个像素)?

2024-09-29 18:41:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个Python脚本,将图像转换为CNC机器的G代码。数控机床使用直径为0.250英寸的圆柱形钻头。我的脚本在图像中找到轮廓,然后将轮廓的坐标转换为机器的方向。你知道吗

这是伟大的作品,除了形状是雕刻是0.125“小于设计的一部分。钻头的中心直接在轮廓上,因此产生的形状太小,只有钻头直径的一半。你知道吗

我想将每个轮廓扩展x像素。我想制作一个输出图像,其中源图像中的每个白色像素在输出图像中也是白色的,但是输入图像中白色像素x像素内的每个像素在输出图像中应该是白色的。你知道吗

这是我的源图像:

source image

使用cv2.dilate()来扩展轮廓不会产生我想要的结果,因为它会使圆边变成正方形。你知道吗

img = cv2.dilate(img, (15,15), 5)

dilated using cv2.dilate

我试着逐像素地遍历图像,然后使用cv2.pointPolygontest(contour, (x,y), True)测试到轮廓的距离。这是可行的,但这是非常缓慢的黑客。你知道吗

import cv2
import numpy as np

def erode_contours_by_cutter_size(img, contours, cutter_size):
    # Create an output image
    outputImage = np.zeros_like(img)
    # Iterate through every pixel in the image
    for x in range(img.shape[0]):
        for y in range(img.shape[1]):
            # Check if the pixel is black
            if img[y,x] != 255:
                # Check if the distance from this pixel to a contour is smaller than the cutter size
                for contour in contours:
                    dist = cv2.pointPolygonTest(contour, (x,y), True)                    
                    if abs(dist) < cutter_size:
                        outputImage[y,x] = 255
    return outputImage

img = 255-cv2.imread('/home/stephen/Desktop/t2.png',0)
img = cv2.resize(img, (234,234))
cutter_size = 50
contours, _ = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img = erode_contours_by_cutter_size(img, contours, cutter_size)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

这是输出图像:

output image from slow dilation method


Tags: thein图像imgsizeif像素cv2
1条回答
网友
1楼 · 发布于 2024-09-29 18:41:22

这可能不是最干净的解决方案,但它很简单,适用于所有形状。有一点额外的工作,你可以用它在模板内的剪切以及。所以它可能足够满足你的需要。你知道吗

找到轮廓,在上面画一条2倍于钻头大小的白线。现在使用输入图像的反转版本作为遮罩,只留下路由路径-就像在输出图像中一样。相反,你也可以把这些图像组合起来,形成一个更大的白色形状(如你的问题所述)。你知道吗

结果:

enter image description here

代码:

import cv2
import numpy as np

bitsize = 100
# load image
img = cv2.imread('PluT1.png',0)
# create empty image
res = np.zeros(img.shape[:2], dtype=np.uint8)
# find countours. use a more complex CHAIN_APPROX if SIMPLE is not enough 
contours, hier = cv2.findContours(img,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# draw contour
for cnt in contours:
    cv2.drawContours(res,[cnt],0,(255),bitsize)

#invert input image to create mask
img_inverted = cv2.bitwise_not(img)
# apply mask to get routing path
path = cv2.bitwise_and(res,res, mask=img_inverted)
# join drawn contour and input image to get solid
solid = cv2.bitwise_or(img,res)
# show images
cv2.imshow('Input',img)
cv2.imshow('Path',path)
cv2.imshow('Solid',solid)
cv2.waitKey(0)
cv2.destroyAllWindows()

相关问题 更多 >

    热门问题