【发布时间】:2020-03-17 18:25:33
【问题描述】:
我正在编写一个 Python 脚本,用于将图像转换为 CNC 机器的 G 代码。 CNC 机床使用直径为 0.250 英寸的圆柱形钻头。我的脚本在图像中找到轮廓,然后将轮廓中的坐标转换为机器的方向。
这很好用,除了雕刻的形状比设计的部分小 0.125 英寸。钻头的中心直接在轮廓上,因此生成的形状太小了钻头直径的一半。
我想将每个轮廓放大 x 个像素。我想制作一个输出图像,其中源图像中的每个白色像素在输出中也是白色的图像,而且输入图像中白色像素的 x 个像素内的每个像素在输出图像中都应该是白色的。
这是我的源图片:
使用cv2.dilate() 扩张轮廓不会产生我正在寻找的结果,因为它往往会使圆边变成正方形。
img = cv2.dilate(img, (15,15), 5)
我尝试逐个像素地遍历图像,然后使用cv2.pointPolygontest(contour, (x,y), True) 测试到轮廓的距离。这行得通,但这个 hack 很慢。
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()
这是输出图像:
【问题讨论】:
-
尝试 distanceTransform 和阈值
-
在这里支持nathancy的想法,试试吧!但是,还有另一个问题:您使用哪个 OpenCV 版本,
img = cv2.dilate(img, 15, 5)有效?第二个参数是默认的膨胀核(结构元素)。我检查了 OpenCV 4.x、3.4.x 和 2.4.x 上的文档,但似乎没有一个允许该代码。 -
@HansHirse 我使用的是 OpenCV 版本 '4.1.1',抱歉那行代码有错误。我在编辑中修复了它。