cvdistransform.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 1,028 行 · 第 1/3 页
SVN-BASE
1,028 行
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cv.h"
#define MIN2(a, b) MIN((a),(b))
#define CALC_MIN(a, b) if((a) > (b)) (a) = (b)
#define _CV_DIST_SHIFT 18
static int
_MINn( const int *values, int n )
{
int i;
int ret;
ret = values[0];
for( i = 1; i < n; i++ )
{
int t = values[i];
CALC_MIN( ret, t );
}
return ret;
}
static void
init_distances_8uC1( const uchar * pSrc, int srcStep, int *pDst, int dstStep, CvSize roiSize )
{
int ri, ci;
for( ri = 0; ri < roiSize.height; ri++, pSrc += srcStep, pDst += dstStep )
{
/* Convert the feature color to zero and non-feature -- to infinity */
for( ci = 0; ci <= roiSize.width - 4; ci += 4 )
{
int t0 = pSrc[ci] ? (INT_MAX >> 1) : 0;
int t1 = pSrc[ci + 1] ? (INT_MAX >> 1) : 0;
int t2 = pSrc[ci + 2] ? (INT_MAX >> 1) : 0;
int t3 = pSrc[ci + 3] ? (INT_MAX >> 1) : 0;
pDst[ci] = t0;
pDst[ci + 1] = t1;
pDst[ci + 2] = t2;
pDst[ci + 3] = t3;
}
for( ; ci < roiSize.width; ci++ )
{
pDst[ci] = pSrc[ci] > 0 ? (INT_MAX >> 1) : 0;
}
}
}
static void
icvCvtIntTofloat( int *idist, int step, CvSize roiSize, float scale )
{
int ri, ci;
for( ri = 0; ri < roiSize.height; ri++, idist += step )
{
for( ci = 0; ci <= roiSize.width - 4; ci += 4 )
{
float ft0 = scale * idist[ci];
float ft1 = scale * idist[ci + 1];
float ft2 = scale * idist[ci + 2];
float ft3 = scale * idist[ci + 3];
((float *) idist)[ci] = (float) ft0;
((float *) idist)[ci + 1] = (float) ft1;
((float *) idist)[ci + 2] = (float) ft2;
((float *) idist)[ci + 3] = (float) ft3;
}
for( ; ci < roiSize.width; ci++ )
{
((float *) idist)[ci] = (float) (scale * idist[ci]);
}
}
}
#define _IS_VALID(roiSize, row, column)\
(row < 0 || column < 0 || row > roiSize.height - 1\
|| column > roiSize.width - 1) ? 0 : 1
#define VALIDATE_INPUT(img, img_step, dist, step, roiSize)\
if( !img || !dist ) return CV_NULLPTR_ERR;\
if( img_step < roiSize.width || step < roiSize.width*sizeof_float ||\
(step & (sizeof_float-1)) != 0 || roiSize.width < 0 || roiSize.height < 0) \
return CV_BADSIZE_ERR;
IPCVAPI_IMPL( CvStatus, icvDistanceTransform_3x3_8u32f_C1R,
(const uchar * pSrc, int srcStep,
float *pDst, int dstStep, CvSize roiSize, float *pMetrics) )
{
int w = roiSize.width;
int h = roiSize.height;
int *idist = (int *) pDst;
int ri;
int t1, t2, t3, t4;
int mask0, mask1;
float scale;
/* Test input data for validness */
if( !pSrc || !pDst || !pMetrics )
return CV_NULLPTR_ERR;
if( roiSize.width < 0 || roiSize.height < 0 ||
srcStep < roiSize.width || dstStep < roiSize.width * sizeof_float ||
(dstStep & (sizeof_float - 1)) != 0 )
return CV_BADSIZE_ERR;
dstStep /= sizeof_float;
mask0 = cvRound( pMetrics[0] * (1 << _CV_DIST_SHIFT) );
mask1 = cvRound( pMetrics[1] * (1 << _CV_DIST_SHIFT) );
scale = (float) (1. / (1 << _CV_DIST_SHIFT));
init_distances_8uC1( pSrc, srcStep, idist, dstStep, roiSize );
if( w == 1 )
{
int ri;
/* Forward mask */
/* ri = 0: do nothing */
/* 0 < ri < h */
for( ri = 1, idist += dstStep; ri < h; ri++, idist += dstStep )
{
t1 = idist[0];
t2 = idist[-dstStep] + mask0;
CALC_MIN( t1, t2 );
idist[0] = t1;
}
/* Backward mask */
/* ri = h - 1: do nothing */
/* h - 1 > ri >= 0 */
for( ri = h - 2, idist -= 2 * dstStep; ri >= 0; ri--, idist -= dstStep )
{
t1 = idist[0];
t2 = idist[dstStep] + mask0;
CALC_MIN( t1, t2 );
idist[0] = t1;
}
idist += dstStep;
}
else
{
int ci;
/* ____________ Forward mask _______________ */
/* ci = 0: do nothing */
/* 0 < ci < w */
for( ci = 1; ci < w; ci++ )
{
t1 = idist[ci];
t2 = idist[ci - 1] + mask0;
CALC_MIN( t1, t2 );
idist[ci] = t1;
}
if( h > 1 )
{
for( ri = 1, idist += dstStep; ri < h; ri++, idist += dstStep )
{
int *idist2 = idist - dstStep;
/* ci = 0 */
t1 = idist[0];
t2 = idist2[0] + mask0;
CALC_MIN( t1, t2 );
t2 = idist2[1] + mask1;
CALC_MIN( t1, t2 );
idist[0] = t1;
/* 0 < ci < w - 1 */
for( ci = 1; ci < w - 1; ci++ )
{
t1 = idist[ci];
t2 = idist[ci - 1] + mask0;
CALC_MIN( t1, t2 );
t3 = idist2[ci] + mask0;
t4 = idist2[ci - 1] + mask1;
CALC_MIN( t3, t4 );
t2 = idist2[ci + 1] + mask1;
CALC_MIN( t1, t3 );
CALC_MIN( t1, t2 );
idist[ci] = t1;
}
/* ci = w - 1 */
t1 = idist[ci];
t2 = idist[ci - 1] + mask0;
CALC_MIN( t1, t2 );
t2 = idist2[ci - 1] + mask1;
CALC_MIN( t1, t2 );
t2 = idist2[ci] + mask0;
CALC_MIN( t1, t2 );
idist[ci] = t1;
}
idist -= dstStep;
}
/* ____________ Backward mask _______________ */
/* ci = w - 1: do nothing */
/* w - 1 > ci >= 0 */
for( ci = w - 2; ci >= 0; ci-- )
{
t1 = idist[ci];
t2 = idist[ci + 1] + mask0;
CALC_MIN( t1, t2 );
idist[ci] = t1;
}
if( h > 1 )
{
/* 0 <= ri < h - 1 */
for( ri = h - 2, idist -= dstStep; ri >= 0; ri--, idist -= dstStep )
{
int *idist2 = idist + dstStep;
/* ci = w - 1 */
t1 = idist[w - 1];
t2 = idist2[w - 1] + mask0;
CALC_MIN( t1, t2 );
t2 = idist2[w - 2] + mask1;
CALC_MIN( t1, t2 );
idist[w - 1] = t1;
/* 0 < ci < w - 1 */
for( ci = w - 2; ci > 0; ci-- )
{
t1 = idist[ci];
t2 = idist[ci + 1] + mask0;
CALC_MIN( t1, t2 );
t3 = idist2[ci] + mask0;
t4 = idist2[ci - 1] + mask1;
CALC_MIN( t3, t4 );
t2 = idist2[ci + 1] + mask1;
CALC_MIN( t1, t3 );
CALC_MIN( t1, t2 );
idist[ci] = t1;
}
/* ci = 0 */
t1 = idist[0];
t2 = idist[1] + mask0;
CALC_MIN( t1, t2 );
t2 = idist2[0] + mask0;
CALC_MIN( t1, t2 );
t2 = idist2[1] + mask1;
CALC_MIN( t1, t2 );
idist[0] = t1;
}
idist += dstStep;
}
}
assert( idist == (int *) pDst );
icvCvtIntTofloat( idist, dstStep, roiSize, scale );
return CV_OK;
}
#define _F2I(i, f) (i) = (f);
#define _I2F(f, i) (f) = (i);
#define _POINT(row, column) (((int*)pDst)[(row)*dstStep+(column)])
#define _ADD_POINT(row, column, m)\
buffer[length++] = ((int*)pDst)[dstStep*(row) + (column)] + (m)
IPCVAPI_IMPL( CvStatus, icvDistanceTransform_5x5_8u32f_C1R,
(const uchar * pSrc, int srcStep,
float *pDst, int dstStep, CvSize roiSize, float *pMetrics) )
{
int ri; /* Row index */
int ci; /* Column index */
int w = roiSize.width;
int h = roiSize.height;
int t1, t2;
int *d;
int buffer[13];
int length;
int offset;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?