#if !defined OFINDER
#define OFINDER
#include
#include
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
#include
#include
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::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
#include
#include
#include
#include
#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;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章