老铁!怎么识别一张图片上文字的颜色 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
fffflyfish
V2EX    Python

老铁!怎么识别一张图片上文字的颜色

  •  
  •   fffflyfish
    FormatFish 2017-04-14 19:11:28 +08:00 9676 次点击
    这是一个创建于 3108 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位好,最近小弟遇到一个问题,就是怎么识别一张图片上文字的颜色,我目前的解决方法如下:

    首先使用 ocr 工具先在图片上找出一行文本,然后把这一行文本中的每个文字都切片,然后对每个切片抽取 5 个颜色,选择占面积最大的颜色作为该切片上的文字颜色,但是因为一张图片上文字的颜色可能不一样,我这里只是想抽取一种颜色,所以我就把所有切片的文字颜色综合起来,找出其中出现数量最多的颜色,并把这个颜色作为该张图片的文字颜色。

    以上就是我的方法,但是很耗时间,各位老铁有什么更好的方法吗?

    29 条回复    2021-01-19 10:08:49 +08:00
    dingz
        1
    dingz  
       2017-04-14 19:35:22 +08:00 via Android
    文字背景色是纯色么?你的方法能排除文字背景色么?觉得直接对文字部分位图数组遍历,排除掉背景色像素值,剩下前景色求颜色平均值,效率应该不会很差吧。
    fffflyfish
        2
    fffflyfish  
    OP
       2017-04-14 19:53:13 +08:00
    @dingz 文字背景不一定是纯色的,但是使用 ocr 选中每一个颜色的框框里按道理来说文字所占的颜色面积最大,这是我的依据。直接排除背景色像素值,因为是这样,我会对 ocr 识别出的文字图片抽取 5 个颜色,所以现在就不知道哪个是背景哪个是前景,如果默认面积大的就是背景的话会有问题
    fffflyfish
        3
    fffflyfish  
    OP
       2017-04-14 19:54:09 +08:00
    @dingz 我给你看看我这边做出来的效果吧,黑色是 0 ,也就是非文字,白色是 1 ,也就是文字颜色
    ![]( )
    ![]( )
    dingz
        4
    dingz  
       2017-04-14 20:43:02 +08:00 via Android
    我没有细想,你的黑白图哪来的?是 ocr 结果么?如果原图和黑白图大小一样,剩下的就是让程序读取原图在黑白图中为白色的部分。
    fffflyfish
        5
    fffflyfish  
    OP
       2017-04-14 20:50:42 +08:00
    @dingz 黑白图是我用我上面说的方法自己做出来的效果,我这个方法是可以识别出部分文字颜色的,但是很耗时间,大概一张图要 1min+,所以想问下有没有更好的方法
    steley
        6
    steley  
       2017-04-14 20:59:58 +08:00
    有相关软件,叫什么 pickup colour 什么的
    fffflyfish
        7
    fffflyfish  
    OP
       2017-04-14 21:10:07 +08:00
    @steley 你说的是那种取色工具吗?我这里想实现完全自动化,让计算机识别文字颜色,中间不需要人为干预的那种 233
    jinyue524
        8
    jinyue524  
       2017-04-14 21:23:58 +08:00
    可以先把颜色从 RGB 转换成 HSV ,然后直接判断图片的颜色“角度”就可以了。

    如果用 OpenCV 的话,可以考虑 cvtColor, InRange 两个函数,应该可以直接得到红色文字了。
    fffflyfish
        9
    fffflyfish  
    OP
       2017-04-14 22:14:40 +08:00
    @jinyue524 没有用过 opencv ,你这个方法是指针对某个颜色的文字吗?假设文字的颜色有多种呢?我这里用的颜色通道是 LAB ,你说的颜色角度是啥?
    dingz
        10
    dingz  
       2017-04-14 22:31:55 +08:00 via Android
    如果有 ocr 工具的源代码,直接识别文字的时候顺带拿一下颜色应该最效率……
    ilotuo
        11
    ilotuo  
       2017-04-15 00:38:32 +08:00
    找特征点,遍历特征点找出现最多次的颜色.
    ilotuo
        12
    ilotuo  
       2017-04-15 00:40:09 +08:00   1
    补充一下,遍历特征点附近的 8*8 色块,找出现最多次的颜色
    jinyue524
        13
    jinyue524  
       2017-04-15 09:26:30 +08:00 via iPhone
    @fffflyfish HSV 的颜色是用角度标识的, H 通道,在 openCV 里面范围是 0-180 。比如,红色是 0-10 和 160-180 ,蓝色大概是 35-55 ,等等,还可以区分绿色,紫色,青色等等。
    zhidian
        14
    zhidian  
       2017-04-15 09:32:14 +08:00
    好奇楼上,换成 HSV 颜色空间就能区分出字上的像素和背景像素?
    zhidian
        15
    zhidian  
       2017-04-15 09:38:10 +08:00
    我的思路: 1 )缩放到一个合适的比例再处理(怎么会一张图片几分钟……); 2 )边缘提取; 3 )细化边缘(用腐蚀?); 3 )求边缘像素的颜色众数。

    细化边缘是因为字体和背景过渡的地方(很可能)反锯齿了。
    zhidian
        16
    zhidian  
       2017-04-15 09:39:54 +08:00
    或许应该用“线提取”而不是“边缘提取”。
    minami
        17
    minami  
       2017-04-15 10:01:17 +08:00
    @zhidian 他的意思是,转换成 HSV 后,颜色信息就只包含在一个通道内,检查这一个通道就可以判断颜色。如果是 RGB 的话,颜色信息就分散到三个通道内了。
    fffflyfish
        18
    fffflyfish  
    2017-04-15 13:11:51 +08:00
    @jinyue524 @minami 原来如此,这个我倒是没有想到,但是我想了一下,如果只是换一下颜色空间的话貌似还是没解决我的问题,不过我试试 hsv 套在我的方法上会不会好点,谢谢两位
    fffflyfish
        19
    fffflyfish  
    OP
       2017-04-15 13:19:18 +08:00
    @zhidian 哎呀,我忘了缩放了,,你说的边缘提取这种需要先把图像二值化了把,但是不知道文字颜色的话如何二值化,咋设置 thresh ,我试过把一张图灰度化,然后二值化图像连通域分析,但是通常如果图像背景是深色,前景是淡色的话会有用,遇上背景是白色字是黑色这种情况就不行了,因为我二值化的时候都是把 thresh 设成 0.5 ,偏白色大部分会被二值化为 1 ,所以效果有限。也不知道 ocr 中识别文字区域的那一步是咋做的,我找找代码好了,谢谢老铁
    pimin
        20
    pimin  
       2017-04-15 13:34:32 +08:00 via Android
    OCR 选区建立的时候普遍就是根据颜色。
    类似 PS 中的选择色彩范围。
    zhidian
        21
    zhidian  
       2017-04-15 13:42:35 +08:00
    @fffflyfish 边缘提取不能二值化啊 ==(只有两种像素还提取啥啊 ==)。通常先处理成灰度倒是真的。
    JerryCha
        22
    JerryCha  
       2017-04-15 16:45:49 +08:00 via iPhone
    你都得 OCR 的结果了,直接对结果进行边缘检测就能提取边缘了,干净有效。或者用 OCR 结果与原图逐个像素进行与运算,相当于抠图把文字从原图里抠出来,然后马赛克化,再从 HSV 通道统计颜色信息。
    理论上来说,统计个颜色不会很慢,跑 1min 太夸张了
    fffflyfish
        23
    fffflyfish  
    OP
       2017-04-15 16:59:00 +08:00
    @pimin @zhidian
    我根据两位的思路做了一个 ocr 的前期的文字区域识别的方法,但是有点问题,先给你们看下效果图:
    ![]( )
    ![]( )
    ![]( )
    但是有个问题,在前期选区的时候需要对图像进行斑点检测,然后生成二值化图像,问题就出在二值化图像这里,阈值不好选,跟文字的颜色和文字所在背景的颜色有很大的关系,以下是检测出错的:
    ![]( )
    两位老哥有啥建议不
    fffflyfish
        24
    fffflyfish  
    OP
       2017-04-15 17:04:22 +08:00
    @JerryCha 对哦,我试试,谢谢啦
    zhidian
        25
    zhidian  
       2017-04-16 00:44:10 +08:00
    这些文字的框的坐标你都知道吗?(用的什么软件?)如果是自己代码找到了框的位置,画上去的,你就可以直接统计了啊。==
    fffflyfish
        26
    fffflyfish  
    OP
       2017-04-16 12:30:03 +08:00
    @zhidian 对,我进行斑点检测,找到的所有框,用 python 的 skimage 库做的, opencv 应该也可以。直接统计还是会有点小问题的,我还在想法解决
    xiaotianhu
        27
    xiaotianhu  
       2017-04-16 17:46:25 +08:00
    PHP 聚类算法 就可以的,代码不多 几百行搞定了
    http://www.phpfensi.com/php/20140827/4848.html
    fffflyfish
        28
    fffflyfish  
    OP
       2017-04-16 17:51:19 +08:00
    @xiaotianhu 谢谢啦,提取图像颜色不是问题,问题在于要提取图像上某一个元特定素的颜色的问题,这个可能就会涉及到识别和检测相关的算法
    gandhi001
        29
    gandhi001  
       2021-01-19 10:08:49 +08:00
    大佬,请问您最后解决的方案是什么呀
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2761 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 08:56 PVG 16:56 LAX 01:56 JFK 04:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86