📄 colourmodel.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 + -