cvtemplmatch.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 1,915 行 · 第 1/5 页
SVN-BASE
1,915 行
/*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"
/* calculate sizes of temporary buffers */
static void
icvCalculateBufferSizes( CvSize roiSize, CvSize templSize,
CvDataType dataType,
int is_centered, int is_normed,
int *imgBufSize, int *templBufSize,
int *sumBufSize, int *sqsumBufSize,
int *resNumBufSize, int *resDenomBufSize )
{
int depth = dataType == cv32f ? sizeof_float : 1;
#define align(size) icvAlign((int)(size) + 16, 32)
*imgBufSize = align( (templSize.width * roiSize.height + roiSize.width) * depth );
*templBufSize = align( templSize.width * templSize.height * depth );
*resNumBufSize = align( (roiSize.height - templSize.height + 1) * sizeof( double ));
if( is_centered || is_normed )
{
*sumBufSize = align( roiSize.height * sizeof( double ));
*sqsumBufSize = align( roiSize.height * sizeof( double ));
*resDenomBufSize = align( (roiSize.height - templSize.height + 1) *
(is_centered + is_normed) * sizeof( double ));
}
#undef align
}
static CvStatus
icvMatchTemplateEntry( const void *pImage, int imageStep,
CvSize roiSize,
const void *pTemplate, int templStep,
CvSize templSize,
float *pResult, int resultStep,
void *pBuffer, CvDataType dataType,
int is_centered, int is_normed,
void **imgBuf, void **templBuf,
void **sumBuf, void **sqsumBuf, void **resNum, void **resDenom )
{
int templBufSize = 0,
imgBufSize = 0,
sumBufSize = 0, sqsumBufSize = 0, resNumBufSize = 0, resDenomBufSize = 0;
int depth = dataType == cv32f ? 4 : 1;
int i;
char *buffer = (char *) pBuffer;
if( !pImage || !pTemplate || !pResult || !pBuffer )
return CV_NULLPTR_ERR;
if( templSize.width <= 0 || templSize.height <= 0 ||
roiSize.width < templSize.width || roiSize.height < templSize.height )
return CV_BADSIZE_ERR;
if( templStep < templSize.width * depth ||
imageStep < roiSize.width * depth ||
resultStep < (roiSize.width - templSize.width + 1) * sizeof_float )
return CV_BADSIZE_ERR;
if( (templStep & (depth - 1)) != 0 ||
(imageStep & (depth - 1)) != 0 || (resultStep & (sizeof_float - 1)) != 0 )
return CV_BADSIZE_ERR;
icvCalculateBufferSizes( roiSize, templSize, dataType,
is_centered, is_normed,
&imgBufSize, &templBufSize,
&sumBufSize, &sqsumBufSize, &resNumBufSize, &resDenomBufSize );
*templBuf = buffer;
buffer += templBufSize;
*imgBuf = buffer;
buffer += imgBufSize;
*resNum = buffer;
buffer += resNumBufSize;
if( is_centered || is_normed )
{
if( sumBuf )
*sumBuf = buffer;
buffer += sumBufSize;
if( sqsumBuf )
*sqsumBuf = buffer;
buffer += sqsumBufSize;
if( resDenom )
*resDenom = buffer;
buffer += resDenomBufSize;
}
for( i = 0; i < roiSize.height; i++ )
{
memcpy( (char *) *imgBuf + i * templSize.width * depth,
(char *) pImage + i * imageStep, templSize.width * depth );
}
for( i = 0; i < templSize.height; i++ )
{
memcpy( (char *) *templBuf + i * templSize.width * depth,
(char *) pTemplate + i * templStep, templSize.width * depth );
}
return CV_OK;
}
/****************************************************************************************\
* External functions' implementation *
\****************************************************************************************/
/****************************************************************************************\
* 8u flavor *
\****************************************************************************************/
/* --------------------------------------- SqDiff ------------------------------------- */
IPCVAPI_IMPL( CvStatus, icvMatchTemplate_SqDiff_8u32f_C1R,
(const uchar * pImage, int imageStep, CvSize roiSize,
const uchar * pTemplate, int templStep, CvSize templSize,
float *pResult, int resultStep, void *pBuffer) )
{
uchar *imgBuf = 0;
uchar *templBuf = 0;
int64 *resNum = 0;
int winLen = templSize.width * templSize.height;
CvSize resultSize = cvSize( roiSize.width - templSize.width + 1,
roiSize.height - templSize.height + 1 );
int x, y;
CvStatus result = icvMatchTemplateEntry( pImage, imageStep, roiSize,
pTemplate, templStep, templSize,
pResult, resultStep, pBuffer,
cv8u, 0, 0,
(void **) &imgBuf, (void **) &templBuf,
0, 0, (void **) &resNum, 0 );
if( result != CV_OK )
return result;
resultStep /= sizeof_float;
/* main loop - through x coordinate of the result */
for( x = 0; x < resultSize.width; x++ )
{
uchar *imgPtr = imgBuf + x;
/* update sums and image band buffer */
if( x > 0 )
{
const uchar *src = pImage + x + templSize.width - 1;
uchar *dst = imgPtr - 1;
dst += templSize.width;
for( y = 0; y < roiSize.height; y++, src += imageStep, dst += templSize.width )
{
dst[0] = src[0];
}
}
for( y = 0; y < resultSize.height; y++, imgPtr += templSize.width )
{
int64 res = icvCmpBlocksL2_8u_C1( imgPtr, templBuf, winLen );
resNum[y] = res;
}
for( y = 0; y < resultSize.height; y++ )
{
pResult[x + y * resultStep] = (float) resNum[y];
}
}
return CV_OK;
}
/* ----------------------------------- SqDiffNormed ----------------------------------- */
IPCVAPI_IMPL( CvStatus, icvMatchTemplate_SqDiffNormed_8u32f_C1R,
(const uchar * pImage, int imageStep, CvSize roiSize,
const uchar * pTemplate, int templStep, CvSize templSize,
float *pResult, int resultStep, void *pBuffer) )
{
uchar *imgBuf = 0;
uchar *templBuf = 0;
int64 *sqsumBuf = 0;
int64 *resNum = 0;
int64 *resDenom = 0;
double templCoeff = 0;
int winLen = templSize.width * templSize.height;
CvSize resultSize = cvSize( roiSize.width - templSize.width + 1,
roiSize.height - templSize.height + 1 );
int x, y;
CvStatus result = icvMatchTemplateEntry( pImage, imageStep, roiSize,
pTemplate, templStep, templSize,
pResult, resultStep, pBuffer,
cv8u, 0, 1,
(void **) &imgBuf, (void **) &templBuf,
0, (void **) &sqsumBuf,
(void **) &resNum, (void **) &resDenom );
if( result != CV_OK )
return result;
resultStep /= sizeof_float;
/* calc common statistics for template and image */
{
const uchar *rowPtr = (const uchar *) imgBuf;
int64 templSqsum = icvCrossCorr_8u_C1( templBuf, templBuf, winLen );
templCoeff = (double) templSqsum;
templCoeff = icvInvSqrt64d( fabs( templCoeff ) + FLT_EPSILON );
for( y = 0; y < roiSize.height; y++, rowPtr += templSize.width )
{
sqsumBuf[y] = icvCrossCorr_8u_C1( rowPtr, rowPtr, templSize.width );
}
}
/* main loop - through x coordinate of the result */
for( x = 0; x < resultSize.width; x++ )
{
int64 sqsum = 0;
uchar *img_ptr = imgBuf + x;
/* update sums and image band buffer */
if( x > 0 )
{
const uchar *src = pImage + x + templSize.width - 1;
uchar *dst = img_ptr - 1;
int out_val = dst[0];
dst += templSize.width;
for( y = 0; y < roiSize.height; y++, src += imageStep, dst += templSize.width )
{
int in_val = src[0];
sqsumBuf[y] += (in_val - out_val) * (in_val + out_val);
out_val = dst[0];
dst[0] = (uchar) in_val;
}
}
for( y = 0; y < templSize.height; y++ )
{
sqsum += sqsumBuf[y];
}
for( y = 0; y < resultSize.height; y++, img_ptr += templSize.width )
{
int64 res = icvCmpBlocksL2_8u_C1( img_ptr, templBuf, winLen );
if( y > 0 )
{
sqsum -= sqsumBuf[y - 1];
sqsum += sqsumBuf[y + templSize.height - 1];
}
resNum[y] = res;
resDenom[y] = sqsum;
}
for( y = 0; y < resultSize.height; y++ )
{
double res = ((double) resNum[y]) * templCoeff *
icvInvSqrt64d( fabs( (double) resDenom[y] ) + FLT_EPSILON );
pResult[x + y * resultStep] = (float) res;
}
}
return CV_OK;
}
/* -------------------------------------- Corr ---------------------------------------- */
IPCVAPI_IMPL( CvStatus, icvMatchTemplate_Corr_8u32f_C1R,
(const uchar * pImage, int imageStep, CvSize roiSize,
const uchar * pTemplate, int templStep, CvSize templSize,
float *pResult, int resultStep, void *pBuffer) )
{
uchar *imgBuf = 0;
uchar *templBuf = 0;
int64 *resNum = 0;
int winLen = templSize.width * templSize.height;
CvSize resultSize = cvSize( roiSize.width - templSize.width + 1,
roiSize.height - templSize.height + 1 );
int x, y;
CvStatus result = icvMatchTemplateEntry( pImage, imageStep, roiSize,
pTemplate, templStep, templSize,
pResult, resultStep, pBuffer,
cv8u, 0, 0,
(void **) &imgBuf, (void **) &templBuf,
0, 0, (void **) &resNum, 0 );
if( result != CV_OK )
return result;
resultStep /= sizeof_float;
/* main loop - through x coordinate of the result */
for( x = 0; x < resultSize.width; x++ )
{
uchar *imgPtr = imgBuf + x;
/* update sums and image band buffer */
if( x > 0 )
{
const uchar *src = pImage + x + templSize.width - 1;
uchar *dst = imgPtr - 1;
dst += templSize.width;
for( y = 0; y < roiSize.height; y++, src += imageStep, dst += templSize.width )
{
dst[0] = src[0];
}
}
for( y = 0; y < resultSize.height; y++, imgPtr += templSize.width )
{
int64 res = icvCrossCorr_8u_C1( imgPtr, templBuf, winLen );
resNum[y] = res;
}
for( y = 0; y < resultSize.height; y++ )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?