【原】OpenCV轮廓提取(7月13日~7月17日工作小记)

这周是实习的第一周,天天要早起,天天挤地铁,没想到,自己就这样成为上班一族了 。第一周比较累,每天到公司就像梦游似的,晚睡的习惯一下也改不过来,严重睡眠不足,在公司中午也睡不了觉,所以到下午两点左右的时候特别困,好几天我都坐在电脑前打瞌睡

公司在做一个地面互动系统的项目,我的任务是从图像中提取出脚印的轮廓,拼接相近的脚印,当做一个脚印处理,并返回拼接后每个脚印的位置,我返回的是包含脚印的矩形,采用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   
{   
   //相交   
}  
/****************************************************************************/
我就把它写成代码了,如下:
.
// 在二值图像上查找contour
    cvFindContours( m_pTempImg,storage, & cont, sizeof (CvContour),
                           CV_RETR_LIST,CV_CHAIN_APPROX_NONE, cvPoint(
0 , 0 ) );


/**/ /**********************************将位置相近的轮廓合并***************************************/     
    BOOL                       m,n;
    
int                         mark  =   0 ,diffX,diffY;
    CvRect                     temp;
    vector
<  CvRect  > ::iterator iter ;
    
    
for ( ;cont;cont  =  cont -> h_next )    
    
{
        rect 
= ( (CvContour*)cont ) -> rect;
        
if( rect.height * rect.width > AREASMALL && ( rect.height * rect.width ) < (m_pContourImg->width * m_pContourImg->height-AREALARGE )) 
        
{
            
if0 == mark ) 
            
{
                FootSeq.push_back( rect );
                mark 
= 1;
                    
            }

            
else                 
            
{
                
for( iter= FootSeq.begin();iter != FootSeq.end();iter++ )    //for1
                {
                    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 )   //两矩形不相交
                    {
                        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 )
                        
{
                            
//保存原值
                            temp.x      = ( *iter ).x;
                            temp.y      
= ( *iter ).y;
                            temp.width  
= ( *iter ).width;
                            temp.height 
= ( *iter ).height;    

                            
//合并新的矩形,覆盖原矩形
                            (*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          //相交则合并
                    {
                        
//保存原值
                        temp.x      = ( *iter ).x;
                        temp.y      
= ( *iter ).y;
                        temp.width  
= ( *iter ).width;
                        temp.height 
= ( *iter ).height;

                        
//合并新的矩形,覆盖原矩形
                        (*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;
                    }
//相交
                }


                
if( iter == FootSeq.end() )    
                    FootSeq.push_back( rect );    
//如果FootSeq中没有与cont可合并的矩形,就将该矩形存储,作为新的矩形。
            }
//end else  (mark == 1)
        }
  //end if   (面积符合要求)
    }
// end for (cont == NULL)

你可能感兴趣的:(【原】OpenCV轮廓提取(7月13日~7月17日工作小记))