我有许多黑白图像,并希望将它们转换为一组线,这样我就可以从这些线完全或至少接近完全重建原始图像。换句话说,我正在尝试将图像矢量化为一组线。

我已经看过HoughLinesTransform,但是它并没有覆盖图像的每个部分,而是更多关于在图像中查找线条,而不是将图像完全转换为线条表示。另外,线变换不对线的实际宽度进行编码,这让我猜测如何重建图像(我需要这样做,因为这是训练机器学习算法的前一步)。

到目前为止,我已经使用houghLineTransform尝试了以下代码:

importnumpyasnpimportcv2MetersPerPixel=0.1defloadImageGray(path):img=(cv2.imread(path,0))returnimgdefLineTransform(img):edges=cv2.Canny(img,50,150,apertureSize=3)minLineLength=10maxLineGap=20lines=cv2.HoughLines(edges,1,np.pi/180,100,minLineLength,maxLineGap)returnlines;defsaveLines(liness):img=np.zeros((2000,2000,3),np.uint8)forlinesinliness:forx1,y1,x2,y2inlines:print(x1,y1,x2,y2)img=cv2.line(img,(x1,y1),(x2,y2),(0,255,0),3)cv2.imwrite('houghlines5.jpg',img)defmain():img=loadImageGray("loadtest.png")lines=LineTransform(img)saveLines(lines)main()

但是,当使用以下方法进行测试时

我得到了这张图片:

如您所见,它丢失了未与轴对齐的线,并且如果您仔细观察,即使检测到的线也被分割为2条线,并且它们之间有一定间隔。我还必须以预设的宽度绘制这些图像,而实际宽度未知。

编辑:根据@MarkSetchell的建议,我通过使用以下代码尝试了pypotrace,目前它在很大程度上忽略了贝塞尔曲线,只是试图像它们是直线一样工作,稍后我将重点讨论该问题,但是现在结果不是' t最优:

defTraceLines(img):bmp=potrace.Bitmap(bitmap(img))path=bmp.trace()lines=[]i=0forcurveinpath:forsegmentincurve:print(repr(segment))ifsegment.is_corner:c_x,c_y=segment.c

c2_x,c2_y=segment.end_point

lines.append([[int(c_x),int(c_y),int(c2_x),int(c2_y)]])else:c_x,c_y=segment.c1

c2_x,c2_y=segment.end_point

i=i+1returnlines

这会产生这种图像,这是一种改进,但是,虽然可以在以后解决圆的问题,但正方形的缺失部分和其他直线上的怪异伪像更成问题。有人知道如何解决它们吗?关于如何获得线宽的任何提示?

有人对如何更好地解决此问题有任何建议吗?

编辑编辑:这是另一张测试图像:,它包含多个我要捕获的线宽。

解决方案

OpenCV的

使用OpenCVfindContours,drawContours可以首先对线条进行矢量化处理,然后精确地重新创建原始图像:

importnumpyasnpimportcv2

img=cv2.imread('loadtest.png',0)result_fill=np.ones(img.shape,np.uint8)*255result_borders=np.zeros(img.shape,np.uint8)# the '[:-1]' is used to skip the contour at the outer border of the imagecontours=cv2.findContours(img,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[0][:-1]# fill spaces between contours by setting thickness to -1cv2.drawContours(result_fill,contours,-1,0,-1)cv2.drawContours(result_borders,contours,-1,255,1)# xor the filled result and the borders to recreate the original imageresult=result_fill^result_borders# prints True: the result is now exactly the same as the originalprint(np.array_equal(result,img))cv2.imwrite('contours.png',result)

结果

Scikit图片

使用scikit-image的,find_contours并approximate_polygon允许您通过逼近多边形来减少行数(基于此示例):

importnumpyasnpfromskimage.measureimportapproximate_polygon,find_contoursimportcv2

