OpenCV2用均值漂移(Mean Shift)查找物体
2015-12-10 10:30
267 查看
参考《opecv2计算机视觉》
//在image1中找一块作为样本,在image2中找出和image1中样本相近的区域
colorhistogram.h
error C2660: “ColorHistogram::getHueHistogram”: 函数不接受 2 个参数.
修改后的
objectfinder.h
finder.cpp
//在image1中找一块作为样本,在image2中找出和image1中样本相近的区域
colorhistogram.h
#if !defined COLHISTOGRAM #define COLHISTOGRAM #include <opencv2\core\core.hpp> #include <opencv2\imgproc\imgproc.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 histogram. cv::SparseMat getSparseHistogram(const cv::Mat &image) { cv::SparseMat hist(3,histSize,CV_32F); // 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 2D ab histogram. // BGR source image is converted to Lab cv::MatND getabHistogram(const cv::Mat &image) { cv::MatND hist; // Convert to Lab color space cv::Mat lab; cv::cvtColor(image, lab, CV_BGR2Lab); // Prepare arguments for a 2D color histogram hranges[0]= -128.0; hranges[1]= 127.0; channels[0]= 1; // the two channels used are ab channels[1]= 2; // Compute histogram cv::calcHist(&lab, 1, // histogram of 1 image only channels, // the channel used cv::Mat(), // no mask is used hist, // the resulting histogram 2, // it is a 2D 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::Mat colorReduce(const cv::Mat &image, int div=64) { int n= static_cast<int>(log(static_cast<double>(div))/log(2.0)); // mask used to round the pixel value uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0 cv::Mat_<cv::Vec3b>::const_iterator it= image.begin<cv::Vec3b>(); cv::Mat_<cv::Vec3b>::const_iterator itend= image.end<cv::Vec3b>(); // Set output image (always 1-channel) cv::Mat result(image.rows,image.cols,image.type()); cv::Mat_<cv::Vec3b>::iterator itr= result.begin<cv::Vec3b>(); for ( ; it!= itend; ++it, ++itr) { (*itr)[0]= ((*it)[0]&mask) + div/2; (*itr)[1]= ((*it)[1]&mask) + div/2; (*itr)[2]= ((*it)[2]&mask) + div/2; } return result; } }; #endif
error C2660: “ColorHistogram::getHueHistogram”: 函数不接受 2 个参数.
修改后的
#if !defined COLHISTOGRAM #define COLHISTOGRAM #include <opencv2\core\core.hpp> #include <opencv2\imgproc\imgproc.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 histogram. cv::SparseMat getSparseHistogram(const cv::Mat &image) { cv::SparseMat hist(3,histSize,CV_32F); // 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 2D ab histogram. // BGR source image is converted to Lab cv::MatND getabHistogram(const cv::Mat &image) { cv::MatND hist; // Convert to Lab color space cv::Mat lab; cv::cvtColor(image, lab, CV_BGR2Lab); // Prepare arguments for a 2D color histogram hranges[0]= -128.0; hranges[1]= 127.0; channels[0]= 1; // the two channels used are ab channels[1]= 2; // Compute histogram cv::calcHist(&lab, 1, // histogram of 1 image only channels, // the channel used cv::Mat(), // no mask is used hist, // the resulting histogram 2, // it is a 2D 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 // Pixels with low saturation are ignored <span style="background-color: rgb(255, 255, 0);">cv::MatND getHueHistogram(const cv::Mat &image, int minSaturation=0) { cv::MatND hist; // Convert to HSV color space cv::Mat hsv; cv::cvtColor(image, hsv, CV_BGR2HSV); // Mask to be used (or not) cv::Mat mask; if (minSaturation>0) { // Spliting the 3 channels into 3 images std::vector<cv::Mat> v; cv::split(hsv,v); // Mask out the low saturated pixels cv::threshold(v[1],mask,minSaturation,255, cv::THRESH_BINARY); }</span> // 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(&hsv, 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::Mat colorReduce(const cv::Mat &image, int div=64) { int n= static_cast<int>(log(static_cast<double>(div))/log(2.0)); // mask used to round the pixel value uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0 cv::Mat_<cv::Vec3b>::const_iterator it= image.begin<cv::Vec3b>(); cv::Mat_<cv::Vec3b>::const_iterator itend= image.end<cv::Vec3b>(); // Set output image (always 1-channel) cv::Mat result(image.rows,image.cols,image.type()); cv::Mat_<cv::Vec3b>::iterator itr= result.begin<cv::Vec3b>(); for ( ; it!= itend; ++it, ++itr) { (*itr)[0]= ((*it)[0]&mask) + div/2; (*itr)[1]= ((*it)[1]&mask) + div/2; (*itr)[2]= ((*it)[2]&mask) + div/2; } return result; } }; #endif
objectfinder.h
#if !defined OFINDER #define OFINDER #include <opencv2\core\core.hpp> #include <opencv2\imgproc\imgproc.hpp> class ObjectFinder { private: float hranges[2]; const float* ranges[3]; int channels[3]; float threshold; cv::MatND histogram; cv::SparseMat shistogram; bool isSparse; public: ObjectFinder() : 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); } // Finds the pixels belonging to the histogram 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
finder.cpp
/*------------------------------------------------------------------------------------------*\ This file contains material supporting chapter 4 of the cookbook: Computer Vision Programming using the OpenCV Library. by Robert Laganiere, Packt Publishing, 2011. This program is free software; permission is hereby granted to use, copy, modify, and distribute this source code, or portions thereof, for any purpose, without fee, subject to the restriction that the copyright notice may not be removed or altered from any source or altered source distribution. The software is released on an as-is basis and without any warranties of any kind. In particular, the software is not guaranteed to be fault-tolerant or free from failure. The author disclaims all warranties with regard to this software, any use, and any consequent failure, is purely the responsibility of the user. Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name \*------------------------------------------------------------------------------------------*/ #include <iostream> #include <vector> using namespace std; #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <opencv2\video\tracking.hpp> #include "objectFinder.h" #include "colorhistogram.h" int main() { // Read reference image cv::Mat image= cv::imread("baboon1.jpg"); if (!image.data) return 0; // Define ROI cv::Mat imageROI= image(cv::Rect(110,260,35,40)); cv::rectangle(image, cv::Rect(110,260,35,40),cv::Scalar(0,0,255)); // Display image cv::namedWindow("Image"); cv::imshow("Image",image); // Get the Hue histogram int minSat=65; ColorHistogram hc; cv::MatND colorhist= hc.getHueHistogram(imageROI,minSat); ObjectFinder finder; finder.setHistogram(colorhist); finder.setThreshold(0.2f); // Convert to HSV space cv::Mat hsv; cv::cvtColor(image, hsv, CV_BGR2HSV); // Split the image vector<cv::Mat> v; cv::split(hsv,v); // Eliminate pixels with low saturation cv::threshold(v[1],v[1],minSat,255,cv::THRESH_BINARY); cv::namedWindow("Saturation"); cv::imshow("Saturation",v[1]); // Get back-projection of hue histogram int ch[1]={0}; cv::Mat result= finder.find(hsv,0.0f,180.0f,ch,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); // Second image image= cv::imread("baboon3.jpg"); // Display image cv::namedWindow("Image 2"); cv::imshow("Image 2",image); // Convert to HSV space cv::cvtColor(image, hsv, CV_BGR2HSV); // Split the image cv::split(hsv,v); // Eliminate pixels with low saturation cv::threshold(v[1],v[1],minSat,255,cv::THRESH_BINARY); cv::namedWindow("Saturation"); cv::imshow("Saturation",v[1]); // Get back-projection of hue histogram result= finder.find(hsv,0.0f,180.0f,ch,1); cv::namedWindow("Result Hue"); cv::imshow("Result Hue",result); // Eliminate low stauration pixels cv::bitwise_and(result,v[1],result); cv::namedWindow("Result Hue and"); cv::imshow("Result Hue and",result); // Get back-projection of hue histogram finder.setThreshold(-1.0f); result= finder.find(hsv,0.0f,180.0f,ch,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; }
相关文章推荐
- 网站统计中的数据收集原理及实现_埋点统计
- Centos6.5 卸载系统默认安装的jdk
- Linux DNS之一DNS相关基础概念
- Apache Commons工具集简介
- Linux 基础 —— YUM入门
- 利用Nginx做负载均衡
- Xcode真机测试could not find developer disk image解决方法
- 为何 Linux 桌面应该按任务来组织管理?
- Shell 字符串比较
- shell 常用命令之二 find
- 解决opengl计算顶点的法线问题
- Linux进程的Uninterruptible sleep(D)状态
- OpenCV成长之路(8):直线、轮廓的提取与描述
- OpenGL超级宝典笔记——GLSL语言基础(转)
- Linux基础教程
- Linux下matlab断点调试
- OpenCV成长之路(9):特征点检测与图像匹配
- input_open_file()浅析
- Openstack API
- J版OpenStack非admin用户无法获取OS-EXT-SRV-ATTR属性问题详解