图像中搜索曲线轨迹的极简方法(python)

       这样一个问题的来源,是我在思考怎样把一张二次元的彩色图片转化为一张完美的黑白的纯线稿图时遇到并需要解决的难关,这个问题听起来似乎并没有那么难,可实际上却超出想象,由于本来就不会复杂的算法,所以只能把问题简化了想,争取让什么算法都不会的人也能轻松明白其中的原理,目前整个解决方案也只是停留在思路阶段,下面主要整理这几天的思路作为学习笔记,方便之后完善代码。

解决该问题初步的步骤如下:

1.将图片黑白化,二值化

2.修复二值化后的白色和黑色杂质,去除大块黑色

3.搜索出整个线稿的路径(难点)

4.将路径的点连接的线段变成顺滑曲线(难点)

5.将曲线加粗

 

各步骤详细分析:

1.对于这种动漫图片来说可用公式

gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
 

加权平均求出各点的灰度值(系数怎样确定暂且不讨论,我只是百度搬运工),然后使其R,G,B值都为此值

黑白化完毕。

然后规定一个阈值比如120,使大于此值的像素值变为255,小于此值变为0。

关于此阈值的选取方法,可多次改变阈值之后分析得到的图片,这里引入一个新概念叫连通分量,我们假设每个黑色像素都是一个结点,相邻的两个黑色像素之间有一条边连接,整张图片就可以就可以看成有许多连通分量的图,当我们取的阈值不合适时,就会导致连通分量特别大,原因见下图:

蓝圈处由于原图该处是渐变的颜色效果,就会导致出现黑白交错的块,零零碎碎的,所以我们只要改变阈值排除过大的连通分量即可。

二值化完毕。

2.修复小杂质我的思路是当那一块像素数量少于某个阈值时就整个抹去,对于大块黑暗,比如上图就有这样的大片黑暗,但是我们这次不能规定新的阈值使大于它的时候抹去这种大黑块了,因为这些黑块可能连着整个线稿,面临损失信息的风险,我的思路是,在图中找黑点,这些黑点满足条件:

以该点为圆心,R为半径做圆,该圆内所有点皆为黑色。

那我们就可以把这个圆内区域全都变成白色。其中R为图中的线稿线条宽度,这样,当黑块清理到边界时,就会留下黑色边界了(当然也有可能图象某些地方本来就有黑色的大块,这里也不讨论了),刚好是我们想要的效果。

 

3.这也是最棘手的问题,想了好几种方案,可能都不能完美解决这个问题,不过基本想法还是要有的,现在先简化问题,如图:

我们先来着手这个没有岔路没有分段且粗细均匀的“线稿”,如果能找出其轨迹,也算是一个大大的进步了。

针对上图的处理步骤:

1)以左上角为起点A,以曲线的宽度R为半径做一个圆(关于线稿的宽度,可以指定一个并不精确的值,也可以在图中先找一个线稿上的中心点然后看最大能做半径为多少的圆,使得圆内全为黑色,鉴于二值化得线稿并不一定粗细均匀,所以这样可能是徒劳)。

2)在圆边界上找一个点B,满足条件:A,B连线上所有点均为黑色。当然由于线是很粗的所以满足条件的点可能会有很多个,这时候只需要找出两个极端位置,求出倾斜角,求平均值作为最终B点即可(这只适用于没有分岔路的情况)。

3)以AB为直径做一个圆,把圆内的黑块全变成白块儿(主要是为了不走重复的路,所以走完就擦掉)

4)以B为新的起点,重复1,2步骤,不过要优先在AB延长线附近找满足条件的点,以此类推,直到没有满足条件的新的点诞生为止。

5)把这些按顺序存储到数组里,把相邻点之间生成一条直线,生成图片

完成。

对于岔路,我的想法是岔路之间是空的,应该是还可以分辨的,但是我不会多线程处理两条以上的路,所以只好把这个节点和方向先存到列表里,等一条路走完之后再回来走这条路。

对于多段断开的路,有必要在最开始就计算出整个图的连通分量,然后找到相应数量的起点,另外在探索之后也可以检测是否探索完了所有路,方法如下:

搜索全图,尝试找到满足如下条件的黑色点:

