Pixy原理及Opencv实现
来源:互联网 发布:网络管理系统 编辑:程序博客网 时间:2024/06/10 09:00
Pixy原理
Pixy的基本思想其实是简单的:利用颜色空间来除去所有用户不感兴趣的背景,提取出前景。但是在实际的环境下却并不好做,特别是摄像头看到的颜色会受到光线的影响,导致颜色的变化(对于这一点,笔者觉得确实是没有办法的,比如红色在黑暗的条件下确实看起来是红色,那么依靠任何颜色空间看到的其实都是黑色,无法区别),因此,对于Pixy这样神奇的产品来讲,他的识别也需要颜色尽量鲜艳,饱和度尽量好的物体,对于背景来讲,也尽量是光线较好、不突变的环境。否则Pixy是“学习”不来的。
在笔者看到的Pixy的对于颜色处理的源码中,其核心思想有2个部分,这也是笔者借鉴最多的地方:
1、对像素点的处理
Pixy接收到摄像头的信息格式应该是YUV格式的,在源码的colorlut.cpp的nextHelper函数中,Pixy做了两件事:1、将YUV转为RGB的;2、处理该像素值得到U和V的值,这里的U和V并不是YUV中的UV通道,而是经过了处理,具体处理的代码如下:其中CL_LUT_ENTRY_SCALE变量为15
if (uv) { c = r+g1+b; if (c<miny) { m_x += 2; continue; } u = ((r-g1)<<CL_LUT_ENTRY_SCALE)/c; c = r+g2+b; if (c<miny) { m_x += 2; continue; } v = ((b-g2)<<CL_LUT_ENTRY_SCALE)/c; uv->m_u = u; uv->m_v = v; }
这样做的好处是在U和V的值中,加入亮度的影响,这样得到的U和V值就考虑到了光线亮度对于物体颜色的影响。
2、对感兴趣域的比较统计
对于得到的U和V,Pixy将其作为“学习”的依据,即下面的学习算法均是依靠此处的U和V来进行的,在colorlut.cpp的calcRatios函数中,Pixy对于得到的U和V值进行了如下处理:其中sig是个结构体,其中的元素代表该感兴趣前景的U和V的上下阈值
while(ip->next(&uv)) { if (uv.m_u>sig->m_uMin) counts[0]++; if (uv.m_u<sig->m_uMax) counts[1]++; if (uv.m_v>sig->m_vMin) counts[2]++; if (uv.m_v<sig->m_vMax) counts[3]++; n++; } // calc ratios ratios[0] = (float)counts[0]/n; ratios[1] = (float)counts[1]/n; ratios[2] = (float)counts[2]/n; ratios[3] = (float)counts[3]/n; // calc mean (because it's cheap to do it here) sig->m_uMean = (sig->m_uMin + sig->m_uMax)/2; sig->m_vMean = (sig->m_vMin + sig->m_vMax)/2;
在上段代码中,Pixy对用户给出区域的像素点与上下阈值进行比较统计,得到的统计值决定了“学习”的方向。
3、根据统计进行“学习”
由上部分得到的ratios数组表征了用户给定区域的像素在该阈值左右的分布,假定给定一个该分布情况的界限,则阈值就可以根据当前分布与给定分布之间的大小进行自动调整(Pixy默认的界限是80%,即该阈值可以提取出图像区域80%的像素值):以U值为例,当图像在该阈值作用下,大于U阈值最小值的像素点有90%,则说明U阈值的最小值过小,此时应该向下调整,使该阈值增大,反之则反之。具体的代码见下: 其中m_ratio为0.8
for (scale=1<<30, sig->m_uMin=sig->m_uMax=sig->m_vMin=sig->m_vMax=0; scale!=0; scale>>=1) { calcRatios(ip, sig, ratios); if (ratios[0]>m_ratio) sig->m_uMin += scale; else sig->m_uMin -= scale; if (ratios[1]>m_ratio) sig->m_uMax -= scale; else sig->m_uMax += scale; if (ratios[2]>m_ratio) sig->m_vMin += scale; else sig->m_vMin -= scale; if (ratios[3]>m_ratio) sig->m_vMax -= scale; else sig->m_vMax += scale; }
根据上述代码可以看到,Pixy在学习的过程中对一幅图像(用户感兴趣)学习了30次,最终根据反馈得到了较好的阈值。
Opencv实现
其实知道了原理之后,想用Opencv对一幅图像进行处理并得到较好的阈值是比较容易的,笔者也对该算法进行了尝(chao)试(xi),但是效果十分不好,1、不能进行较好的前景提取;2、处理速度十分慢。对于以上两个问题,个人认为还是对于YUV的格式没有把握好,导致中间运算出现问题(悼念三分钟尝试失败)。
但是笔者并没有放弃,把该算法移植到了HSV空间上,说是移植,其实中间去掉了一些处理,比如移植的算法没有考虑亮度对颜色的影响(> <),但是确实可以给定一个区域进行自“学习”了,收获还是不小,想要进行参考的同学可以到该地址进行下载http://download.csdn.net/detail/wubaobao1993/9745837
最后上两个图,是该算法的实际效果
- Pixy原理及Opencv实现
- Camshift原理及opencv实现
- kmeans算法原理及opencv中的实现
- 【opencv】SIFT算法原理及实现
- Hu不变矩原理及opencv实现
- Sobel算子原理及OpenCv实现
- Surf算法原理及openCV代码实现
- Hu不变矩原理及opencv实现
- 霍夫变换原理及opencv实现
- 直方图均衡原理及opencv实现
- Hu不变矩原理及opencv实现
- Opencv学习笔记-----PCA原理及OpenCV实现
- 基于opencv人脸检测原理及实现
- 基于opencv人脸检测原理及实现
- 基于opencv人脸检测原理及实现
- Lucas-Kanade算法原理介绍及OpenCV代码实现分析
- Harris角点检测原理及openCV实现
- RANSAC(随机采样一致算法)原理及openCV代码实现
- 如何在 Mac 上卸载 Java
- HTML5中Canvas与SVG的画图原理比较
- zookeeper集群部署
- node-express
- 堆相关的一些操作
- Pixy原理及Opencv实现
- SVG实现超酷素描动画
- JAVA基础题目
- RSA加密传输AES的key和iv (补2016年11月)
- 夕拾算法进阶篇:15)最长公共子序列(动态规划DP)
- 笔记:运算符的重载
- Oracle之用户管理
- hdu1394 -Minimum Inversion Number(线段树求逆序数)
- Andrew Ng教你如何学习机器学习——Quora问答