最近在琢磨如何对物体上带颜色标记的点进行实时跟踪,并且显示点的质心坐标。接下来和大家分享一下学习过程中学到的一些基础知识。
笔者刚开始研究物体追踪时也是不知道从何处下手,刚开始先去OpenCV example里下载了Camshiftdemo,在电脑上跑了跑demo,发现需要手动来框选追踪物体,而且无法同时追踪多个物体,太不方便了。。。。
下面开始介绍算法思路:
二.算法中用到的函数
(1)Videocapture类
cv::VideoCapture::VideoCapture ( const String & filename )
用途:可打开视频文件或用于打开由摄像头捕获的视频流,打开视频文件举例
VideoCapture capture("F:/videos.avi");
打开摄像头示例(打开默认摄像头)
VideoCapture capture
capture.open(0)
(2)cvtcolor函数
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 );
InputArray src:未进行颜色变换前的原始图像
OutputArray dst:颜色变换后输出的图像
int code:即确定将图片由什么颜色空间转换为另一个颜色空间,本算法使用COLOR_BGR2HSV将图片有RGB空间转换为HSV空间
int dstCn=0:目标图像通道数,如果取值为0,则由src和code决定
(3)inRange函数
void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)
InputArray src:原始图像
InputArray upperb:阈值上界
OutputArray dst:表示输出后的图像是二值化的图像
本算法中函数具体应用为:
inRange(HSV,Scalar(H_MIN,S_MIN,V_MIN),Scalar(H_MAX,S_MAX,V_MAX),threshold)
(4)图像腐蚀
void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );
(5)图像膨胀
void dilate( const Mat& src, Mat& dst, const Mat& element,Point anchor=Point(-1,-1), int iterations=1,int borderType=BORDER_CONSTANT,
(6)图像滤波:高斯滤波、中值滤波、双边滤波、均值滤波,方框滤波,几种滤波各有优缺点。
void GaussianBlur(InputArray src,OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, intborderType=BORDER_DEFAULT )
void medianBlur(InputArray src,OutputArray dst, int ksize)
void bilateralFilter(InputArray src, OutputArraydst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT)
void blur(InputArray src, OutputArraydst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
void boxFilter(InputArray src,OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), boolnormalize=true, int borderType=BORDER_DEFAULT )
void Canny(InputArray image,OutputArray edges, double threshold1, double threshold2, int apertureSize=3,bool L2gradient=false )
(5)findContours函数
void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )
(6)计算轮廓的矩
vector mu(contours.size());//Moments得到多边形的多阶矩,
for (int i = 0; i < contours.size(); i++)
{
mu[i] = moments(contours[i], false);
}
(7)计算轮廓的质心
vector mc(contours.size());
for (int i = 0; i < contours.size(); i++)
{
mc[i] = Point2d(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);//多边形的质心为x=m10/m00,y=m01/m00;
}