您的位置:首页 > 其它

cvCalcBackProject-直方图反向投影

2009-11-25 22:21 309 查看
CV_IMPL void
cvCalcArrBackProject( CvArr** img, CvArr* dst, const CvHistogram* hist )//输入为单通道的图像,输出为反向投影图形,hist为直方图数据结构
{
CV_FUNCNAME( "cvCalcArrBackProject" );

__BEGIN__;

uchar* ptr[CV_MAX_DIM];
uchar* dstptr = 0;
int dststep = 0, step = 0;
int i, dims;
int cont_flag = -1;
CvMat stub0, *mat0 = 0;
CvSize size;

if( !CV_IS_HIST(hist))
CV_ERROR( CV_StsBadArg, "Bad histogram pointer" );

if( !img )
CV_ERROR( CV_StsNullPtr, "Null double array pointer" );

CV_CALL( dims = cvGetDims( hist->bins ));

for( i = 0; i <= dims; i++ )
{
CvMat stub, *mat = (CvMat*)(i < dims ? img[i] : dst);
CV_CALL( mat = cvGetMat( mat, i == 0 ? &stub0 : &stub, 0, 1 ));//返回矩阵头,对于iplimage和cvmat类型返回值不同

if( CV_MAT_CN( mat->type ) != 1 )
CV_ERROR( CV_BadNumChannels, "Only 1-channel arrays are allowed here" );

if( i == 0 )
{
mat0 = mat;
step = mat0->step;
}
else
{
if( !CV_ARE_SIZES_EQ( mat0, mat ))
CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal sizes" );

if( mat0->step != mat->step )
CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal steps" );

if( !CV_ARE_TYPES_EQ( mat0, mat ))
CV_ERROR( CV_StsUnmatchedFormats, "Not all the planes have equal types" );
}

cont_flag &= mat->type;
if( i < dims )
ptr[i] = mat->data.ptr;
else
{
dstptr = mat->data.ptr; //输出指针
dststep = mat->step;
}
}

size = cvGetMatSize(mat0);
if( CV_IS_MAT_CONT( cont_flag ))
{
size.width *= size.height;
size.height = 1;
dststep = step = CV_STUB_STEP;
}

if( CV_MAT_DEPTH(mat0->type) > CV_8S && !CV_HIST_HAS_RANGES(hist))
CV_ERROR( CV_StsBadArg, "histogram ranges must be set (via cvSetHistBinRanges) "
"before calling the function" );

switch( CV_MAT_DEPTH(mat0->type) )
{
case CV_8U:
IPPI_CALL( icvCalcBackProject_8u_C1R( ptr, step, dstptr, dststep, size, hist ));
break;
case CV_32F:
{
union { uchar** ptr; float** fl; } v;
v.ptr = ptr;
IPPI_CALL( icvCalcBackProject_32f_C1R( v.fl, step,
(float*)dstptr, dststep, size, hist ));
}
break;
default:
CV_ERROR( CV_StsUnsupportedFormat, "Unsupported array type" );
}

__END__;
}