img=cv2.imread('loadtest.png',0)contours=find_contours(img,0)result_contour=np.zeros(img.shape+(3,),np.uint8)result_polygon1=np.zeros(img.shape+(3,),np.uint8)result_polygon2=np.zeros(img.shape+(3,),np.uint8)forcontourincontours:print('Contour shape:',contour.shape)# reduce the number of lines by approximating polygonspolygon1=approximate_polygon(contour,tolerance=2.5)print('Polygon 1 shape:',polygon1.shape)# increase tolerance to further reduce number of linespolygon2=approximate_polygon(contour,tolerance=15)print('Polygon 2 shape:',polygon2.shape)contour=contour.astype(np.int).tolist()polygon1=polygon1.astype(np.int).tolist()polygon2=polygon2.astype(np.int).tolist()# draw contour linesforidx,coordsinenumerate(contour[:-1]):y1,x1,y2,x2=coords+contour[idx+1]result_contour=cv2.line(result_contour,(x1,y1),(x2,y2),(0,255,0),1)# draw polygon 1 linesforidx,coordsinenumerate(polygon1[:-1]):y1,x1,y2,x2=coords+polygon1[idx+1]result_polygon1=cv2.line(result_polygon1,(x1,y1),(x2,y2),(0,255,0),1)# draw polygon 2 linesforidx,coordsinenumerate(polygon2[:-1]):y1,x1,y2,x2=coords+polygon2[idx+1]result_polygon2=cv2.line(result_polygon2,(x1,y1),(x2,y2),(0,255,0),1)cv2.imwrite('contour_lines.png',result_contour)cv2.imwrite('polygon1_lines.png',result_polygon1)cv2.imwrite('polygon2_lines.png',result_polygon2)

结果

Python输出:

Contourshape:(849,2)Polygon1shape:(28,2)Polygon2shape:(9,2)Contourshape:(825,2)Polygon1shape:(31,2)Polygon2shape:(9,2)Contourshape:(1457,2)Polygon1shape:(9,2)Polygon2shape:(8,2)Contourshape:(879,2)Polygon1shape:(5,2)Polygon2shape:(5,2)Contourshape:(973,2)Polygon1shape:(5,2)Polygon2shape:(5,2)Contourshape:(224,2)Polygon1shape:(4,2)Polygon2shape:(4,2)Contourshape:(825,2)Polygon1shape:(13,2)Polygon2shape:(13,2)Contourshape:(781,2)Polygon1shape:(13,2)Polygon2shape:(13,2)

outline_lines.png:

多边形1_lines.png:

多边形2_lines.png:

The length of the lines can then be calculated by applying Pythagoras' theorem to the coordinates: line_length = math.sqrt(abs(x2 - x1)**2 + abs(y2 - y1)**2). If you want to get the width of the lines as numerical values, take a look at the answers of "How to determine the width of the lines?" for some suggested approaches.

