opencv2均值漂移算法

来源:互联网 发布:不宜乐乎的乐怎么读 编辑:程序博客网 时间:2024/04/27 11:05

为了方便调用,我将opencv2许多常用的函数以及功能都封装在一个类里面,所以这次的均值漂移算法也将从封装类中截取出来,供大家学习

类的代码:

class Package{private:public:Rect MeanShitfMath(const Mat &OrgInImage, const Mat &PreInImage, Rect &ROIrect);};Rect Package::MeanShitfMath(const Mat &OrgInImage, const Mat &PreInImage, Rect &ROIrect){Mat orgimg = OrgInImage;Mat preimg = PreInImage;/*先对输入的原始图像进行感兴趣区域的采集*///先获取感兴趣区域的图像Mat bgrROI = orgimg(ROIrect);//将感兴趣区域的BGR空间转换为HSV空间Mat hsvROI;cvtColor(bgrROI, hsvROI, CV_BGR2HSV);//获取感兴趣区域的HSV空间的S空间vector<Mat>hsvROIvector;split(hsvROI, hsvROIvector);//将S通道的阀值化threshold(hsvROIvector[1], hsvROIvector[1], 65, 255.0, THRESH_BINARY);//计算S通道的直方图float hranges[2];const float* ranges[1];int channels[1];MatND hsvROIhist;int histSize[1];hranges[0] = 0.0;hranges[1] = 180.0;ranges[0] = hranges;channels[0] = 0;histSize[0] = 256;calcHist(&hsvROIvector[1], 1, channels, Mat(), hsvROIhist, 1, histSize, ranges);//归一化直方图normalize(hsvROIhist, hsvROIhist, 1.0);/*在输入的第二幅图像中进行均值漂移算法*/Mat prehsv;cvtColor(preimg, prehsv, CV_BGR2HSV);vector<Mat>prehsvvector;split(prehsv, prehsvvector);/*threshold(prehsvvector[1], prehsvvector[1], 65, 255.0, THRESH_BINARY);*///在第二幅图上获取感兴趣区域的直方图的反投影Mat result;calcBackProject(&(prehsvvector[1]), 1, channels, hsvROIhist, result, ranges, 255.0);threshold(result, result, 255 * (-1.0f), 255.0, THRESH_BINARY);bitwise_and(result, prehsvvector[1], result);/*rectangle(preimg, ROIrect, Scalar(0, 0, 255));*///meanshift算法TermCriteria criteria(TermCriteria::MAX_ITER, 10, 0.01);meanShift(result, ROIrect, criteria);/*rectangle(preimg, ROIrect, Scalar(0, 255, 0));*/return ROIrect;}


基本思路:
  1、先在输入的原始图像中找到感兴趣的区域,并将这个感兴趣区域的直方图计算出来(不过这次计算的直方图不是BGR空间下的,而是HSV空间下的,所以需要
  先转换颜色空间),也不再是得到改感兴趣区域某一个通道下的直方图信息,而是得到HSV空间的S通道的改感兴趣区域的直方图(需分解)
  2、然后就是在第二幅图像中将上一部得到的感兴趣区域的S通道的直方图进行反投影,反投影到第二幅图像中的S通道上
  3、反投影完成后就开始进行meanshift算法

返回的是一个Rect类型的矩形区域,这个矩形是通过均值漂移算法在另一张图中找到的相似的区域,在主函数中可以用rectangle函数降其显示出来


测试代码:

#include<opencv2/imgproc/imgproc.hpp>#include<opencv2/imgproc/types_c.h>#include<opencv2/highgui/highgui.hpp>#include<opencv2/core/core.hpp>#include<iostream>#include<vector>#include<opencv2/nonfree/features2d.hpp>#include<opencv2/legacy/legacy.hpp>#include<opencv2/features2d/features2d.hpp>#include<opencv2/calib3d/calib3d.hpp>#include<opencv2/video/tracking.hpp>using namespace cv;using namespace std;class Package{private:public:Rect MeanShitfMath(const Mat &OrgInImage, const Mat &PreInImage, Rect &ROIrect);};Rect Package::MeanShitfMath(const Mat &OrgInImage, const Mat &PreInImage, Rect &ROIrect){Mat orgimg = OrgInImage;Mat preimg = PreInImage;/*先对输入的原始图像进行感兴趣区域的采集*///先获取感兴趣区域的图像Mat bgrROI = orgimg(ROIrect);//将感兴趣区域的BGR空间转换为HSV空间Mat hsvROI;cvtColor(bgrROI, hsvROI, CV_BGR2HSV);//获取感兴趣区域的HSV空间的S空间vector<Mat>hsvROIvector;split(hsvROI, hsvROIvector);//将S通道的阀值化threshold(hsvROIvector[1], hsvROIvector[1], 65, 255.0, THRESH_BINARY);//计算S通道的直方图float hranges[2];const float* ranges[1];int channels[1];MatND hsvROIhist;int histSize[1];hranges[0] = 0.0;hranges[1] = 180.0;ranges[0] = hranges;channels[0] = 0;histSize[0] = 256;calcHist(&hsvROIvector[1], 1, channels, Mat(), hsvROIhist, 1, histSize, ranges);//归一化直方图normalize(hsvROIhist, hsvROIhist, 1.0);/*在输入的第二幅图像中进行均值漂移算法*/Mat prehsv;cvtColor(preimg, prehsv, CV_BGR2HSV);vector<Mat>prehsvvector;split(prehsv, prehsvvector);/*threshold(prehsvvector[1], prehsvvector[1], 65, 255.0, THRESH_BINARY);*///在第二幅图上获取感兴趣区域的直方图的反投影Mat result;calcBackProject(&(prehsvvector[1]), 1, channels, hsvROIhist, result, ranges, 255.0);threshold(result, result, 255 * (-1.0f), 255.0, THRESH_BINARY);bitwise_and(result, prehsvvector[1], result);/*rectangle(preimg, ROIrect, Scalar(0, 0, 255));*///meanshift算法TermCriteria criteria(TermCriteria::MAX_ITER, 10, 0.01);meanShift(result, ROIrect, criteria);/*rectangle(preimg, ROIrect, Scalar(0, 255, 0));*/return ROIrect;}Package P;int main(){Mat img1 = imread("F:\\baboon1.jpg");Mat img2 = imread("F:\\baboon3.jpg");rectangle(img1, Rect(110, 260, 35, 40), Scalar(0, 255, 255));namedWindow("img1");imshow("img1", img1);Rect rect = P.MeanShitfMath(img1, img2, Rect(110, 260, 35, 40));rectangle(img2, rect, Scalar(255, 0, 0));namedWindow("result");imshow("result", img2);waitKey(0);return 0;}



各位博友,如果要转载的话,请注明出处!!!

谢谢各位了


0 0