OpenCV2 cookbook source code analyse - histogram match

原创 2013年12月04日 22:07:00

1.  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

 

2.  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


 

 

3.  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("C:/images/baboon1.jpg");
	if (!image.data)
		return 0;
 
        // 从image中得到一块ROI区域, 并用红色在image上用红色标出ROI
   	// 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));
        
        // 显示image及其标出的ROI(红色方框)
	// Display image
   	cv::namedWindow("Image");
	cv::imshow("Image",image);
 
        // 得到imageROI的色度直方图
	// Get the Hue histogram
	int minSat=65;
	ColorHistogram hc;
	// cv::MatND colorhist= hc.getHueHistogram(imageROI, minSat);
	cv::MatND colorhist= hc.getHueHistogram(imageROI);

	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);
 
        //v[0] - Hue,  v[1] - Saturation,  v[2] - Value
	// 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("C:/images/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;
}



 

OpenCV2 cookbook source code analyse - histogram

Histogram.h   #if !defined HISTOGRAM #define HISTOGRAM #include #include class Histogram1D {     ...
  • fanbird2008
  • fanbird2008
  • 2013年12月04日 21:56
  • 851

sources code does not match the bytecode

项目中在下载压缩包时出错,debug提示sources code does not match the bytecode 最终解决办法: 删除.gradle中对应项目使用版本下的cache,重新b...
  • Poulfei
  • Poulfei
  • 2017年08月19日 15:57
  • 2565

debug显示 'Source code does not match the bytecode' 解决方法

最近用intelliJ IDEA 调试代码时显示Source code does not match the byte code。 后来解决方法是 重新编译所有的项目,在进行debug 。 或者点击...
  • harryptter
  • harryptter
  • 2017年03月03日 10:22
  • 4942

OpenCV 2 Computer Vision Application Programming Cookbook

学习opencv感觉过时了,而且与看文档没有什么区别。 最近发现一本非常好的关于opnecv的书,很实用,基于opencv2,c++实现。 书名: OpenCV 2 Computer Vision...
  • vsooda
  • vsooda
  • 2012年06月01日 16:49
  • 4320

java线程中异常的处理 -Java 7 Concurrency Cookbook 读书笔记

java线程中异常的处理Processing uncontrolled exceptions in a thread  *       There are two kinds...
  • doctor_who2004
  • doctor_who2004
  • 2015年11月01日 09:53
  • 578

Android Studio Project debug library show source code does not match the bytecode

最近接手了一些新的工程,里面用android studio调试library。在调试的时候 会发现调用某些接口的时候 ide 提示:source code does not match the byt...
  • autumn_xl
  • autumn_xl
  • 2016年12月21日 19:45
  • 7574

Program for Android in C/C++ with the Native Development Kit (if you dare)

Not a big fan of Java? Well, get over it, because that’s the primary and recommended way to write ap...
  • colinchan
  • colinchan
  • 2010年08月27日 12:11
  • 1521

LLVM Cookbook读书笔记(本书的缺点是直接展示大量Sample代码,对SSA/phi并没有怎么解释,TableGen部分也没讲清楚)

LLVM Cookbook(Packt,2015) *重新理解 value --> use(每个IR就是一个value,SSA)builder.GetInsertBlock();...
  • cteng
  • cteng
  • 2015年08月26日 16:44
  • 2655

IDEA查看源码时提示:Library source does not match the bytecode for class的问题分析

通过Maven查看依赖的源码时,通常是Maven自动下载JAR包附属的source包,但是会出现一个问题,由于使用lombok插件会造成编写的Java文件和编译后的class上有差别,所以IDEA打开...
  • LOVE____JAVA
  • LOVE____JAVA
  • 2017年12月26日 19:21
  • 251

Source code does not match the bytecode

最近开始使用idea 因为其强大的功能而抛弃了最喜欢的eclipse,使用时遇到了很多问题,择其中一些分享给大家: 使用idea时,有很方便的一点就是在对java类文件改动时不需要重新部署debu...
  • weixin_38508261
  • weixin_38508261
  • 2017年09月18日 17:05
  • 281
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenCV2 cookbook source code analyse - histogram match
举报原因:
原因补充:

(最多只允许输入30个字)