www.pudn.com > colortracker.rar > cvHistWrapper.cpp


#include "cvHistWrapper.h" 
#include  
#include  
#include "Images/color.h" 
#include "Images/imageio.h" 
 
using namespace std; 
 
MPColorTools m_colorTools; 
MPImageIO m_imageIO; 
 
/* ================================================================ */ 
 
void cvHistWrapper::update_back_project( const IplImage* cur_frame ) {   
	 
	CvSize size = cvGetSize(cur_frame); 
	if (m_log_back_project.width != size.width || m_log_back_project.height != size.height) 
		m_log_back_project.setSize(size.width, size.height); 
	 
	 
	uchar* data = 0;       
	uchar* color_data = 0; 
	int x, y, color_step = 0, plane_step = 0; 
	int dims, histsize[CV_MAX_DIM];   
	dims = cvGetDims( m_hist->bins, histsize ); 
	 
	cvReleaseImage( &m_temp ); 
	m_temp = cvCreateImage( size, IPL_DEPTH_8U, 3 ); 
	 
	cvCvtColor( cur_frame, m_temp, CV_BGR2HSV ); 
	cvGetRawData( m_temp, &color_data, &color_step, &size ); 
	 
	for(y=0 ; size.height--; y++, color_data += color_step) 
	{ 
		for( x = 0; x < size.width; x++ ) 
		{ 
			int val0 = color_data[x*3]; 
			int val1 = color_data[x*3+1]; 
			int val2 = color_data[x*3+2]; 
			if( m_min_ch_val[0] <= val0 && val0 <= m_max_ch_val[0] && 
				m_min_ch_val[1] <= val1 && val1 <= m_max_ch_val[1] && 
				m_min_ch_val[2] <= val2 && val2 <= m_max_ch_val[2] ) { 
				double prob = cvQueryHistValue_1D( m_hist, m_histlookuptable[val0]); 
				m_log_back_project.setPixel(x, y, prob); 
			} else { 
				static float minVal = 0.0; 
				cvGetMinMaxHistValue( m_hist, &minVal, 0 ); 
				m_log_back_project.setPixel(x, y, minVal); 
			} 
		} 
	} 
} 
 
/* ================================================================ */ 
 
void cvHistWrapper::create_lookup_table(int *tab, CvHistogram* hist) { 
	int dims, histsize[CV_MAX_DIM];   
	dims = cvGetDims( hist->bins, histsize ); 
	 
	int step = ((CvMatND*)(hist->bins))->dim[0].step/sizeof(float); 
	 
	int is_sparse = CV_IS_SPARSE_HIST( hist ); 
	int have_range = CV_HIST_HAS_RANGES(hist); 
	 
	double a = have_range ? hist->thresh[0][0] : 0; 
	double b = have_range ? hist->thresh[0][1] : 256; 
	 
	double scale = histsize[0]/(b-a), cur = 0; 
	for (int i = 0; i < 256; i++) { 
		int idx = cvFloor(cur); 
		if ((unsigned)idx < histsize[0]) 
			idx *= step; 
		else 
			idx = -1;//ICV_HIST_DUMMY_IDX; 
		 
		tab[i] = idx; 
		cur += scale; 
	} 
} 
 
/* ================================================================ */ 
 
