zoukankan      html  css  js  c++  java
  • opecv2 MeanShift 使用均值漂移算法查找物体

    #if !defined OFINDER
    #define OFINDER
    
    #include <opencv2corecore.hpp>
    #include <opencv2imgprocimgproc.hpp>
    
    class ContentFinder {
    
    private:
    
    	float hranges[2];
        const float* ranges[3];
        int channels[3];
    
    	float threshold;
    	cv::MatND histogram;
    	cv::SparseMat shistogram;
    	bool isSparse;
    
      public:
    
    	ContentFinder() : threshold(0.1f), isSparse(false) {
    
    		ranges[0]= hranges; // all channels have the same range 
    		ranges[1]= hranges; 
    		ranges[2]= hranges; 
    	}
       
    	// Sets the threshold on histogram values [0,1]
    	void setThreshold(float t) {
    
    		threshold= t;
    	}
    
    	// Gets the threshold
    	float getThreshold() {
    
    		return threshold;
    	}
    
    	// Sets the reference histogram
    	void setHistogram(const cv::MatND& h) {
    
    		isSparse= false;
    		histogram= h;
    		cv::normalize(histogram,histogram,1.0);
    	}
    
    	// Sets the reference histogram
    	void setHistogram(const cv::SparseMat& h) {
    
    		isSparse= true;
    		shistogram= h;
    		cv::normalize(shistogram,shistogram,1.0,cv::NORM_L2);
    	}
    
    cv::Mat find(const cv::Mat& image) {
    
    		cv::Mat result;
    
    		hranges[0]= 0.0;	// range [0,255]
    		hranges[1]= 255.0;
    		channels[0]= 0;		// the three channels 
    		channels[1]= 1; 
    		channels[2]= 2; 
    
    		if (isSparse) { // call the right function based on histogram type
    
    		   cv::calcBackProject(&image,
                          1,            // one image
                          channels,     // vector specifying what histogram dimensions belong to what image channels
                          shistogram,   // the histogram we are using
                          result,       // the resulting back projection image
                          ranges,       // the range of values, for each dimension
                          255.0         // the scaling factor is chosen such that a histogram value of 1 maps to 255
    		   );
    
    		} else {
    
    		   cv::calcBackProject(&image,
                          1,            // one image
                          channels,     // vector specifying what histogram dimensions belong to what image channels
                          histogram,    // the histogram we are using
                          result,       // the resulting back projection image
                          ranges,       // the range of values, for each dimension
                          255.0         // the scaling factor is chosen such that a histogram value of 1 maps to 255
    		   );
    		}
    
    
            // Threshold back projection to obtain a binary image
    		if (threshold>0.0)
    			cv::threshold(result, result, 255*threshold, 255, cv::THRESH_BINARY);
    
    		return result;
    	}
    
    cv::Mat find(const cv::Mat& image, float minValue, float maxValue, int *channels, int dim) {
    
    		cv::Mat result;
    
    		hranges[0]= minValue;
    		hranges[1]= maxValue;
    
    		for (int i=0; i<dim; i++)
    			this->channels[i]= channels[i];
    
    		if (isSparse) { // call the right function based on histogram type
    
    		   cv::calcBackProject(&image,
                          1,            // we only use one image at a time
                          channels,     // vector specifying what histogram dimensions belong to what image channels
                          shistogram,   // the histogram we are using
                          result,       // the resulting back projection image
                          ranges,       // the range of values, for each dimension
                          255.0         // the scaling factor is chosen such that a histogram value of 1 maps to 255
    		   );
    
    		} else {
    
    		   cv::calcBackProject(&image,
                          1,            // we only use one image at a time
                          channels,     // vector specifying what histogram dimensions belong to what image channels
                          histogram,    // the histogram we are using
                          result,       // the resulting back projection image
                          ranges,       // the range of values, for each dimension
                          255.0         // the scaling factor is chosen such that a histogram value of 1 maps to 255
    		   );
    		}
    
            // Threshold back projection to obtain a binary image
    		if (threshold>0.0)
    			cv::threshold(result, result, 255*threshold, 255, cv::THRESH_BINARY);
    
    		return result;
    	}
    
    };
    
    
    #endif
    
    #if !defined COLHISTOGRAM
    #define COLHISTOGRAM
    
    #include <opencv2corecore.hpp>
    #include <opencv2imgprocimgproc.hpp>
    #include<opencv2/highgui/highgui.hpp>
    class ColorHistogram {
    
      private:
    
        int histSize[3];
    	float hranges[2];
        const float* ranges[3];
        int channels[3];
    
      public:
    
    	ColorHistogram() {
    
    		// Prepare arguments for a color histogram
    		histSize[0]= histSize[1]= histSize[2]= 256;
    		hranges[0]= 0.0;    // BRG range
    		hranges[1]= 255.0;
    		ranges[0]= hranges; // all channels have the same range 
    		ranges[1]= hranges; 
    		ranges[2]= hranges; 
    		channels[0]= 0;		// the three channels 
    		channels[1]= 1; 
    		channels[2]= 2; 
    	}
    
    	// Computes the histogram.
    	cv::MatND getHistogram(const cv::Mat &image) {
    
    		cv::MatND hist;
    
    		// BGR color histogram
    		hranges[0]= 0.0;    // BRG range
    		hranges[1]= 255.0;
    		channels[0]= 0;		// the three channels 
    		channels[1]= 1; 
    		channels[2]= 2; 
    
    		// Compute histogram
    		cv::calcHist(&image, 
    			1,			// histogram of 1 image only
    			channels,	// the channel used
    			cv::Mat(),	// no mask is used
    			hist,		// the resulting histogram
    			3,			// it is a 3D histogram
    			histSize,	// number of bins
    			ranges		// pixel value range
    		);
    
    		return hist;
    	}
    
    	// Computes the 1D Hue histogram with a mask.
    	// BGR source image is converted to HSV
    	cv::MatND getHueHistogram(const cv::Mat &image) {
    
    		cv::MatND hist;
    
    		// Convert to Lab color space
    		cv::Mat hue;
    		cv::cvtColor(image, hue, CV_BGR2HSV);
    
    		// Prepare arguments for a 1D hue histogram
    		hranges[0]= 0.0;
    		hranges[1]= 180.0;
    		channels[0]= 0; // the hue channel 
    
    		// Compute histogram
    		cv::calcHist(&hue, 
    			1,			// histogram of 1 image only
    			channels,	// the channel used
    			cv::Mat(),	// no mask is used
    			hist,		// the resulting histogram
    			1,			// it is a 1D histogram
    			histSize,	// number of bins
    			ranges		// pixel value range
    		);
    
    		return hist;
    	}
    
    	
    cv::MatND getHueHistogram(const cv::Mat &image,int minSaturation)
    	{
    		cv::MatND hist;
    		cv::Mat hsv;
    		cv::cvtColor(image,hsv,CV_BGR2HSV);
    		cv::Mat mask;
    		if(minSaturation>0)
    		{
    			std::vector<cv::Mat>v;
    			cv::split(hsv,v);
    			cv::threshold(v[1],mask,minSaturation,255,cv::THRESH_BINARY);
    		}
    		hranges[0]=0.0;
    		hranges[1]=180.0;
    		channels[0]=0;
    		calcHist(&hsv,1,channels,mask,hist,1,histSize,ranges);
    		return hist;
    	}
    
    };
    
    
    #endif
    
    #include<opencv2/core/core.hpp>
    #include<opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
    #include<opencv2/video/video.hpp>
    #include<iostream>
    #include"colorhistogram.h"
    #include"ContentFinder.h"
    
    using namespace std;
    using namespace cv;
     
    
    int main()
    {
    	Mat image=imread("d:/test/opencv/baboon1.jpg");
    	Mat imageROI=image(Rect(110,260,35,40));
    	int minSat=65;
    	ColorHistogram hc;
    	MatND colorhist=hc.getHueHistogram(imageROI,minSat);
    
    	namedWindow("image 1");
    	imshow("image 1",image);
    
    	ContentFinder finder;
    	finder.setHistogram(colorhist);
    	Mat hsv;
    	image=imread("d:/test/opencv/baboon3.jpg");
    	namedWindow("image 2");
    	imshow("image 2",image);
    	cvtColor(image,hsv,CV_BGR2HSV);
    	vector<Mat>v;
    	split(hsv,v);
    	threshold(v[1],v[1],minSat,255,THRESH_BINARY);
    	cv::namedWindow("Saturation");
    	cv::imshow("Saturation",v[1]);
    	int channel[1]={0};
    	Mat result=finder.find(hsv,0.0f,180.0f,channel,1);
    
    
    	cv::namedWindow("Result Hue");
    	cv::imshow("Result Hue",result);
    
    	cv::bitwise_and(result,v[1],result);
    	cv::namedWindow("Result Hue and");
    	cv::imshow("Result Hue and",result);
    
    
    	finder.setThreshold(-1.0f);//
    	result= finder.find(hsv,0.0f,180.0f,channel,1);
    	cv::bitwise_and(result,v[1],result);
    	cv::namedWindow("Result Hue and raw");
    	cv::imshow("Result Hue and raw",result);
    
    	cv::Rect rect(110,260,35,40);
    	cv::rectangle(image, rect, cv::Scalar(0,0,255));
    
    	cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER,10,0.01);
    	cout << "meanshift= " << cv::meanShift(result,rect,criteria) << endl;//
    
    	cv::rectangle(image, rect, cv::Scalar(0,255,0));//
    
    	// Display image
    	cv::namedWindow("Image 2 result");
    	cv::imshow("Image 2 result",image);
    
    	cv::waitKey();
    	return 0;
    
    }


     

  • 相关阅读:
    怎么在excel单元格里原有的筛选里面添加新选项
    redis通信协议
    nginx路由文件配置
    R语言绘制相对性关系图
    Generator函数的语法
    360前端星计划作业
    工厂模式
    ReferenceError与undefined的区别
    for...in与点语法
    博客申请成功
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7047390.html
Copyright © 2011-2022 走看看