CMVision的详细知识介绍
Part I
首先必须了解CMVision所处理的图像格式为YUV,如YUYV,两个像素占一个32位的结构体:{y1,u,y2,v},故压缩了一半。CMVision的实时性完全取决于将每一像素与三通道颜色分量6个阈值的比较转化为直接用数组访问+移位操作,这种方式有点像直方图的建立过程,值落在数组的某一个index上就取出该index处的值,0表示不在阈值范围内,整个过程没有使用条件判断。而且它可以顾及任意数量的颜色分割要求。这就是它的出色的地方。
(CTeX 2006.9.14)
Part II
void CMVision::connectComponents(rle * restrict map,int num)
{
int x1,x2;
int l1,l2;
rle r1,r2;
int i,p,s,n;
l1 = l2 = 0;
x1 = x2 = 0;
// Lower scan begins on second line, so skip over first
while(x1 < width){
x1 += map[l1++].length;
}
x1 = 0;
// Do rest in lock step
r1 = map[l1];
r2 = map[l2];
s = l1;
while(l1 < num){
if(r1.color==r2.color && r1.color){
if((x1>=x2 && x1<x2+r2.length) || (x2>=x1 && x2<x1+r1.length)){
if(s != l1){
map[l1].parent = r1.parent = r2.parent;
s = l1;
}else{
// find terminal roots of each path
n = r1.parent;
while(n != map[n].parent) n = map[n].parent;
p = r2.parent;
while(p != map[p].parent) p = map[p].parent;
// must use smaller of two to preserve DAGness!
if(n < p){
map[p].parent = n;
}else{
map[n].parent = p;
}
}
}
}
// Move to next point where values may change
if(x1+r1.length < x2+r2.length){
x1 += r1.length;
r1 = map[++l1];
}else{
x2 += r2.length;
r2 = map[++l2];
}
}
// Now we need to compress all parent paths
for(i=0; i<num; i++){
p = map[i].parent;
if(p > i){
while(p != map[p].parent) p = map[p].parent;
map[i].parent = p;
}else{
map[i].parent = map[p].parent;
}
}
}
其中x1,x2代表像素点索引,l1,l2为RLE的index,r1,r2为当前比较的map。过程示意图
这个代码虽然寥寥数行,里面给出的信息很丰富:
1、定义同一区域为具有共同父节点的runs集合;
2、if((x1>=x2 && x1<x2+r2.length) || (x2>=x1 && x2<x1+r1.length))为判断是否为4-邻域;
3、if(s!l1)判断l1是否+1,l1不变则说明检测到了overlap(图2-4);
...
讨论:
if((x1>=x2 && x1<x2+r2.length) || (x2>=x1 && x2<x1+r1.length))条件好像是多余的,因为 if(x1+r1.length < x2+r2.length)条件已经包含了它们是一定会相邻的.
本文地址:http://www.45fan.com/bcdm/70608.html