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; } /* ================================================================ */