千张笔记

Email:rain_qian830@163.com
posts - 28, comments - 42, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
这周是实习的第一周,天天要早起,天天挤地铁,没想到,自己就这样成为上班一族了。第一周比较累,每天到公司就像梦游似的,晚睡的习惯一下也改不过来,严重睡眠不足,在公司中午也睡不了觉,所以到下午两点左右的时候特别困,好几天我都坐在电脑前打瞌睡

公司在做一个地面互动系统的项目,我的任务是从图像中提取出脚印的轮廓,拼接相近的脚印,当做一个脚印处理,并返回拼接后每个脚印的位置,我返回的是包含脚印的矩形,采用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)

Feedback

# re: 【原】OpenCV轮廓提取(7月13日~7月17日工作小记)  回复  更多评论   

2009-07-28 11:57 by SW
"二值化很依赖阈值" 可以使用自动阈值,一般效果不错

# re: 【原】OpenCV轮廓提取(7月13日~7月17日工作小记)  回复  更多评论   

2009-07-28 15:14 by 99读书人
很好啊!

# re: 【原】OpenCV轮廓提取(7月13日~7月17日工作小记)  回复  更多评论   

2009-08-01 13:29 by 千张
恩 我用迭代法试了下,效果还可以。@SW

# re: 【原】OpenCV轮廓提取(7月13日~7月17日工作小记)  回复  更多评论   

2009-10-27 21:45 by leremy
不错,我也正在找这样一个方法

# re: 【原】OpenCV轮廓提取(7月13日~7月17日工作小记)  回复  更多评论   

2012-03-15 09:51 by 雷子深蓝
博主,写的很好。。。现在正好感兴趣你这一块,由于新手有点疑惑,想问一下foodseq怎么定义的????

# re: 【原】OpenCV轮廓提取(7月13日~7月17日工作小记)[未登录]  回复  更多评论   

2012-05-29 15:54 by feng
footSeq是怎么定义的

# re: 【原】OpenCV轮廓提取(7月13日~7月17日工作小记)  回复  更多评论   

2013-08-27 10:15 by 一二一
楼主,能解释一下FootSeq是什么么

# re: 【原】OpenCV轮廓提取(7月13日~7月17日工作小记)  回复  更多评论   

2014-03-08 00:28 by l2468y
请问footseq是什么啊?是findcontours保存的所有轮廓的外接矩形vector吗?

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理