您的位置:首页 > 运维架构

OpenCV的circle函数画圆的小技巧

2015-11-21 11:46 881 查看

前言

在特征点检测的时候,通常需要画圆来表示特征点的强度,OpenCV很方便的提供了circle函数来画圆,函数签名

CV_EXPORTS_W void circle(CV_IN_OUT Mat& img, Point center, int radius,const Scalar& color,
int thickness=1,int lineType=8, int shift=0);


一般来说,我们只关心前面4个参数,给定图像,中心点,半径和颜色就可以画一个圆,最近在研究OpenCV源码的时候,发现了一个很好玩的结果,先看两张图像



分析

这是我在做尺度不变性Harris角点检测得到的结果,可以看到右边图中的圆更加饱满更加好看,左边图中的圆锯齿状非常明显,下面是对应的代码

//(a)图
circle(imgSrc, Point(c, r),3*round(dvecSigma[i])*,Scalar(0, 255, 0);

//(b)图
circle(imgSrc, Point(c*(1<<4), r*(1<<4)),
3*round(dvecSigma[i])*(1<<4), Scalar(0, 255, 0), 1,CV_AA,4);


和(a)相比,(b)将中心点坐标和半径同时乘以1<<4(即16),再将linetype设为CV_AA,同时将shift设置为4,就可以将圆画的更加好看,下面是OpenCV画sift特征点的源码,我的灵感就是从这里面来的,文件位置OpencvDir/sources/modules/features2d/src\draw.cpp

//就是这个变量
const int draw_shift_bits = 4;
const int draw_multiplier = 1 << draw_shift_bits;

namespace cv
{

/*
* Functions to draw keypoints and matches.
*/
static inline void _drawKeypoint( Mat& img, const KeyPoint& p,
const Scalar& color, int flags )
{
CV_Assert( !img.empty() );
//中心点*(1<<4)
Point center( cvRound(p.pt.x * draw_multiplier), cvRound(p.pt.y * draw_multiplier) );

if( flags & DrawMatchesFlags::DRAW_RICH_KEYPOINTS )
{
//半径*(1<<4)
int radius = cvRound(p.size/2 * draw_multiplier); // KeyPoint::size is a diameter

// 画圆
circle( img, center, radius, color, 1, CV_AA, draw_shift_bits );

// draw orientation of the keypoint, if it is applicable
if( p.angle != -1 )
{
float srcAngleRad = p.angle*(float)CV_PI/180.f;
Point orient( cvRound(cos(srcAngleRad)*radius ),
cvRound(sin(srcAngleRad)*radius )
);
line( img, center, center+orient, color, 1, CV_AA, draw_shift_bits );
}
...


有哪位大神知道原理的,希望不吝赐教
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息