以该黑色点为圆心R为半径没有发现新的节点。

那么就可以断定这条路没走过,然后以它为起点向两端探索重复上述5个步骤即可。

 

4.最开始是打算把所有直线都近似成圆弧,使得节点处两圆弧顺滑对接,然而发现在急转弯处会有不协调的现象发生,于是改为

如下方法:

假设ABC三点依次相邻,AB的倾斜角设为a,现在:

1)从B点开始向(a+k)%360的方向延长d的距离,作为新的B点,而原来的B点变为A点

2)重复上述步骤,直到B点和C点重合(当B到C的方向已经和延长方向一致时,k变为0)

3)将中间经过的各点直线连接

其中,k和d为常数,当d足够小时,肉眼可认为是曲线。

顺滑化完成。

5.这一步就比较简单了,直接把第四步的单列(线稿)上的每一点存入数组,再一次以数组里的每一点为圆心R为半径的圆全变为黑色。

加粗完成。

 

 

(如果顺利的话可能会更新各步骤的代码)

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
采用python,opencv开源库实现图片提取曲线数据 使用说明: openpic 可以选择采用自动采集测点数据或手动采集测点数据 操作过程:第一步裁剪,crop, 鼠标响应step_crop, 鼠标左键选裁剪的矩形区域,选后键盘n表示确认进入下一步骤; 无需裁剪时键盘o直接进入下一步骤;esc表示取消,退回到开始 第二步矫正,correction,鼠标响应step_correction, 鼠标左键点选梯形矫正的四个顶点, 键盘u左上,i右上,j左下,k右下,切换当前有效操作做的顶点, 键盘w up, s down, a left, d right 或上下左右键,微调鼠标选点位置,detail display放大显示当前选点的细节; 键盘t键操作矫正,n键表示确认矫正结果进入下一步骤,b键表示取消矫正重新选梯形顶点 第三步坐标系,coordinate,鼠标响应step_coordinate, 鼠标左键点选xy坐标系的原点、x轴最大刻度点、y轴最大刻度点。 xy轴的坐标刻度值由选择图片窗口的x、y最大最小值决定,xy轴必须原点处交汇但可以从非零开始分别计算刻度 键盘u y轴,j 坐标原点,k x轴,切换当前鼠标点选的有效点 键盘w up, s down, a left, d right 或上下左右键,微调鼠标选点位置,detail display放大显示当前选点的细节; 默认图片已经矫正,坐标系仅支持直角坐标系,在设置坐标系时原点可以任意移动,x轴y轴只能依据原点位置在直角轴上移动 键盘n表示确认坐标系设置结果进入下一步,b表示取消退回到上一步,esc退回到开始 第四步采集数据:手动采集manual_sample使用sample_points,鼠标响应step_sample_points,鼠标左键点选要采集的测点,键盘n表示确认选择开始选下一个点 键盘o表示选择完输出测点数据到csv文件。 键盘w up, s down, a left, d right 或上下左右键,微调鼠标选点位置,detail display放大显示当前选点的细节; 自动采集auto_sample使用tracecolor,鼠标响应step_color_picker。自动采集原理为先选择曲线,然后自动等间隔采集曲线上点 开始界面没有自动采集点数,在使用auto的函数调用时添加。 自动采集以tracecolor颜色提取构建曲线曲线点数据平滑,间隔重采样为主要工作过程。在图片存在同色非相关区域时,可采用颜色提取刷,手动确定曲线的有效范围 键盘l切换提取刷开关,提取刷功能开启时,鼠标右键按住滑动刷出有效的采集范围。 鼠标左键点选的位置作为提取颜色,同时具备单一颜色固定阈值提取曲线和多个颜色自动确定阈值范围的提取曲线两种模式。 键盘p选择鼠标位置的点颜色作为多个颜色参考提取,移动鼠标位置(或键盘移动)采用p键选择多个颜色点,确定提取阈值范围 键盘n表示完成颜色选择开始曲线提取,显示提取后黑白曲线图,键盘b取消提取退回上一步重新操作 esc取消退回到开始 键盘o表示接受曲线提取结果,开始自动间隔采集计算曲线上点,并输出csv文件
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值