python画黑白线条_将黑白图像完全转换为一组线(也称为仅使用线进行矢量化)...相关推荐

  1. python——画蛇形线条

    用python画蛇形线条 代码: turtle.setup(650, 350, 200, 200) turtle.penup() turtle.fd(-250) turtle.pendown() tu ...

  2. python画交互式地图_使用Python构建交互式地图-入门指南

    python画交互式地图 Welcome to The Beginner's Guide to Building Interactive Maps in Python 欢迎使用Python构建交互式地 ...

  3. 用python画机器猫代码_如何用Python画一只机器猫?| 原力计划

    原标题:如何用Python画一只机器猫?| 原力计划 作者 | 人邮异步社区 责编 | 胡巍巍 出品 | CSDN博客 自信心是成功的源泉,对刚入门编程行业的初级程序员来说,多敲代码多做项目就是构建自 ...

  4. 怎么用python画皮卡丘_实现童年宝可梦,教你用Python画一只属于自己的皮卡丘

    原标题:实现童年宝可梦,教你用Python画一只属于自己的皮卡丘 大数据文摘出品 作者:李雷.蒋宝尚 还记得小时候疯狂收集和交换神奇宝贝卡片的经历吗? 还记得和小伙伴拿着精灵球,一起召唤小精灵的中二模 ...

  5. 用python画动态樱花_利用python画一棵漂亮的樱花树,turtle画图代码大全,此处感谢知乎大佬小白...

    利用python画一棵漂亮的樱花树,turtle画图代码大全,此处感谢知乎大佬小白 此处感谢知乎大佬 小白练手 练习一下比较流行的turtle(海龟库) 画一棵漂亮的樱花树,效果如下: ps: 是动态 ...

  6. python画爱心原理_程序员式优雅表白,教你用python代码画爱心

    还能用python代码画爱心?还有这种操作?这是什么原理? 不相信python代码可以画爱心?先来一张效果图来看看效果吧!PyCharm pro Mac-PyCharm pro for Mac( Py ...

  7. python画猪头_使用Python画小猪佩奇 社会人标配

    看了一些用python实现小猪佩奇画画的帖子,向自己实现下,以此记录. 社会人的标配是谁,当然是吹风机小猪佩奇身上纹. 我自己尝试画过小猪配齐但是感觉眼睛特别难画,画出来的猪头没有立体感,眼睛画不好整 ...

  8. 如何用python画爱心型线_如何用python画爱心

    用python绘制爱心的基本步骤如下: 首先先下载安装好python程序. 在我们自己的电脑上找到python 的IDLE工具. 2.然后打开IDLE,新建一个文件,命名为test1.py. 3.接着 ...

  9. python画地图经纬度_如何用python画地图上的标注线?

    我们平时看文章的时候会遇到一些不太好理解的地方,如果上面有标注那就事半功倍了.当然在地图中也是如此.之前我们学会了很多画图的技巧,但是忽略了标注这种细节的重要作用.小编经过一番学习和整理,清楚了这部分 ...

最新文章

  1. Windows Workflow Beta2 HOL学习笔记(三):使用IfElse Activity,声明条件和自定义活动...
  2. IDEA创建springboot项目:Unable to import maven project: See logs for details
  3. 微信公众号 Spring Cloud 相关文章链接备份(纯技术)
  4. android 粒子动画火焰,canvas粒子火焰跟随动画特效
  5. mysql 正则 捕获_在mysql中模拟正则表达式捕获组
  6. CarMaker快速入门
  7. ANSYS18.2/HFSS18.2安装步骤
  8. 微信小程序订阅消息,并跳转指定页面
  9. 子网掩码掩码计算器_Javascript加载掩码
  10. 北京“宇宙中心”二手房挂单6天11次看房破记录
  11. 操作系统——内存交换技术
  12. nginx 配置 apple-app-site-association
  13. centos 设置mtu_Linux上合理设置网卡的MTU值
  14. 从数学上推导伴随矩阵特征值
  15. 【JavaScript】JavaScript模拟实现面向对象一张图帮助你深刻理解原型链和原型对象
  16. UITableViewCell中嵌套UITableView,用UITextView加载HTML数据
  17. 通信工程考研英语复试专有名词翻译
  18. CCR自动炒币机器人到底有多神奇,让无数炒币人疯狂追捧
  19. 基于Ernie-3.0 CAIL2019法研杯要素识别多标签分类任务
  20. 十进制浮点数的表示方法

热门文章

  1. DRM驱动代码分析:开机过程中显示驱动做了什么
  2. Error:(4, 35) java: 程序包org.springframework.context不存在
  3. SpringBoot和日志框架:缘由,日志框架的选择,使用,自定义配置,日志框架切换
  4. 倒金字塔java语言_java打印正金字塔,倒金字塔和“水影”金字塔(示例代码)
  5. swagger实现example效果
  6. Mysql深度讲解 – 子查询优化
  7. 关于Linux系统诞生发展历程、组成、特点、核心、发行版本
  8. WordPress eXtended Rss (WXR)文件格式解析
  9. 转:领导力与你想象的并不一样
  10. tomcat自动部署脚本