如何从图像中提取平滑的骨架

我有一些固定大小的字体字符图像,如输入图像示例下所示。我想提取字符骨架(单像素宽)。我尝试了如下所示的各种方法,但输出都不同且不流畅。我认为一像素宽的骨架会很平滑(像素不会破裂,也没有噪点像素)。有一个更好的方法吗?如果没有,这三个中哪个最好?

输入图像样本

http://img3.mukewang.com/61d5021e0001514700560060.jpg

1) 例子


from skimage import img_as_bool, io, color, morphology

import matplotlib.pyplot as plt


image = img_as_bool(color.rgb2gray(io.imread('image.jpeg')))

out = morphology.medial_axis(image)


f, (ax0, ax1) = plt.subplots(1, 2)

ax0.imshow(image, cmap='gray', interpolation='nearest')

ax1.imshow(out, cmap='gray', interpolation='nearest')

plt.show()

输出 1

http://img4.mukewang.com/61d5022e000147ce03660186.jpg

2) 例子


from PIL import Image, ImageDraw, ImageFont

import mahotas as mh

import numpy as np


image = Image.new("RGBA", (600,150), (255,255,255))

draw = ImageDraw.Draw(image)

fontsize = 150

font = ImageFont.truetype("font.TTF", fontsize)

txt = '가'

draw.text((30, 5), txt, (0,0,0), font=font)

img = image.resize((188,45), Image.ANTIALIAS)

print(type(img))

plt.imshow(img)


img = np.array(img)

im = img[:,0:50,0]

im = im < 128

skel = mh.thin(im)

noholes = mh.morph.close_holes(skel)

plt.subplot(311)

plt.imshow(im)

plt.subplot(312)

plt.imshow(skel)

输出 2

http://img.mukewang.com/61d5023b000109bc01460179.jpg

3) 例子


from skimage.morphology import skeletonize

from skimage import draw

from skimage.io import imread, imshow

from skimage.color import rgb2gray

import os


# load image from file

img_fname='D:\Ammar Data\Debbie_laptop_data\Ammar\sslab-deeplearning\GAN models\sslab_GAN\skeleton\hangul_1.jpeg' 

image=imread(img_fname)


# Change RGB color to gray 

image=rgb2gray(image)


# Change gray image to binary

image=np.where(image>np.mean(image),1.0,0.0)


# perform skeletonization

skeleton = skeletonize(image)


plt.imshow(skeleton)

输出3

http://img.mukewang.com/61d502470001540c03200251.jpg

慕斯王
浏览 222回答 1
1回答

一只萌萌小番薯

您的代码很好,但您可能需要更改将图像转换为二进制的方式。此外,为了避免看起来嘈杂的输出,您可以应用binary_closing到您的骨架图像。看看下面的代码——import matplotlib.pyplot as pltfrom skimage import img_as_boolfrom skimage.io import imreadfrom skimage.color import rgb2grayfrom skimage.morphology import skeletonize, binary_closingim = img_as_bool(rgb2gray(imread('0jQjL.jpg')))out = binary_closing(skeletonize(im))f, (ax0, ax1) = plt.subplots(1, 2)ax0.imshow(im, cmap='gray', interpolation='nearest')ax1.imshow(out, cmap='gray', interpolation='nearest')plt.show()您的两个示例图像给了我以下输出 -编辑:为避免将图像转换为 bool 时的精度损失,您还可以使用可用的阈值算法之一对图像进行二值化。我更喜欢大津的。import matplotlib.pyplot as pltfrom skimage.io import imreadfrom skimage.filters import threshold_otsufrom skimage.color import rgb2grayfrom skimage.morphology import skeletonize, binary_closingdef get_binary(img):&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; thresh = threshold_otsu(img)&nbsp; &nbsp; binary = img > thresh&nbsp; &nbsp; return binaryim = get_binary(rgb2gray(imread('Snip20190410_9.png')))out = binary_closing(skeletonize(im))f, (ax0, ax1) = plt.subplots(1, 2)ax0.imshow(im, cmap='gray', interpolation='nearest')ax1.imshow(out, cmap='gray', interpolation='nearest')plt.show()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python