bool cvHistWrapper::update_histogram( const IplImage* cur_frame ) { 
	int i; 
	int dims, histsize[CV_MAX_DIM];   
	dims = cvGetDims( m_hist->bins, histsize ); 
	bool status = CvCamShiftTracker::update_histogram( cur_frame ); 
	 
	cvNormalizeHist( m_hist, 1.0 ); 
	 
	const double uniform = 1.0/histsize[0]; 
	const double alpha = .9999999999; 
 
	/* TODO: should adding uniform to protect against log(0) error be done like this? */ 
	for (i = 0; i < histsize[0]; i++) { 
		float *val = cvGetHistValue_1D( m_hist, i ); 
		*val = alpha*(*val) + (1-alpha)*uniform; 
	} 
 
	const double expBoostWeight = 1.0; /* bad idea to use anything higher than 1 */ 
 
	if (m_expBoost) { 
		for (i = 0; i < histsize[0]; i++) { 
			float *val = cvGetHistValue_1D( m_hist, i ); 
			*val = exp(expBoostWeight * *val); 
		} 
		cvNormalizeHist( m_hist, 1.0 ); 
	} 
	 
 
	/* TODO: use a separate histogram to store log prob ratio */ 
	for (i = 0; i < histsize[0]; i++) { 
		float *val = cvGetHistValue_1D( m_hist, i ); 
		*val = log(*val) - log(uniform); 
	} 
	 
	create_lookup_table(m_histlookuptable, m_hist); 
 
	FILE *fid = fopen("hist.txt", "w"); 
	for (i = 0; i < histsize[0]; i++) { 
		float *val = cvGetHistValue_1D( m_hist, i ); 
		fprintf(fid, "%g\n", *val); 
	} 
	fclose(fid); 
	 
	return(status); 
} 
 
/* ================================================================ */ 
 
void cvHistWrapper::process(MPImageWrapper & imageWrapper, const long int & frameNum, MPKeyFrameCollection *collection) { 
	unsigned char*   pData = imageWrapper.rgbimage; 
	IplImage image; 
	CvSize size = cvSize( imageWrapper.width, imageWrapper.height ); 
	int stride = (size.width * 3 + 3) & -4; 
	cvInitImageHeader( &image, size, IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); 
	cvSetImageData( &image, pData, stride ); 
	 
	static const float m_params_x = 0.4f;  
	static const float m_params_y = 0.3f; 
	static const float m_params_width = 0.2f; 
	static const float m_params_height = 0.3f; 
	static const int m_params_Smin = 20; 
	static const int m_params_Vmin = 40; 
	static const int m_params_Vmax = 255; 
	static const int m_params_bins = 20; 
	static const int m_params_view = 0; 
	static const int m_params_threshold = 0; 
	 
	long fn = -1; 
	int x = 0, y = 0, w = 0, h = 0; 
	for (int s = 0; s < collection->size(); s++) { 
		collection->get_keyframe(fn, x, y, w, h, s); 
		if (frameNum == fn) { 
			m_object.x = x; 
			m_object.y = y; 
			m_object.width = w; 
			m_object.height = h; 
			break; 
		} 
	} 
	 
	{ 
		IplImage* _image = ℑ 
		CvSize size; 
		int bins = m_params_bins; 
		set_hist_dims( 1, &bins ); 
		set_hist_bin_range( 0, 0, 180 ); 
		set_threshold( 0 ); 
		set_min_ch_val( 1, m_params_Smin ); 
		set_max_ch_val( 1, 255 ); 
		set_min_ch_val( 2, m_params_Vmin ); 
		set_max_ch_val( 2, m_params_Vmax ); 
		cvGetImageRawData( _image, 0, 0, &size ); 
		 
		if( m_object.x < 0 ) m_object.x = 0; 
		if( m_object.x > size.width - m_object.width - 1 ) 
			m_object.x = MAX(0, size.width - m_object.width - 1); 
		if( m_object.y < 0 ) m_object.y = 0; 
		if( m_object.y > size.height - m_object.height - 1 ) 
			m_object.y = MAX(0, size.height - m_object.height - 1); 
		if( m_object.width > size.width - m_object.x ) 
			m_object.width = MIN(size.width, size.width - m_object.x); 
		if( m_object.height > size.height - m_object.y ) 
			m_object.height = MIN(size.height, size.height - m_object.y); 
		 
		set_window(m_object); 
		 
		if (frameNum == fn) { 
			reset_histogram(); 
			update_histogram( _image ); 
		} 
		update_back_project( _image ); 
	} 
} 
 
/* ================================================================ */ 
	 
void cvHistWrapper::set_expBoost(const bool val) { 
	m_expBoost = val; 
} 
 
/* ================================================================ */