⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 colourmodel.cpp

📁 基于均值漂移理论的该进算法
💻 CPP
字号:
//colourModel.cpp - the colourModel object
//Iain Wallace 16/08/05

//Modified by xdb 2007-03-19
#include "stdafx.h"
#include "colourModel.h"
#include <math.h>
#include <iostream>
//using namespace cimg_library;
using namespace std;
colourModel::colourModel()
{
	//model must be initialised to 0
	memset( m_model, '\0', sizeof(m_model) );
	//Se we can tell if the memory's been allocated
	binsInit = false;
}
colourModel::~colourModel()
{
	//Free the bins memory, if it's assigned.
	if (binsInit)
	{
		if( bins != NULL )
		{
			for (unsigned int i=0; i< mX_dim; i++)
			{
				if( bins[i] != NULL )
					delete[] bins[i];
			}
			delete[] bins;
		}
		bins = NULL;
		binsInit = false;
		memset( m_model, '\0', sizeof(m_model) );
	}
}
double colourModel::operator[](unsigned int bin)
{
	//Use GTE as index is from 0
	if (bin >= NUMBINS)
	{
		cerr << "ERROR! Tried to access a model bin that doesn't exit!" << endl;
		return 0;
	}
	return m_model[bin];
}
unsigned int colourModel::findBin(unsigned char R,unsigned char G,unsigned char B)
{
	//return the bin number of a pixel according to its RGB value.
	//Note that the constants defined in the header file, and this function
	//control the only real tuning of the tracker.
	//scale the colours
	unsigned int r,g,b;
	r = (unsigned int)floor( (float)(R/BINSIZE) );
	g = (unsigned int)floor( (float)(G/BINSIZE) );
	b = (unsigned int)floor( (float)(B/BINSIZE) );
	//If, for example, the blue channel is not to be used, then change for:
	//b = 0;
	return (r + BPC*g + BPC*BPC*b);
}
void colourModel::clearModel()
{
	memset( m_model, '\0', sizeof(m_model) );
}

//This performs the function described by eqn(2) and eqn(4) (effectively the same)
//It saves the bin that each pixel is allocated too, as this prevents it being
//re-calculated when the weights are updated.
//void colourModel::updateModel(cimg_library::CImg<unsigned char>* image, //The image in question
//							  unsigned int centreX, //X co-ord of centre
//							  unsigned int centreY, //Y co-ord of centre
//							  int half_x, //half the x-size of the window
//							  int half_y, //half the y-size of the window
//							  double*** kArray) //the kernel
//{
//	clearModel();
//	//first time this is called, create bins with the size of the window
//	//NOTE: more cunning memory management would be required for reszizing windows!
//	if (!binsInit)
//	{
//		cout << "Allocating a bin allocation table" << endl;
//		//allocate the memory
//		mX_dim = 2*half_x+1;
//		mY_dim = 2*half_y+1;
//		bins = new unsigned int*[mX_dim];
//		for (unsigned int i=0;i<mX_dim;++i)
//			bins[i] = new unsigned int[mY_dim];
//		binsInit = true;
//	}
//	for (int x = -half_x;x <= half_x;++x)
//	{
//		for (int y = -half_y;y <= half_y;++y)
//		{
//			//update the bin allocation table at the same time
//			int iX = centreX + x;
//			int iY = centreY + y;
//			bins[x+half_x][y+half_y] = findBin((*image)(iX,iY,0),(*image)(iX,iY,1),(*image)(iX,iY,2));
//			//adding on the kernel function, instead of summing like a regular histogram,
//			//accounts for the delta function in the eqns.
//			m_model[bins[x+half_x][y+half_y]]+= (*kArray)[x+half_x][y+half_y];
//		}
//	}
//	//The model values must by normalised.
//	double total = 0;
//	for (int i = 0;i< NUMBINS;++i)
//	{
//		total += m_model[i];
//	}
//	for (int i = 0;i< NUMBINS;++i)
//	{
//		m_model[i] /= total;
//	}
//}

// Modified by xdb, 2007-03-19
// Because the first parameter in the origin function is CImag type. 
// So I override it using data area of image file to replace the first paramerter.

void colourModel::updateModel(BYTE* image, //The image in question
							  unsigned int centreX, //X co-ord of centre
							  unsigned int centreY, //Y co-ord of centre
							  int half_x, //half the x-size of the window
							  int half_y, //half the y-size of the window
							  double*** kArray, //the kernel
							  UINT bytesPerLine)	//Bytes per line
{	
	clearModel();
	//first time this is called, create bins with the size of the window
	//NOTE: more cunning memory management would be required for reszizing windows!
	if (!binsInit)
	{
		cout << "Allocating a bin allocation table" << endl;
		//allocate the memory
		mX_dim = 2*half_x+1;
		mY_dim = 2*half_y+1;
		bins = new unsigned int*[mX_dim];
		ZeroMemory(bins, mX_dim * sizeof(UINT));
		for (unsigned int i=0;i<mX_dim; i++)
		{
			bins[i] = new unsigned int[mY_dim];
			ZeroMemory(bins[i], mY_dim * sizeof(UINT));
		}
		binsInit = true;
	}
/*	for (int x = -half_x;x <= half_x;++x)
	{
		for (int y = -half_y;y <= half_y;++y)
		{
			//update the bin allocation table at the same time
			int iX = centreX + x;
			int iY = centreY + y;
			bins[x+half_x][y+half_y] = findBin((*image)(iX,iY,0),(*image)(iX,iY,1),(*image)(iX,iY,2));
			//adding on the kernel function, instead of summing like a regular histogram,
			//accounts for the delta function in the eqns.
			m_model[bins[x+half_x][y+half_y]]+= (*kArray)[x+half_x][y+half_y];
		}
	}*/

	//I modified the section because it not read data by consective address, I think the x represents width,
	// and y represents height. The followed is modfied code. 2007-03-19
	int m, n, x, y;
	m = n = x = y = 0;
	for( y = -half_y + int( centreY); y > 0, y < half_y + int(centreY); y++, m++ )
	{
		int p = y * bytesPerLine;
		for( x = -half_x + int(centreX),p += 3 * x, n = 0; x > 0 && x< half_x + int(centreX); x++, n++, p += 3 )
		{			
			BYTE b = *( image + p );
			BYTE g = *( image + p + 1 );
			BYTE r = *( image + p + 2);					
			UINT tmp = findBin(b, g, r);
			bins[n][m] = tmp;	
			//adding on the kernel function, instead of summing like a regular histogram,
			//accounts for the delta function in the eqns.
			m_model[tmp]+= (*kArray)[n][m];
		}

	}

	//The model values must by normalised.
	double total = 0;
	for (int i = 0;i< NUMBINS; i++)
	{
		total += m_model[i];	
	}
	for (int i = 0;i< NUMBINS; i++)
	{
		if( total == 0)
			m_model[i] = 0;
		else
			m_model[i] /= total;
	}
}
unsigned int colourModel::theBin(unsigned int x, unsigned int y)
{
	if ((x >= mX_dim) || (y >= mY_dim) || (!binsInit))
	{
		cerr << "ERROR! Attempted to access a pixel out of the window!" << endl;
		return( 0);
	}
	else
	{
		return(bins[x][y]);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -