`

python 简单图像处理(16) 图像的细化(骨架抽取)

 
阅读更多

 

参考:http://www.cnblogs.com/xianglan/archive/2011/01/01/1923779.html

 

图像的细化主要是针对二值图而言

所谓骨架,可以理解为图像的中轴,,一个长方形的骨架,是它的长方向上的中轴线,

圆的骨架是它的圆心,直线的骨架是它自身,孤立点的骨架也是自身。

骨架的获取主要有两种方法:

(1)基于烈火模拟

设想在同一时刻,将目标的边缘线都点燃,火的前沿以匀速向内部蔓延,当前沿相交时火焰熄灭,

火焰熄灭点的结合就是骨架。

(2)基于最大圆盘

目标的骨架是由目标内所有内切圆盘的圆心组成

我们来看看典型的图形的骨架(用粗线表示)

细化的算法有很多种,但比较常用的算法是查表法

细化是从原来的图中去掉一些点,但仍要保持原来的形状。

实际上是保持原图的骨架。

判断一个点是否能去掉是以8个相邻点(八连通)的情况来作为判据的,具体判据为:

1,内部点不能删除

2,鼓励点不能删除

3,直线端点不能删除

4,如果P是边界点,去掉P后,如果连通分量不增加,则P可删除


看看上面那些点。

第一个点不能去除,因为它是内部点

第二个点不能去除,它也是内部点

第三个点不能去除,删除后会使原来相连的部分断开

第四个点可以去除,这个点不是骨架

第五个点不可以去除,它是直线的端点

第六个点不可以去除,它是直线的端点

 

对于所有的这样的点,我们可以做出一张表,来判断这样的点能不能删除

我们对于黑色的像素点,对于它周围的8个点,我们赋予不同的价值,

若周围某黑色,我们认为其价值为0,为白色则取九宫格中对应的价值

对于前面那幅图中第一个点,也就是内部点,它周围的点都是黑色,所以他的总价值是0,对应于索引表的第一项

前面那幅图中第二点,它周围有三个白色点,它的总价值为1+4+32=37,对应于索引表中第三十八项

我们用这种方法,把所有点的情况映射到0~255的索引表中

 

我们扫描原图,对于黑色的像素点,根据周围八点的情况计算它的价值,然后查看索引表中对应项来决定是否要保留这一点

 

我们很容易写出程序

 

复制代码
import cv

def Thin(image,array):
h
= image.height
w
= image.width
iThin
= cv.CreateImage(cv.GetSize(image),8,1)
cv.Copy(image,iThin)
for i in range(h):
for j in range(w):
if image[i,j] == 0:
a
= [1]*9
for k in range(3):
for l in range(3):
if -1<(i-1+k)<h and -1<(j-1+l)<w and iThin[i-1+k,j-1+l]==0:
a[k
*3+l] = 0
sum
= a[0]*1+a[1]*2+a[2]*4+a[3]*8+a[5]*16+a[6]*32+a[7]*64+a[8]*128
iThin[i,j]
= array[sum]*255
return iThin

def Two(image):
w
= image.width
h
= image.height
size
= (w,h)
iTwo
= cv.CreateImage(size,8,1)
for i in range(h):
for j in range(w):
iTwo[i,j]
= 0 if image[i,j] < 200 else 255
return iTwo


array
= [0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
0,0,
1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,
1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
0,0,
1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,0,\
1,1,0,0,1,1,1,0,1,1,0,0,1,0,0,0]

image
= cv.LoadImage('pic3.jpg',0)
iTwo
= Two(image)
iThin
= Thin(iTwo,array)
cv.ShowImage(
'image',image)
cv.ShowImage(
'iTwo',iTwo)
cv.ShowImage(
'iThin',iThin)
cv.WaitKey(0)
复制代码

 

 

我们来看看运行效果:

(下图最左边的原图若涉及版权问题,请作者与我联系,谢谢)

 

效果差强人意,总觉得有点不对头,但又说不出哪里不对

好吧,我们来看看最简单的事例

按照前面的分析,我们应该得到一条竖着的线,但实际上我们得到了一条横线

我们在从上到下,从左到右扫描的时候,遇到第一个点,我们查表可以删除,遇到第二个点,我们查表也可以删除,整个第一行都可以删除

于是我们查看第二行时,和第一行一样,它也被整个删除了。这样一直到最后一行,于是我们得到最后的结果是一行直线

 

解决的办法是:

在每行水平扫描的过程中,先判断每一点的左右邻居,如果都是黑点,则该点不做处理。另外,如果某个黑店被删除了,则跳过它的右邻居,处理下一点。对矩形这样做完一遍,水平方向会减少两像素。

然后我们再改垂直方向扫描,方法一样。

这样做一次水平扫描和垂直扫描,原图会“瘦”一圈

多次重复上面的步骤,知道图形不在变化为止

 

这一改进让算法的复杂度的运行时间增大一个数量级

我们来看看改进后的算法:

 

复制代码
import cv

def VThin(image,array):
h
= image.height
w
= image.width
NEXT
= 1
for i in range(h):
for j in range(w):
if NEXT == 0:
NEXT
= 1
else:
M
= image[i,j-1]+image[i,j]+image[i,j+1] if 0<j<w-1 else 1
if image[i,j] == 0 and M != 0:
a
= [0]*9
for k in range(3):
for l in range(3):
if -1<(i-1+k)<h and -1<(j-1+l)<w and image[i-1+k,j-1+l]==255:
a[k
*3+l] = 1
sum
= a[0]*1+a[1]*2+a[2]*4+a[3]*8+a[5]*16+a[6]*32+a[7]*64+a[8]*128
image[i,j]
= array[sum]*255
if array[sum] == 1:
NEXT
= 0
return image

def HThin(image,array):
h
= image.height
w
= image.width
NEXT
= 1
for j in range(w):
for i in range(h):
if NEXT == 0:
NEXT
= 1
else:
M
= image[i-1,j]+image[i,j]+image[i+1,j] if 0<i<h-1 else 1
if image[i,j] == 0 and M != 0:
a
= [0]*9
for k in range(3):
for l in range(3):
if -1<(i-1+k)<h and -1<(j-1+l)<w and image[i-1+k,j-1+l]==255:
a[k
*3+l] = 1
sum
= a[0]*1+a[1]*2+a[2]*4+a[3]*8+a[5]*16+a[6]*32+a[7]*64+a[8]*128
image[i,j]
= array[sum]*255
if array[sum] == 1:
NEXT
= 0
return image

def Xihua(image,array,num=10):
iXihua
= cv.CreateImage(cv.GetSize(image),8,1)
cv.Copy(image,iXihua)
for i in range(num):
VThin(iXihua,array)
HThin(iXihua,array)
return iXihua

def Two(image):
w
= image.width
h
= image.height
size
= (w,h)
iTwo
= cv.CreateImage(size,8,1)
for i in range(h):
for j in range(w):
iTwo[i,j]
= 0 if image[i,j] < 200 else 255
return iTwo


array
= [0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
0,0,
1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,
1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
0,0,
1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,\
1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,0,\
1,1,0,0,1,1,1,0,1,1,0,0,1,0,0,0]

image
= cv.LoadImage('pic3.jpg',0)
iTwo
= Two(image)
iThin
= Xihua(iTwo,array)
cv.ShowImage(
'image',image)
cv.ShowImage(
'iTwo',iTwo)
cv.ShowImage(
'iThin',iThin)
cv.WaitKey(0)
复制代码

 

 

我们在调用函数的时候可以控制扫描的次数,而不是判断是否扫描完成

 

好啦,我们来看看运行效果吧。

 

效果确实比刚才好多了

 

我们来看看对复杂图形的效果

 

(上图中左图若有版权问题,请与我联系,谢谢)

 

好啦,图像的细化就讲到这里了

 

之后一段时间要准备考研,虽然并不认为自己还来得及复习,但总得做出点姿态

呵呵,可能之后两个星期不再更新

分享到:
评论

相关推荐

    python图像处理,python图像处理库,Python

    在Python编程语言中,图像处理是一项广泛应用于各种领域的重要技能,包括数据分析、视觉艺术、机器学习等。Python提供了丰富的库来支持图像处理任务,使得开发者能够轻松地进行图像的编辑、分析和转换。本篇文章将...

    Python图像处理.pdf

    Python 语言的面向对象、弱数据类型等特点使得它非常适合进行简单的图像处理任务。PythonWare 公司提供了免费的图像处理工具包 PIL(Python Image Library),该软件包提供了基本的图像处理功能,如改变图像大小、...

    python-图像处理入门.pdf

    本课程旨在引导学生熟悉Python编程,了解如何利用Python、NumPy和SciPy进行图像处理,并掌握matplotlib进行图像可视化的基本技巧。通过使用spyder IDE,学生将能更高效地完成课程中的练习,提高解决问题的能力。课程...

    python图像处理实验指导书1

    Python 图像处理实验指导书1 是一个基于 Python 的图像处理实验指导书,旨在帮助学生和开发者学习和掌握图像处理技术。该指导书共分为 11 个任务,涵盖了从图像处理基础到 ROS 机器人操作系统的应用。 任务一:...

    python图像处理_python图像处理_python图像_python图像处理_python文档_tuxiangchuli_

    在Python中进行图像处理是一项广泛且实用的任务,尤其在数据可视化、计算机视觉和人工智能领域。Python提供了多个强大的库,如PIL(Python Imaging Library)、OpenCV、Matplotlib以及scikit-image,它们支持丰富的...

    基于Python的图像处理技术在鱼类尺寸测量中的应用.pdf

    基于Python的图像处理技术在鱼类尺寸测量中的应用 本文介绍了一种基于Python的图像处理技术在鱼类尺寸测量中的应用。该技术通过使用OpenCV库函数对原始图像进行预处理,去除噪声干扰、增强鱼体特征等,接着使用...

    数字图像处理大作业-拍照图像处理(python+OpenCV+qt)

    在本项目中,我们主要探讨的是使用Python编程语言结合OpenCV和Qt库进行数字图像处理。这个大作业涵盖了多个图像处理的重要概念和技术,包括图片的文字添加、空间转换、旋转、缩放、翻转、投影矫正、二值化、图像校正...

    图像处理python

    在图像处理领域,Python语言因其丰富的库支持和易读性,成为了开发者们首选的工具之一。本项目"图像处理python"旨在提供一个完整的图像处理系统,涵盖了多种图像操作功能,如格式转换、尺寸调整、像素操作、角度旋转...

    Python图形图像处理实战集锦

    Python在图像处理和识别领域有着广泛的应用,OpenCV是一个强大的图像处理库,它提供了丰富的功能,包括图像的读取、显示、处理、分析等。在上述的实战文章中,涉及了多个关键知识点,我们将逐一进行深入探讨。 1. *...

    基于python图像处理实验.zip

    Python图像处理实验主要涉及到使用Python语言以及相关的图像处理库,如PIL(Python Imaging Library)或其现代化的分支,Pillow,以及OpenCV等。这些工具提供了丰富的功能,包括图像的读取、显示、保存、裁剪、旋转...

    用Python进行图像处理

    尽管MATLAB以其内置的图像处理工具箱而闻名,并且在复杂图像处理任务中表现卓越,但在处理相对简单的图像处理任务时,Python则展现出了更高的效率和灵活性。Python的这些优点主要体现在以下几个方面: - **简洁性**...

    总结python做图像处理毕业设计 (2).pdf

    Python在图像处理领域的应用广泛,尤其适合初学者和专业开发者进行毕业设计或项目开发。这份文档似乎是一个关于图形图像处理的课程设计指南,旨在帮助学生综合运用计算机图形学和数字图像处理的知识,通过编程实现一...

    Python在图像处理中的应用.pdf

    Python在图像处理领域的应用非常广泛,从简单的图像读取、显示到复杂的图像分析和处理都有成熟的解决方案。通过上述介绍可以看出,Python结合PIL、Matplotlib、Scipy等库,能够轻松实现各种图像处理任务。对于科研...

    图像处理的详细python程序实例

    在图像处理领域,Python语言因其丰富的库支持和易读性而被广泛使用。这个压缩包“image_tutorial”显然是一个图像处理的学习资源,包含了具体的Python程序实例,旨在帮助初学者和有经验的开发者深入理解图像处理技术...

    用Python来完成简单图像处理.doc

    使用 Python 完成简单图像处理 本文主要介绍了使用 Python 完成简单图像处理的方法和相关技术。图像处理是计算机视觉和图像处理领域的重要组成部分,而 Python 语言则是完成简单图像处理任务的理想选择。下面将对...

    python利用图像处理方法 实现多目标定位与裁剪(源代码)

    python利用图像处理方法 实现多目标定位与裁剪(源代码)

    总结python做图像处理毕业设计.docx

    在Python中进行图像处理是一项广泛应用于许多领域的技术,包括但不限于科学研究、医学成像、艺术创作、数据可视化和安全监控。本课程设计旨在帮助学生通过实际项目深入理解和掌握计算机图形学和数字图像处理的基础...

    数字图像处理实验(Python版本)--20221

    【数字图像处理实验(Python版本)--20221】是自动化工程学院的一个实验课程,专注于使用Python和OpenCV库进行数字图像处理。实验旨在让学生熟悉Python中的图像处理操作,包括读取、分析和存储图像,以及了解不同...

    图像处理大作业-基于python的图像编码-香农 霍夫曼 费诺

    在本项目中,我们将深入探讨图像处理领域的一个关键概念——基于Python的图像编码,特别是涉及到香农、霍夫曼和费诺编码的理论与实践。这些编码方法在数据压缩和图像传输中扮演着重要角色,因为它们能有效地减少数据...

Global site tag (gtag.js) - Google Analytics