Image processing 如何获取边的单线/曲线?

Image processing 如何获取边的单线/曲线?,image-processing,scipy,convolution,edge-detection,Image Processing,Scipy,Convolution,Edge Detection,这是我第一次体验图像处理。在jupiter笔记本中,我尝试使用scipy将灰度线艺术图像转换为SVG矢量表示。到目前为止,我能够将灰度图像转换为二值图像(单色图像),并在x轴和y轴上使用sobel滤波器来获得图形的边缘。我得到了两条线作为边,以说明线的两侧(如下图所示,以及我使用的代码) 我想把这两条线换成一条。然后检测图形中的直线和曲线,并将其转换为svg直线和贝塞尔曲线。在网上搜索时,我有点不知所措,对正确的前进方向感到困惑。如果我能得到一些关于如何从这里开始的建议,那将是非常有帮助的。如果

这是我第一次体验图像处理。在jupiter笔记本中,我尝试使用scipy将灰度线艺术图像转换为SVG矢量表示。到目前为止,我能够将灰度图像转换为二值图像(单色图像),并在x轴和y轴上使用sobel滤波器来获得图形的边缘。我得到了两条线作为边,以说明线的两侧(如下图所示,以及我使用的代码)

我想把这两条线换成一条。然后检测图形中的直线和曲线,并将其转换为svg直线和贝塞尔曲线。在网上搜索时,我有点不知所措,对正确的前进方向感到困惑。如果我能得到一些关于如何从这里开始的建议,那将是非常有帮助的。如果可能的话,我只想在scipy中这样做,而不是使用opencv

与其简单地使用现有的scipy函数和算法,我还想了解底层理论,以便能够有效地使用它们。因此,请分享任何有用的理论资源

提前谢谢

%matplotlib内联
将numpy作为np导入
从scipy导入ndimage作为nd
将matplotlib.pyplot作为plt导入
从撇渣进口io
def应用梯度阈值(d,thres):
d2=np.副本(d)
d2[d2==-thres]=thres
d2[d2!=thres]=0
返回d2
def plot_图像(IMG、名称):
图,轴列表=plt.子图(1,len(imgs),figsize=(20,20))
对于名称,zip中的轴(名称、轴列表):
轴。设置标题(名称)
对于img,轴在zip中(img,轴列表):
axes.imshow(img,cmap='Greys\u r')
plt.show()
img_文件=
img=plt.imread(img\u文件)
gray\u img=io.imread(img\u文件,as\u gray=True)
如果(np.max(gray_img)>1):
gray_img=gray_img/255#规格化
阈值=0.2
二进制=(灰度>阈值)*1#将灰度图像转换为二进制(单色)
im=binary.astype('int32')
dx=nd.sobel(im,1)
dy=nd.sobel(im,0)
dx=应用梯度阈值(dx,4)
dy=应用梯度阈值(dy,4)
mag=np.hypot(dx,dy)#sqrt(dx^2+dy^2)
磁力*=255.0/np.最大(磁力)
绘图图像([binary,mag],'binary-'+str(阈值),'Sobel Filter Result']))

您的图像实际上已经由边缘构成。使用细化,而不是边缘过滤器。

您的图像实际上已经由边缘组成。使用细化,而不是边缘过滤器。

这可能会引起您的兴趣@谢谢你的建议。我已经尝试过它和类似的工具autotrace。Potrace还为边生成双线,而autotrace生成中心线,但它是用C语言编写的。在玩了一段时间之后,我尝试使用标准的scipy/scikit图像函数在python中实现这一点。主要用于学习,也可根据我的需要进行优化/定制。与其使用Sobel,不如将二值图像反转,它会将双线固定为边缘。您可以查看我在这里使用的
中轴线()
。。。这可能会让你感兴趣@谢谢你的建议。我已经尝试过它和类似的工具autotrace。Potrace还为边生成双线,而autotrace生成中心线,但它是用C语言编写的。在玩了一段时间之后,我尝试使用标准的scipy/scikit图像函数在python中实现这一点。主要用于学习,也可根据我的需要进行优化/定制。与其使用Sobel,不如将二值图像反转,它会将双线固定为边缘。您可以查看我在这里使用的
中轴线()
。。。
%matplotlib inline

import numpy as np
from scipy import ndimage as nd
import matplotlib.pyplot as plt
from skimage import io

def apply_gradient_threshold(d,thres):
    d2 = np.copy(d)
    d2[d2 == -thres] = thres
    d2[d2 != thres] = 0
    return d2


def plot_images(imgs, names):
    fig, axes_list =  plt.subplots(1, len(imgs), figsize=(20, 20))
    for name,axes in zip(names, axes_list):
        axes.set_title(name)

    for img, axes in zip(imgs, axes_list):
        axes.imshow(img, cmap='Greys_r')

    plt.show()  

img_file = <file_url>

img = plt.imread(img_file)
gray_img = io.imread(img_file, as_gray=True) 

if(np.max(gray_img) > 1) :
    gray_img = gray_img/255 #normalize

threshold = 0.2
binary = (gray_img > threshold)*1  # convert the grayscale image to binary (monochrome)

im = binary.astype('int32')
dx = nd.sobel(im,1)
dy = nd.sobel(im,0)
dx = apply_gradient_threshold(dx, 4)
dy = apply_gradient_threshold(dy, 4)
mag = np.hypot(dx,dy) #sqrt(dx^2 + dy^2)
mag *= 255.0/np.max(mag)

plot_images([binary, mag ], ['Binary - ' + str(threshold), 'Sobel Filter Result'])