2009年4月25日星期六

The full "Square Detector" program.//检测矩形的例子

矩形检测程序,
浏览
//
// The full "Square Detector" program.
// It loads several images subsequentally and tries to find squares in
// each image
//
#ifdef _CH_
#pragma package
#endif

#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#include
#include
#include
#endif

int thresh = 50;
IplImage* img = 0;
IplImage* img0 = 0;
CvMemStorage* storage = 0;
CvPoint pt[4];
const char* wndname = "Square Detection Demo";

// helper function:
// finds a cosine of angle between vectors
// from pt0->pt1 and from pt0->pt2
double angle( CvPoint* pt1, CvPoint* pt2, CvPoint* pt0 )
{
double dx1 = pt1->x - pt0->x;
double dy1 = pt1->y - pt0->y;
double dx2 = pt2->x - pt0->x;
double dy2 = pt2->y - pt0->y;
return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}

// returns sequence of squares detected on the image.
// the sequence is stored in the specified memory storage
CvSeq* findSquares4( IplImage* img, CvMemStorage* storage )
{
CvSeq* contours;
int i, c, l, N = 11;
CvSize sz = cvSize( img->width & -2, img->height & -2 );
IplImage* timg = cvCloneImage( img ); // make a copy of input image
IplImage* gray = cvCreateImage( sz, 8, 1 );
IplImage* pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 );
IplImage* tgray;
CvSeq* result;
double s, t;
// create empty sequence that will contain points -
// 4 points per square (the square's vertices)
CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage );

// select the maximum ROI in the image
// with the width and height divisible by 2
cvSetImageROI( timg, cvRect( 0, 0, sz.width, sz.height ));

// down-scale and upscale the image to filter out the noise
cvPyrDown( timg, pyr, 7 );
cvPyrUp( pyr, timg, 7 );
tgray = cvCreateImage( sz, 8, 1 );

// find squares in every color plane of the image
for( c = 0; c < l =" 0;" l ="=" result =" cvApproxPoly(">total == 4 &&
fabs(cvContourArea(result,CV_WHOLE_SEQ)) > 1000 &&
cvCheckContourConvexity(result) )
{
s = 0;

for( i = 0; i <>= 2 )
{
t = fabs(angle(
(CvPoint*)cvGetSeqElem( result, i ),
(CvPoint*)cvGetSeqElem( result, i-2 ),
(CvPoint*)cvGetSeqElem( result, i-1 )));
s = s > t ? s : t;
}
}

// if cosines of all angles are small
// (all angles are ~90 degree) then write quandrange
// vertices to resultant sequence
if( s < i =" 0;" contours =" contours-">h_next;
}
}
}

// release all the temporary images
cvReleaseImage( &gray );
cvReleaseImage( &pyr );
cvReleaseImage( &tgray );
cvReleaseImage( &timg );

return squares;
}


// the function draws all the squares in the image
void drawSquares( IplImage* img, CvSeq* squares )
{
CvSeqReader reader;
IplImage* cpy = cvCloneImage( img );
int i;

// initialize reader of the sequence
cvStartReadSeq( squares, &reader, 0 );

// read 4 sequence elements at a time (all vertices of a square)
for( i = 0; i <>total; i += 4 )
{
CvPoint* rect = pt;
int count = 4;

// read 4 vertices
memcpy( pt, reader.ptr, squares->elem_size );
CV_NEXT_SEQ_ELEM( squares->elem_size, reader );
memcpy( pt + 1, reader.ptr, squares->elem_size );
CV_NEXT_SEQ_ELEM( squares->elem_size, reader );
memcpy( pt + 2, reader.ptr, squares->elem_size );
CV_NEXT_SEQ_ELEM( squares->elem_size, reader );
memcpy( pt + 3, reader.ptr, squares->elem_size );
CV_NEXT_SEQ_ELEM( squares->elem_size, reader );

// draw the square as a closed polyline
cvPolyLine( cpy, &rect, &count, 1, 1, CV_RGB(0,255,0), 3, CV_AA, 0 );
}

// show the resultant image
cvShowImage( wndname, cpy );
cvReleaseImage( &cpy );
}


