新手提问:如何用 Python 识别魔方上不同颜色块的数量?

2019-05-16 19:06:15 +08:00
 zaxlct

下图由黄,红,绿,蓝方块组成,如何获取每种颜色方块的数量? 如果用 python 来实现的话,有第三方库或思路推荐吗,谢谢

我首先想到了 openCV,如果实在没思路的话,就去 GayHub 找个 python-opencv 的库试试看,考虑到可能会绕圈子,所以在这里问问 pythoner 大佬,感想~

6398 次点击
所在节点    Python
43 条回复
AlisaDestiny
2019-05-16 19:17:09 +08:00
颜色空间直方图了解一下。
zaxlct
2019-05-16 19:22:01 +08:00
@AlisaDestiny 谢谢,我查查相关资料
Muniesa
2019-05-16 19:53:00 +08:00
我的思路是,按颜色设置阈值,分割之后计算每种颜色轮廓的面积,和总面积一比就可以了
Muniesa
2019-05-16 19:55:16 +08:00
好像跟直方图原理差不多 hhh 都是计算像素数量
Takamine
2019-05-16 22:06:52 +08:00
不知道用一个和方块一样大小的 scanner 一路扫过去,结合 PIL 库有没有戏。
ThirdFlame
2019-05-16 22:36:03 +08:00
如果方块大小是固定和一致的,如果是的话 使用 PIL 库 隔多少像素去一个点,获得 rgb 值即可。
no1xsyzy
2019-05-16 22:44:32 +08:00
卖垫子的?

1. 需要被统计的块是否可能本身是白色的?
2. 是否保证存在白色缝隙?
3. 是否对精度有绝对要求?
zaxlct
2019-05-16 22:51:48 +08:00
@no1xsyzy 哈哈,卖地胶的,白色的块无需统计,保证存在白色缝隙,对精度有要求。但是图片分辨率都会和上面的第一张图一样清楚。

如果你有思路可以聊下,我可以付一些辛苦费,告诉我思路自己去实现,嘿嘿
ThirdFlame
2019-05-16 23:05:24 +08:00
有个简单粗暴的方法,直接遍历所有点的 RGB 值,然后拿同颜色的点( RGB 相近)的数量 除以 1 块的像素点数量(宽*高) 就能得到大概值了。
不过半块的之类的会导致少算一些。
minami
2019-05-16 23:15:39 +08:00
这种估计只能用图形学的区域填充算法,把每块的边界算出来,才能保证精度
zaxlct
2019-05-16 23:20:26 +08:00
查了很多资料,GayHub 也翻了半天没找到好的办法,我看最终的办法只能靠肉眼去数了 = =!
no1xsyzy
2019-05-16 23:36:01 +08:00
@zaxlct 这样相对简单,用白色切开后统计每个块的颜色直方图。
精度要求我认为设计成先显示一个带覆盖层的样子然后人工检验一下比较好。
最好能够比较方便地指出错误类型

“与其费力地尝试完全取代人类的工作,不如想想如何让人类的工作变得更加方便”
necomancer
2019-05-17 02:37:25 +08:00
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 即可。
necomancer
2019-05-17 02:52:18 +08:00
我没怎么折腾过这类问题,你最好看看 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 范围参考。
necomancer
2019-05-17 03:10:34 +08:00
P.S. 地胶市场咋样?这么丑的设计地胶能卖出去么……
dangyuluo
2019-05-17 05:53:39 +08:00
如果要大致计算的话,就用直方图。如果要精确计算的话,就划分网格,然后一个个中心取 RGB 值。不规则形状的话,用一个 mask 来遮住空白区域
largecat
2019-05-17 07:23:38 +08:00
第一个图横竖遍历,每个方格中心点像素值取出来,最后统计像素值数量就行。

第二个不规则图形,细节还是小方格,我觉得先把不规则图形补成规则的长方形,再横竖遍历,最后求像素个数,

一般图形颜色不会那么整齐,考虑颜色值的一个偏移范围,
JerryCha
2019-05-17 08:27:09 +08:00
腐蚀好像可以消去细线和封闭区块内的点
zaxlct
2019-05-17 08:43:30 +08:00
@necomancer 这个图只是方便客户,计算需要的数量,实际不是这个样子,市场挺好的
ytmsdy
2019-05-17 09:19:39 +08:00
参考图片二值化的做法,把颜色进行三值化就可以了。然后就可以直接数块状大小了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/564824

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX