找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 6277|回复: 1

解魔方机器人[四]-建立模型(上)

[复制链接]
发表于 2016-9-5 17:21:48 | 显示全部楼层 |阅读模式

我们已经得到了6×9个RGB值,但这些都代表什么颜色?我们需要的是不同色块对应到6种不同的颜色,因此必须对这54个RGB值进行划分,使他们归到自己的颜色分类中。关于颜色分类其实属于数字图像处理学中的一个重要研究领域,在此仅对比较通用的一种方法进行介绍。

4.1 色彩模型转换

色彩模型是描述使用一组值(通常使用3个、4个值或者颜色成分)表示颜色方法的抽象数学模型。例如三原色光模式(RGB) 和印刷四分色模式(CMYK)都是色彩模型。EV3颜色传感器获得的就是RGB模型,可以表示为三维直角坐标颜色系统的一个单位正方体。

在大多数的彩色图形显示设备一般都是使用红、绿、蓝三原色,我们的真实感图形学中的主要的颜色模型也是RGB模型,但是红、绿、蓝颜色模型用起来不太方便,它与直观的颜色概念如色调、饱和度和亮度等没有直接的联系。比如,我们很难从RGB的取值上区分这个颜色属于哪个色域,因此根据不同应用,还有HSV、HSI、CHL、LAB、CMY等其他色彩模型。由于颜色本身并没有发生变化,只是各个色彩模型表示颜色的方法不同,色彩模型之间可以通过固定的公式进行相互转换。

HSV、HSI、LAB都可以很好的将色相以一定规律排列出来。在本项目中,使用HSV模型作为颜色识别的色彩模型。关于HSV模型的详细描述,可以参见http://www.pazhong.net/?p=325
交给OpenCV

在程序实现方面,我更建议使用已经投入大量应用的函数库,而不是自己重新写一遍。因为已投入应用的函数库经过了长期的优化,能够保证实现的效率和安全。尽管RGB转HSV的程序实现很简单,只要按照公式直译成程序即可,但我还是使用了OpenCV的cvtColor函数。

在此之前,需要按照OpenCV模块,官方网站给出了比较详细的安装方法。ev3dev基于Debian系统,可以通过apt-get install python-opencv指令进行模块及相关依赖包的安装。

OpenCV为图像处理提供了大量的算法实现函数,在处理魔方色块时,我们可以将6×9个色块理解为一张大小为6×9的图像,每个色块为图像中的一个像素点,然后对这张图像进行RGB到HSV的转换。

对于这个图像与魔方色块的对应表示关系为:

  • [0,0]表示图像第1行第1列的像素点,对应魔方上为第1个扫描面的第1个扫描色块
  • [0,1]表示图像第1行第2列的像素点,对应魔方上为第1个扫描面的第2个扫描色块
  • [3,4]表示图像第3行第4列的像素点,对应魔方上为第3个扫描面的第4个扫描色块

OpenCV的程序实现

# 仅为示例,非实际使用程序image_hsv = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2HSV)

此时得到的image_hsv为一张大小为6×9的HSV图像,image_hsv[0,0,0]为第1行第1列的H值,image_hsv[0,0,1]为第1行第1列的S值,image_hsv[0,0,2]为第1行第1列的V值。

4.2 色块划分

利用HSV色彩空间的性质,通过对所有色块H值的排序,然后再以每9个色块为一组,可以得到每个色块的分组,也就得到了该色块所属的颜色类别。

通过一个简单的例子能帮助更好理解。假设我们有9个色块,一共3种颜色,这9个色块的H值分别如下:

位置
[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
H值
22
121
25
186
190
118
24
124
188

接下来我们按这9个色块的H值从小到大排序,排序的同时他们的位置也随着调整:

位置
[0]
[6]
[2]
[5]
[1]
[7]
[3]
[8]
[4]
H值
22
24
25
118
121
124
186
188
190

我们知道一共有3种颜色,按照这个排序,每3个色块归为一组。也就是说位置在[0][6][2]的色块是同一种颜色,[5][1][7]为同一种颜色,[3][8][4]为同一种颜色。

位置排序程序

如果理解了以上的划分原理,开始写程序会发现一个问题。与通常的排序不同,这里不是只对位置上的值排序,而是通过位置上值的大小完成对位置的排序。在程序设计过程中,需要额外增加一个变量来记录位置的变换。

  1. # 按照数组值的大小完成数组位置的排序
  2. # 输入:l为要排序的数组
  3. def sort_pos(l):

  4.   # 定义pos数组,与l相同大小,初始化为l的原始位置
  5.   pos = np.arange(len(l))
  6.   for i in range(len(l)-1):
  7.     for j in range(len(l)-i-1):

  8.       # 按照l数组的值的大小进行比对
  9.       if l[j] > l[j+1]:

  10.       # 调整pos的值,即记录l位置的变化
  11.       pos[j], pos[j+1] = pos[j+1], pos[j]

  12.   # 返回排序后位置的变化情况
  13.   return pos
复制代码

这一节确实有一些难理解,先多看看上面表格里排序的例子,再去试着理解程序会更好一些。


如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2016-9-6 17:13:26 | 显示全部楼层
学习了
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|中文乐高 ( 桂ICP备13001575号-7 )

GMT+8, 2024-4-26 00:23 , Processed in 1.628709 second(s), 22 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表