void on_trackbar( int a )
{
if( img )
drawSquares( img, findSquares4( img, storage ) );
}

char* names[] = { "pic1.png", "pic2.png", "pic3.png",
"pic4.png", "pic5.png", "pic6.png", 0 };

int main(int argc, char** argv)
{
int i, c;
// create memory storage that will contain all the dynamic data
storage = cvCreateMemStorage(0);

for( i = 0; names[i] != 0; i++ )
{
// load i-th image
img0 = cvLoadImage( names[i], 1 );
if( !img0 )
{
printf("Couldn't load %s\n", names[i] );
continue;
}
img = cvCloneImage( img0 );

// create window and a trackbar (slider) with parent "image" and set callback
// (the slider regulates upper threshold, passed to Canny edge detector)
cvNamedWindow( wndname, 1 );
cvCreateTrackbar( "canny thresh", wndname, &thresh, 1000, on_trackbar );

// force the image processing
on_trackbar(0);
// wait for key.
// Also the function cvWaitKey takes care of event processing
c = cvWaitKey(0);
// release both images
cvReleaseImage( &img );
cvReleaseImage( &img0 );
// clear memory storage - reset free space position
cvClearMemStorage( storage );
if( c == 27 )
break;
}

cvDestroyWindow( wndname );

return 0;
}

#ifdef _EiC
main(1,"squares.c");
#endif

没有评论:

发表评论

欢迎访问、交流!对本博客有何建议,请
来信告知!
本博内容来源于网络,如有不当或侵犯权益,请来信告知,将及时撤除!
如引用博客内容、论文,请注明原作者!

Google一下本博客

  • 《Getting Things Done》读书笔记 - 本文来自 inertial 原创投稿。 我第一次听说《Getting Things Done》这本书的时候误以为它和世面上的那些成功学书籍没什么区别,后来在不少书中看到了这个名字,也看见了很多人的推荐,由此产生了很大的兴趣。上个月正好有不少空闲,就抽时间把这本书读完了。 本来打算读英文原版,但是原版的生...
    5 年前
  • [原]Linux下编译使用boost库 - Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一。 Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成为下一代C++标准库内容。在C++社区中影响甚大,是不折不扣的“准”标准库。Boost由于其对跨平台的强调,对标准C++的强调,与...
    6 年前
  • [原]猎头、培训与咨询的价值(2)【补1】——北漂18年(93) - 【上期用手机写的,同时用语音输入转化成文字,错字较多,经好友霍师傅提醒本期重写,并增加一部分新内容】 简单谈下我对猎头、培训与咨询的看法。三样都干过,算是有些浅见。 猎头 简单的说就是人才中介。虽然在公司看来是可以直接解决现有企业问题的一个直接方法,但很多时候都不太管用。 猎头费一般是人才的一个月月...
    7 年前
  • OpenCV統計應用-Mahalanobis距離 - Mahalanobis距離是一個可以準確找出資料分布上面極端值(Outliers)的統計方法,使用線性迴歸的概念,也就是說他使用的是共變數矩陣以及該資料分布的平均數來找尋極端值的產生,而可以讓一群資料系統具有穩健性(Robust),去除不必要的雜訊訊息,這邊拿前面共變數矩陣的資料為例,並且新增了兩個點座標向量來做...
    15 年前
  • 努力推进模式识别实际产品的开发与应用 - Salu 无论是手写体识别、文档处理、人脸识别、基于内容的图片搜索、嵌入人工智能的搜索技术、虚拟网络社区、还是其它相关新科技下的信息整合领域,现在都在努力实用化。 前两年、即使现在还有很多人在抱怨说人脸的方法都不能用,但是就今年出现的和正在做的有关人脸识别实际应用的各种形式的产品可以说如雨后春笋。这是一个趋...
    16 年前