static CvStatus CV_STDCALL
icvCalcBackProject_8u_C1R( uchar** img, int step, uchar* dst, int dstStep,
CvSize size, const CvHistogram* hist )
{
const int small_hist_size = 1<<12;
int* tab = 0;
int is_sparse = CV_IS_SPARSE_HIST(hist);
int dims, histsize[CV_MAX_DIM];
int i, x;
CvStatus status;

dims = cvGetDims( hist->bins, histsize );

tab = (int*)cvStackAlloc( dims*256*sizeof(int));
status = icvCalcHistLookupTables8u( hist, dims, histsize, tab );
if( status < 0 )
return status;

if( !is_sparse )
{
int total = 1;
CvMatND* mat = (CvMatND*)(hist->bins);
float* bins = mat->data.fl;
uchar* buffer = 0;

for( i = 0; i < dims; i++ )
total *= histsize[i];

if( dims <= 3 && total >= -ICV_HIST_DUMMY_IDX )
return CV_BADSIZE_ERR; // too big histogram

if( dims > 1 && total <= small_hist_size && CV_IS_MAT_CONT(mat->type))
{
buffer = (uchar*)cvAlloc(total);
if( !buffer )
return CV_OUTOFMEM_ERR;
for( i = 0; i < total; i++ )
{
int v = cvRound(bins[i]);
buffer[i] = CV_CAST_8U(v);
}
}

switch( dims )
{
case 1:
{
uchar tab1d[256];
for( i = 0; i < 256; i++ )
{
int idx = tab[i];
if( idx >= 0 )
{
int v = cvRound(bins[idx]);
tab1d[i] = CV_CAST_8U(v);
}
else
tab1d[i] = 0;
}

for( ; size.height--; img[0] += step, dst += dstStep )
{
uchar* ptr = img[0];
for( x = 0; x <= size.width - 4; x += 4 )
{
uchar v0 = tab1d[ptr[x]];
uchar v1 = tab1d[ptr[x+1]];

dst[x] = v0;
dst[x+1] = v1;

v0 = tab1d[ptr[x+2]];
v1 = tab1d[ptr[x+3]];

dst[x+2] = v0;
dst[x+3] = v1;
}

for( ; x < size.width; x++ )
dst[x] = tab1d[ptr[x]];
}
}
break;
case 2:
for( ; size.height--; img[0] += step, img[1] += step, dst += dstStep )
{
uchar* ptr0 = img[0];
uchar* ptr1 = img[1];

if( buffer )
{
for( x = 0; x < size.width; x++ )
{
int v0 = ptr0[x];
int v1 = ptr1[x];
int idx = tab[v0] + tab[256+v1];
int v = 0;

if( idx >= 0 )
v = buffer[idx];

dst[x] = (uchar)v;
}
}
else
{
for( x = 0; x < size.width; x++ )
{
int v0 = ptr0[x];
int v1 = ptr1[x];
int idx = tab[v0] + tab[256+v1];
int v = 0;

if( idx >= 0 )
{
v = cvRound(bins[idx]);
v = CV_CAST_8U(v);
}

dst[x] = (uchar)v;
}
}
}
break;
case 3:
for( ; size.height--; img[0] += step, img[1] += step,
img[2] += step, dst += dstStep )
{
uchar* ptr0 = img[0];
uchar* ptr1 = img[1];
uchar* ptr2 = img[2];

if( buffer )
{
for( x = 0; x < size.width; x++ )
{
int v0 = ptr0[x];
int v1 = ptr1[x];
int v2 = ptr2[x];
int idx = tab[v0] + tab[256+v1] + tab[512+v2];
int v = 0;

if( idx >= 0 )
v = buffer[idx];

dst[x] = (uchar)v;
}
}
else
{
for( x = 0; x < size.width; x++ )
{
int v0 = ptr0[x];
int v1 = ptr1[x];
int v2 = ptr2[x];
int idx = tab[v0] + tab[256+v1] + tab[512+v2];
int v = 0;

if( idx >= 0 )
{
v = cvRound(bins[idx]);
v = CV_CAST_8U(v);
}
dst[x] = (uchar)v;
}
}
}
break;
default:
for( ; size.height--; dst += dstStep )
{
if( buffer )
{
for( x = 0; x < size.width; x++ )
{
uchar* binptr = buffer;
int v = 0;

for( i = 0; i < dims; i++ )
{
int idx = tab[i*256 + img[i][x]];
if( idx < 0 )
break;
binptr += idx;
}

if( i == dims )
v = binptr[0];

dst[x] = (uchar)v;
}
}
else
{
for( x = 0; x < size.width; x++ )
{
float* binptr = bins;
int v = 0;

for( i = 0; i < dims; i++ )
{
int idx = tab[i*256 + img[i][x]];
if( idx < 0 )
break;
binptr += idx;
}

if( i == dims )
{
v = cvRound( binptr[0] );
v = CV_CAST_8U(v);
}

dst[x] = (uchar)v;
}
}

for( i = 0; i < dims; i++ )
img[i] += step;
}
}

cvFree( &buffer );
}
else
{
CvSparseMat* mat = (CvSparseMat*)(hist->bins);
int node_idx[CV_MAX_DIM];

for( ; size.height--; dst += dstStep )
{
for( x = 0; x < size.width; x++ )
{
int v = 0;

for( i = 0; i < dims; i++ )
{
int idx = tab[i*256 + img[i][x]];
if( idx < 0 )
break;
node_idx[i] = idx;
}
if( i == dims )
{
float* bin = (float*)cvPtrND( mat, node_idx, 0, 1, 0 );
v = cvRound(bin[0]);
v = CV_CAST_8U(v);
}

dst[x] = (uchar)v;
}

for( i = 0; i < dims; i++ )
img[i] += step;
}
}

return CV_OK;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: