Posted on 2009-07-27 21:52
千张 阅读(12648)
评论(8) 编辑 收藏 引用 所属分类:
图像处理
这周是实习的第一周,天天要早起,天天挤地铁,没想到,自己就这样成为上班一族了
![](http://www.cppblog.com/CuteSoft_Client/CuteEditor/images/emsmile.gif)
。第一周比较累,每天到公司就像梦游似的,晚睡的习惯一下也改不过来,严重睡眠不足,在公司中午也睡不了觉,所以到下午两点左右的时候特别困,好几天我都坐在电脑前打瞌睡
![](http://www.cppblog.com/CuteSoft_Client/CuteEditor/images/emteeth.gif)
。
公司在做一个地面互动系统的项目,我的任务是从图像中提取出脚印的轮廓,拼接相近的脚印,当做一个脚印处理,并返回拼接后每个脚印的位置,我返回的是包含脚印的矩形,采用OpenCV实现的。我们采用了是红外线装置,所以拍摄出来的图像噪声比较少,二值化时采用合适的阈值,效果就比较好。
OpenCV文档中有轮廓提取的例程,这里就详细不介绍了,我的步骤包括预处理(滤波处理)->灰度化->二值化->Canny边缘检测->轮廓提取,可以将二值化这一步省略,二值化很依赖阈值,光照对其影响较大。
下面就贴下拼接的代码:(若两矩形相交或中心比较接近,就拼接这两个矩形)
在CSDN上看到一个测试两矩形是否相交的特简单的方法:
/****************************************************************************/
矩形A和B
矩形 A (x1,y1),(x2,y2); //矩形的左上角和右下角坐标
矩形 B (x3,y3),(x4,y4);
设 m = (x1>x4) | (x2<x3)
n = (y2<y3) | (y1>y4)
if(m | n)
{
//不相交
}
else
{
//相交
}
/****************************************************************************/
我就把它写成代码了,如下:
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/dot.gif)
.
//在二值图像上查找contour
cvFindContours( m_pTempImg,storage,&cont,sizeof(CvContour),
CV_RETR_LIST,CV_CHAIN_APPROX_NONE, cvPoint(0,0) );
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/dot.gif)
![](http://www.cppblog.com/Images/dot.gif)
![](http://www.cppblog.com/Images/dot.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//**********************************将位置相近的轮廓合并***************************************/
BOOL m,n;
int mark = 0,diffX,diffY;
CvRect temp;
vector< CvRect >::iterator iter ;
for( ;cont;cont = cont->h_next )
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
rect = ( (CvContour*)cont ) -> rect;
if( rect.height * rect.width > AREASMALL && ( rect.height * rect.width ) < (m_pContourImg->width * m_pContourImg->height-AREALARGE ))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if( 0 == mark )
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
FootSeq.push_back( rect );
mark = 1;
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
for( iter= FootSeq.begin();iter != FootSeq.end();iter++ ) //for1
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
m = (rect.x > ((*iter).x + (*iter).width)) || ((rect.x + rect.width) < (*iter).x);
n = ((rect.y+rect.height) < (*iter).y) || (rect.y > ((*iter).y + (*iter).height));
if( m || n ) //两矩形不相交
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
diffX = ( rect.x+rect.width/2)-((*iter).x+(*iter).width/2 );
diffY = ( rect.y+rect.height/2)-((*iter).y+(*iter).height/2 );
if ( (int)( diffX*diffX + diffY*diffY ) < DISTANCE )
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//保存原值
temp.x = ( *iter ).x;
temp.y = ( *iter ).y;
temp.width = ( *iter ).width;
temp.height = ( *iter ).height;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//合并新的矩形,覆盖原矩形
(*iter).x = ( rect.x > (*iter).x) ? (*iter).x : rect.x;
(*iter).y = ( rect.y > (*iter).y) ? (*iter).y : rect.y;
(*iter).width = ( (rect.x + rect.width) > (temp.x + temp.width)) ? (rect.x + rect.width - (*iter).x) : ((temp.x + temp.width)-(*iter).x );
(*iter).height = ( (rect.y + rect.height) > (temp.y + temp.height)) ? (rect.y + rect.height - (*iter).y) : ((temp.y + temp.height)-(*iter).y );
break;
}
}//不相交,若不合并,则继续与下一个轮廓比较
else //相交则合并
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//保存原值
temp.x = ( *iter ).x;
temp.y = ( *iter ).y;
temp.width = ( *iter ).width;
temp.height = ( *iter ).height;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//合并新的矩形,覆盖原矩形
(*iter).x = ( rect.x > (*iter).x) ? (*iter).x : rect.x;
(*iter).y = ( rect.y > (*iter).y) ? (*iter).y : rect.y;
(*iter).width = ( (rect.x + rect.width) > (temp.x + temp.width)) ? (rect.x + rect.width - (*iter).x) : ((temp.x + temp.width)-(*iter).x );
(*iter).height = ( (rect.y + rect.height) > (temp.y + temp.height)) ? (rect.y + rect.height - (*iter).y) : ((temp.y + temp.height)-(*iter).y );
break;
}//相交
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( iter == FootSeq.end() )
FootSeq.push_back( rect ); //如果FootSeq中没有与cont可合并的矩形,就将该矩形存储,作为新的矩形。
}//end else (mark == 1)
} //end if (面积符合要求)
}//end for (cont == NULL)