下图由黄,红,绿,蓝方块组成,如何获取每种颜色方块的数量? 如果用 python 来实现的话,有第三方库或思路推荐吗,谢谢
我首先想到了 openCV,如果实在没思路的话,就去 GayHub 找个 python-opencv 的库试试看,考虑到可能会绕圈子,所以在这里问问 pythoner 大佬,感想~
1
AlisaDestiny 2019-05-16 19:17:09 +08:00 1
颜色空间直方图了解一下。
|
2
zaxlct OP @AlisaDestiny 谢谢,我查查相关资料
|
3
Muniesa 2019-05-16 19:53:00 +08:00
我的思路是,按颜色设置阈值,分割之后计算每种颜色轮廓的面积,和总面积一比就可以了
|
4
Muniesa 2019-05-16 19:55:16 +08:00
好像跟直方图原理差不多 hhh 都是计算像素数量
|
5
Takamine 2019-05-16 22:06:52 +08:00
不知道用一个和方块一样大小的 scanner 一路扫过去,结合 PIL 库有没有戏。
|
6
ThirdFlame 2019-05-16 22:36:03 +08:00
如果方块大小是固定和一致的,如果是的话 使用 PIL 库 隔多少像素去一个点,获得 rgb 值即可。
|
7
no1xsyzy 2019-05-16 22:44:32 +08:00 1
卖垫子的?
1. 需要被统计的块是否可能本身是白色的? 2. 是否保证存在白色缝隙? 3. 是否对精度有绝对要求? |
8
zaxlct OP |
9
ThirdFlame 2019-05-16 23:05:24 +08:00
有个简单粗暴的方法,直接遍历所有点的 RGB 值,然后拿同颜色的点( RGB 相近)的数量 除以 1 块的像素点数量(宽*高) 就能得到大概值了。
不过半块的之类的会导致少算一些。 |
10
minami 2019-05-16 23:15:39 +08:00
这种估计只能用图形学的区域填充算法,把每块的边界算出来,才能保证精度
|
11
zaxlct OP 查了很多资料,GayHub 也翻了半天没找到好的办法,我看最终的办法只能靠肉眼去数了 = =!
|
12
no1xsyzy 2019-05-16 23:36:01 +08:00 1
@zaxlct 这样相对简单,用白色切开后统计每个块的颜色直方图。
精度要求我认为设计成先显示一个带覆盖层的样子然后人工检验一下比较好。 最好能够比较方便地指出错误类型 “与其费力地尝试完全取代人类的工作,不如想想如何让人类的工作变得更加方便” |
13
necomancer 2019-05-17 02:37:25 +08:00 1
from skimage.color import rgb2hsv, rgba2rgb
from skimage import data, io, filters import numpy as np image = io.imread('1.png') hsv = rgb2hsv(rgba2rgb(image)) h_hist, h = np.histogram(hsv[...,0].flatten(), bins=30) 1. 把你的图转成 hsv,在 h 空间求 histogram,黑 /白色的 h 值会是 0 所以不用在意。选择合适的 bins,使峰个数和颜色个数相等。忽略小于某值的 h,因为是白色。这里如果你的图里每个颜色都是纯色,bins 原则多大都是准确的。 2. 建议你尽量把图的 dpi 搞成一样的,也就是说每个方块大小相等,图总大小只和方块数有关。这样你只要算出一个方块有多少像素,用上述的 h_hist 值去除就可以了。因为不到一个方块按一个方块计算,所以向上取整 int(h_hist/square_size)+1 即可。 |
14
necomancer 2019-05-17 02:52:18 +08:00 1
我没怎么折腾过这类问题,你最好看看 rgb2hsv 和 rgba2rgb 之类的函数,了解一下 hsv 模型。理论上说,白色的话 hsv 里 s 是 0, v 是 1,rgb2hsv 里给出的 h 也应该是 0,但近白色 h 不一定是 0,所以纯色最好。你这图不知道为啥好像不完全是纯色,所以筛选起来可能会比较麻烦,求 histogram 之前可以考虑像 hsv = hsv[np.logical_and(hsv[...,1]>0.05, hsv[...,2]<0.95)]这样按照 s, v (白色 s 值比较小接近 0,v 值比较大接近 1 )尽可能地把白色去掉,以增加准确度。
可以看看这里: http://www.voidcn.com/article/p-dntnbcyb-ro.html 有常见颜色的 HSV 范围参考。 |
15
necomancer 2019-05-17 03:10:34 +08:00
P.S. 地胶市场咋样?这么丑的设计地胶能卖出去么……
|
16
dangyuluo 2019-05-17 05:53:39 +08:00 1
如果要大致计算的话,就用直方图。如果要精确计算的话,就划分网格,然后一个个中心取 RGB 值。不规则形状的话,用一个 mask 来遮住空白区域
|
17
largecat 2019-05-17 07:23:38 +08:00 via Android 1
第一个图横竖遍历,每个方格中心点像素值取出来,最后统计像素值数量就行。
第二个不规则图形,细节还是小方格,我觉得先把不规则图形补成规则的长方形,再横竖遍历,最后求像素个数, 一般图形颜色不会那么整齐,考虑颜色值的一个偏移范围, |
18
JerryCha 2019-05-17 08:27:09 +08:00
腐蚀好像可以消去细线和封闭区块内的点
|
19
zaxlct OP @necomancer 这个图只是方便客户,计算需要的数量,实际不是这个样子,市场挺好的
|
20
ytmsdy 2019-05-17 09:19:39 +08:00 1
参考图片二值化的做法,把颜色进行三值化就可以了。然后就可以直接数块状大小了。
|
21
atz 2019-05-17 09:32:11 +08:00 1
反正你这每一个格子大小应该都是固定的,用 opencv 查询每个格子中间像素的数值就很好统计
|
23
littleylv 2019-05-17 09:49:28 +08:00 1
简单提供一个思路,不知道符不符合你的要求:
分别针对 4 个颜色,做 cv::threshold、cv::findContours 等操作,得到各个颜色的总面积。后面就可以除以每个色块的面积得到大概的色块数量了 |
25
qza1212 2019-05-17 15:00:28 +08:00
直接通过颜色做阈值分割,分别拿到各种颜色的面积,然后除以单个方块的面积就行了
|
26
moodasmood 2019-05-17 15:39:32 +08:00 via Android
细线一定存在?都存在的话按细线切割开就行了呀
|
27
minmini 2019-05-17 16:19:19 +08:00 via Android 1
下午摸鱼写了一下,4 个颜色分别 181 731 14 34 个?
|
30
minmini 2019-05-17 21:31:06 +08:00 1
|
31
cz5424 2019-05-17 22:42:31 +08:00 via iPhone
计算一下间隙距离(从左到右遇到白色块的距离)切割图片,遍历所有小图
|
33
minmini 2019-05-17 23:54:47 +08:00 1
@zaxlct
先用不同的色彩通道做二值化,然后合并(bitwise_and),再简单的处理一下得到网格的 mask,然后用原图减去网格得到很多小方块。再寻找轮廓就能够得到全部小方块的轮廓,获取每个小方块的中心坐标,再拿着全部坐标到原图(转成 HSV)去取值,最后根据 @necomancer 的方法来判断颜色就好了 |
34
zaxlct OP @minmini 谢谢你的回复,我去试试。另外一个不情之请,方便的话能不能提供下部分代码,作为感谢,一本 python 相关的书作为感谢~京东上可以自选,报酬很低,见谅~
|
36
zaxlct OP |
38
vmebeh 2019-05-18 01:18:37 +08:00 via iPad
我觉得可以写个拼图的工具
|
39
lovestudykid 2019-05-18 02:49:51 +08:00 1
|
40
hacunix 2019-05-18 08:56:29 +08:00 via iPhone
hsv 了解一下
|
41
banditv2ex 2019-05-18 10:15:33 +08:00 1
直接把所有的像素转换成 rgb 编码,然后 计算所有不同 RGB 编码的数量,就是像素量,然后除以每个色块的像素量就是色块数。
|
42
zaxlct OP 条条大路通罗马,等我实现了把代码贴一下
|
43
zaxlct OP @banditv2ex 有的方块可能是半块(不满一块按一块算)所以您的方法可能会有误差
|