void ColorMatcher::calculateHistogram(const ed::Entity& e, ColorHistogram& histogram) const { ed::MeasurementConstPtr msr = e.lastMeasurement(); if (!msr) return; histogram.resize(ColorNameTable::NUM_COLORS); histogram.assign(ColorNameTable::NUM_COLORS, 0); // get color image const cv::Mat& img = msr->image()->getRGBImage(); int pixel_count = 0; for(ed::ImageMask::const_iterator it = msr->imageMask().begin(img.cols); it != msr->imageMask().end(); ++it) { ++pixel_count; const cv::Point2i& p = *it; // Calculate prob distribution const cv::Vec3b& bgr = img.at<cv::Vec3b>(p); const float* probs = color_table_.rgbToDistribution(bgr[2], bgr[1], bgr[0]); for(unsigned int i = 0; i < ColorNameTable::NUM_COLORS; ++i) histogram[i] += probs[i]; } // normalize histogram for(unsigned int i = 0; i < ColorNameTable::NUM_COLORS; ++i) histogram[i] /= pixel_count; }
ColorHistogram ColorHistogram::ScaleHistogram(const vector<float>& gain) const { const ColorHistogramIndexLUT& lut = ColorHistogramIndexLUTFactory::Instance().GetLUT( lum_bins_, color_bins_, color_bins_); ColorHistogram result = EmptyCopy(); if (!IsSparse()) { for (int i = 0; i < total_bins_; ++i) { const float value = bins_[i]; if (value) { const std::tuple<int, int, int>& idx_3d = lut.Ind2Sub(i); const float bin_lum = std::min(lum_bins_ - 1.f, std::get<0>(idx_3d) * gain[0]); const float bin_col1 = std::min(color_bins_ - 1.f, std::get<1>(idx_3d) * gain[1]); const float bin_col2 = std::min(color_bins_ - 1.f, std::get<2>(idx_3d) * gain[2]); result.AddValueInterpolated(bin_lum, bin_col1, bin_col2, value); } } } else { for (const auto& bin : sparse_bins_) { const std::tuple<int, int, int>& idx_3d = lut.Ind2Sub(bin.first); const float bin_lum = std::min(lum_bins_ - 1.f, std::get<0>(idx_3d) * gain[0]); const float bin_col1 = std::min(color_bins_ - 1.f, std::get<1>(idx_3d) * gain[1]); const float bin_col2 = std::min(color_bins_ - 1.f, std::get<2>(idx_3d) * gain[2]); result.AddValueInterpolated(bin_lum, bin_col1, bin_col2, bin.second); } } DCHECK_LT(fabs(WeightSum() - result.WeightSum()), 1e-3f); return result; }
double compare(const Mat &image) { input = hist.colorReduce(image,div); inputH = hist.getHistogram(input); // return compareHist(refH,inputH,CV_COMP_BHATTACHARYYA); //return compareHist(refH,inputH,CV_COMP_CHISQR); //return compareHist(refH,inputH,CV_COMP_INTERSECT); return compareHist(refH,inputH,CV_COMP_CORREL); }
int main() { VideoCapture capture(0); if(!capture.isOpened()) { cout<<"Camera could not be opened"; exit(0); } Mat frame; capture.read(frame); Rect rect(220,100,170,170); Mat imageROI= frame(rect); Mat hsv; ColorHistogram hc; ContentFinder finder; int minSat=65;int channels[]={0}; namedWindow("image 2"); while(1) { MatND colorhist=hc.getHueHistogram(imageROI,minSat); finder.setHistogram(colorhist); int a=capture.read(frame); if(!a) { exit(0); } cv::cvtColor(frame, hsv, CV_BGR2HSV); std::vector<cv::Mat> v; cv::split(hsv,v); threshold(v[1],v[1],minSat,255,cv::THRESH_BINARY); // Get back-projection of hue histogram Mat result= finder.find(hsv,0.0f,180.0f,channels,1); // Eliminate low stauration pixels cv::bitwise_and(result,v[1],result); cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER,10,0.01); cv::CamShift(result,rect,criteria); cv::rectangle(frame, rect, cv::Scalar(0,0,255)); imshow("image 2",frame); int c= cvWaitKey(10); if(char(c)==27) { exit(0); } //cv::imshow("Image",result); Mat imageROI= frame(rect); } cv::waitKey(0); return 0; }
double ColorHistogram::GenericDistance( const ColorHistogram& rhs, std::function<float(float,float)> fun) const { DCHECK(IsSparse() == rhs.IsSparse()); double sum = 0; if (!IsSparse()) { for (int i = 0; i < total_bins_; ++i) { sum += fun(bins_[i], rhs.bins_[i]); } } else { // Sparse processing. for (const auto& bin : sparse_bins_) { const auto& rhs_bin_iter = rhs.sparse_bins_.find(bin.first); sum += fun(bin.second, rhs_bin_iter != rhs.sparse_bins_.end() ? rhs_bin_iter->second : 0.0f); } // Process rhs bins that we might have missed. for (const auto& rhs_bin : rhs.sparse_bins_) { const auto& bin_iter = sparse_bins_.find(rhs_bin.first); if (bin_iter == sparse_bins_.end()) { sum += fun(0, rhs_bin.second); } } } return sum; }
float ColorHistogram::KLDivergence(const ColorHistogram& rhs) const { DCHECK(IsNormalized() && rhs.IsNormalized()); const double eps = 1e-10; return 0.5 * GenericDistance(rhs, [eps](float a, float b) -> float { const double ratio = (a + eps) / (b + eps); return a * std::log(ratio) + b * std::log(1.0 / ratio); }); }
float ColorHistogram::JSDivergence(const ColorHistogram& rhs) const { DCHECK(IsNormalized() && rhs.IsNormalized()); const double eps = 1e-10; return 0.5 * GenericDistance(rhs, [eps](float a, float b) -> float { const double inv_mean = 1.0 / ((a + b) * 0.5 + eps); const double ratio_a = (a + eps) * inv_mean; const double ratio_b = (b + eps) * inv_mean; return a * std::log(ratio_a) + b * std::log(ratio_b); }); }
float ColorHistogram::ChiSquareDist(const ColorHistogram& rhs) const { DCHECK(IsNormalized() && rhs.IsNormalized()); return 0.5 * GenericDistance(rhs, [](float a, float b) -> float { const float add = a + b; if (fabs(add) > 1e-12) { const float sub = a - b; return sub * sub / add; } else { return 0.0f; } }); }
char detectBlueBlock(Mat image) { int T=15; //面积与边长之比的阈值 ColorHistogram hc; MatND colorhist = hc.getHueHistogram(image); //遍历直方图数据 //hc.getHistogramStat(colorhist); /* Mat histImg = hc.getHistogramImage(colorhist); namedWindow("BlueBlockHistogram"); imshow("BlueBlockHistogram", histImg);*/ Mat thresholded, thresholded1, thresholded2, thresholded3; threshold(hc.v[0], thresholded1, 100, 255, 1); threshold(hc.v[0], thresholded2, 124, 255, 0); threshold(hc.v[1], thresholded3, 125, 255, 1); //变成黑色 thresholded = thresholded1+thresholded2+thresholded3; //imshow("1", thresholded1); //imshow("2", thresholded2); //imshow("3", thresholded3); //namedWindow("BlueBlockBinary"); //imshow("BlueBlockBinary", thresholded); int top = (int) (0.05*thresholded.rows); int bottom = (int) (0.05*thresholded.rows); int left = (int) (0.05*thresholded.cols); int right = (int) (0.05*thresholded.cols); Scalar value = Scalar( 255 ); copyMakeBorder( thresholded, thresholded, top, bottom, left, right, 0, value ); /* Mat eroded; erode(thresholded, eroded, Mat()); namedWindow("ErodedImage"); imshow("ErodedImage", eroded); Mat dilated; erode(thresholded, dilated, Mat()); namedWindow("DilatedImage"); imshow("DilatedImage", dilated);*/ //闭运算 Mat closed; morphologyEx(thresholded, closed, MORPH_CLOSE, Mat()); //namedWindow("ClosedImage"); //imshow("ClosedImage", closed); vector<vector<Point>>contours; findContours(closed, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); //筛选不合格轮廓 int cmin = 100; //最小轮廓长度 vector<vector<Point>>::const_iterator itc = contours.begin(); while (itc != contours.end()) { if (itc->size()<cmin) itc = contours.erase(itc); else itc++; } Mat result(closed.size(), CV_8U, Scalar(255)); double area, length, p; double a[2] = {0,0}; cout << "Size=" << contours.size() << endl; for ( int i=0; i<contours.size(); i++) { area = abs(contourArea( contours[i] )); length = abs(arcLength( contours[i], true )); p = area/length; if (p > a[0]) { a[1] = a[0]; a[0] = p; } else if (p > a[1]) a[1] = p; cout << "Area=" << area << " " << "Length=" << length << " " << "Property=" << p << endl; } drawContours(result, contours, -1, Scalar(0), 1); //namedWindow("DrawContours"); //imshow("DrawContours", result); cout << "Property=" << a[1] << endl; //waitKey(); if (a[1] > T) return BLUEBLOCK; else return NOTHING; }
int main() { // Read input image cv::Mat image= cv::imread("waves.jpg",0); if (!image.data) return 0; // define image ROI cv::Mat imageROI; imageROI= image(cv::Rect(216,33,24,30)); // Cloud region // Display reference patch cv::namedWindow("Reference"); cv::imshow("Reference",imageROI); // Find histogram of reference Histogram1D h; cv::Mat hist= h.getHistogram(imageROI); cv::namedWindow("Reference Hist"); cv::imshow("Reference Hist",h.getHistogramImage(imageROI)); // Create the content finder ContentFinder finder; // set histogram to be back-projected finder.setHistogram(hist); finder.setThreshold(-1.0f); // Get back-projection cv::Mat result1; result1= finder.find(image); // Create negative image and display result cv::Mat tmp; result1.convertTo(tmp,CV_8U,-1.0,255.0); cv::namedWindow("Backprojection result"); cv::imshow("Backprojection result",tmp); // Get binary back-projection finder.setThreshold(0.12f); result1= finder.find(image); // Draw a rectangle around the reference area cv::rectangle(image, cv::Rect(216, 33, 24, 30), cv::Scalar(0, 0, 0)); // Display image cv::namedWindow("Image"); cv::imshow("Image",image); // Display result cv::namedWindow("Detection Result"); cv::imshow("Detection Result",result1); // Load color image ColorHistogram hc; cv::Mat color= cv::imread("waves.jpg"); // extract region of interest imageROI= color(cv::Rect(0,0,100,45)); // blue sky area // Get 3D colour histogram (8 bins per channel) hc.setSize(8); // 8x8x8 cv::Mat shist= hc.getHistogram(imageROI); // set histogram to be back-projected finder.setHistogram(shist); finder.setThreshold(0.05f); // Get back-projection of color histogram result1= finder.find(color); cv::namedWindow("Color Detection Result"); cv::imshow("Color Detection Result",result1); // Second color image cv::Mat color2= cv::imread("dog.jpg"); cv::namedWindow("Second Image"); cv::imshow("Second Image",color2); // Get back-projection of color histogram cv::Mat result2= finder.find(color2); cv::namedWindow("Result color (2)"); cv::imshow("Result color (2)",result2); // Get ab color histogram hc.setSize(256); // 256x256 cv::Mat colorhist= hc.getabHistogram(imageROI); // display 2D histogram colorhist.convertTo(tmp,CV_8U,-1.0,255.0); cv::namedWindow("ab histogram"); cv::imshow("ab histogram",tmp); // set histogram to be back-projected finder.setHistogram(colorhist); finder.setThreshold(0.05f); // Convert to Lab space cv::Mat lab; cv::cvtColor(color, lab, CV_BGR2Lab); // Get back-projection of ab histogram int ch[2]={1,2}; result1= finder.find(lab,0,256.0f,ch); cv::namedWindow("Result ab (1)"); cv::imshow("Result ab (1)",result1); // Second colour image cv::cvtColor(color2, lab, CV_BGR2Lab); // Get back-projection of ab histogram result2= finder.find(lab,0,256.0,ch); cv::namedWindow("Result ab (2)"); cv::imshow("Result ab (2)",result2); // Draw a rectangle around the reference sky area cv::rectangle(color,cv::Rect(0,0,100,45),cv::Scalar(0,0,0)); cv::namedWindow("Color Image"); cv::imshow("Color Image",color); // Get Hue colour histogram hc.setSize(180); // 180 bins colorhist= hc.getHueHistogram(imageROI); // set histogram to be back-projected finder.setHistogram(colorhist); // Convert to HSV space cv::Mat hsv; cv::cvtColor(color, hsv, CV_BGR2HSV); // Get back-projection of hue histogram ch[0]=0; result1= finder.find(hsv,0.0f,180.0f,ch); cv::namedWindow("Result Hue (1)"); cv::imshow("Result Hue (1)",result1); // Second colour image color2= cv::imread("dog.jpg"); // Convert to HSV space cv::cvtColor(color2, hsv, CV_BGR2HSV); // Get back-projection of hue histogram result2= finder.find(hsv,0.0f,180.0f,ch); cv::namedWindow("Result Hue (2)"); cv::imshow("Result Hue (2)",result2); cv::waitKey(); return 0; }
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); /* //创建ColorHistogram 对象 ColorHistogram ch; // load the image Mat image = imread("/Users/Haoyang/Downloads/Pics/waves.jpg"); namedWindow("Origianl"); imshow("Original",image); if(image.data) { // reduce color colorReduce(image,32); // set ROI Mat blueROI = image(Rect(0,0,165,75)); namedWindow("ROI"); imshow("ROI",blueROI); // compute the histogram cv::MatND hist = ch.getColorHistogram(blueROI); // 创建ContentFinder 对象 ContentFinder *finder = new ContentFinder; finder->setHistogram(hist); finder->setThreshold(0.05f); // std::cout << finder->getThreshold() << std::endl; std::cout << finder->getMinValue() << std::endl; std::cout << finder->getMaxValue() << std::endl; // Get back-projection of color histgram cv::Mat result = finder->find(image,finder->getMinValue(), finder->getMaxValue(),finder->getChannels(), 3); namedWindow("Result"); imshow("Result",result); } else std::cerr << "你妹,读文件出错!" << std::endl; */ /*****************************************************************/ /********************** MEAN SHIFT ALGORITHM *********************/ // 读入第一张图片 Mat image1 = imread("/Users/Haoyang/Downloads/Pics/baboon1.jpg"); // 获取脸部,作为ROI Mat image1ROI = image1(Rect(110,260,35,40)); // namedWindow("temp",cv::WINDOW_AUTOSIZE); // imshow("temp",image1ROI); // Get the hue histogram int minSat = 65; ColorHistogram hc; cv::MatND colorhist = hc.getHueHistogram(image1ROI,minSat); ContentFinder *finder = new ContentFinder; // 将得到的脸部的 1D hue histogram作为参数输入, // 用来设置ContentFinder 的私有变量 finder->setHistogram(colorhist); // 打开第二张图像 Mat image2 = imread("/Users/Haoyang/Downlaods/Pics/baboon2.jpg"); // Convert to hsv color space Mat hsv; cv::cvtColor(image2, hsv,CV_BGR2HSV); // split the image std::vector<Mat> v; cv::split(image2,v); // Identify pixels with low saturation cv::threshold(v[1],v[1],minSat,255,cv::THRESH_BINARY); // next, obtain the back-projection of the hue channel of this image // using the previously obtained histogram // Get back - projection of hue histogram, using find method Mat result = finder->find(hsv,0.0f,180,hc.getChannel(),1); // Eliminate low staturation pixels cv::bitwise_and(result,v[1],result); Rect rect(110,260,35,40); cv::rectangle(image2,rect,cv::Scalar(0,0,255)); TermCriteria criteria(TermCriteria::MAX_ITER,10,0.01); // cv::meanShift(result,rect,criteria); cv::meanShift(result,rect,criteria); namedWindow("Result"); imshow("Result",result); return a.exec(); }
int main() { // Read reference image cv::Mat image= cv::imread("../images/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 1"); cv::imshow("Image 1",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); // Second image image= cv::imread("../images/baboon3.jpg"); // Display image cv::namedWindow("Image 2"); cv::imshow("Image 2",image); // 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); // Eliminate low stauration pixels 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; }
void setRefrenceImage(const Mat &image) { reference = hist.colorReduce(image,div); refH = hist.getHistogram(reference); }