cvmorph.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 2,145 行 · 第 1/5 页
SVN-BASE
2,145 行
/*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"
#include <limits.h>
IPCVAPI_IMPL( CvStatus,
icvMorphologyInitAlloc, ( int roiWidth, CvDataType dataType, int channels,
CvSize elSize, CvPoint elAnchor,
CvElementShape elShape, int* elData,
struct CvMorphState** morphState ))
{
CvStatus status;
switch( elShape )
{
case CV_SHAPE_RECT:
case CV_SHAPE_CROSS:
break;
case CV_SHAPE_ELLIPSE:
{
int i, r = elSize.height / 2, c = elSize.width / 2;
double inv_r2 = 1. / (((double) (r)) * (r));
elData = (int*)alloca( elSize.width * elSize.height * sizeof(elData[0]));
memset( elData, 0, elSize.width*elSize.height*sizeof(elData[0]));
for( i = 0; i < r; i++ )
{
int y = r - i;
int dx = cvRound( c * sqrt( ((double)r * r - y * y) * inv_r2 ));
int x1 = c - dx;
int x2 = c + dx;
if( x1 < 0 )
x1 = 0;
if( x2 >= elSize.width )
x2 = elSize.width;
x2 = (x2 - x1 - 1)*sizeof(elData[0]);
memset( elData + i * elSize.width + x1, -1, x2 );
memset( elData + (elSize.height - i - 1) * elSize.width + x1, -1, x2 );
}
elShape = CV_SHAPE_CUSTOM;
}
break;
case CV_SHAPE_CUSTOM:
if( elShape == CV_SHAPE_CUSTOM && elData == 0 )
return CV_NULLPTR_ERR;
break;
default:
return CV_BADFLAG_ERR;
}
status = icvFilterInitAlloc( roiWidth, dataType, channels, elSize, elAnchor,
elShape == CV_SHAPE_CUSTOM ? elData : 0,
ICV_MAKE_BINARY_KERNEL(elShape), morphState );
if( status < 0 )
return status;
if( !morphState )
return CV_NOTDEFINED_ERR;
return CV_OK;
}
IPCVAPI_IMPL( CvStatus, icvMorphologyFree, (CvMorphState ** morphState) )
{
return icvFilterFree( morphState );
}
static CvStatus
icvErodeRC_8u( uchar * src, int srcStep,
uchar * dst, int dstStep, CvSize * roiSize, CvMorphState * state, int stage )
{
int width = roiSize->width;
int src_height = roiSize->height;
int dst_height = src_height;
int x, y = 0, i;
int ker_x = state->ker_x;
int ker_y = state->ker_y;
int ker_width = state->ker_width;
int ker_height = state->ker_height;
int ker_right = ker_width - ker_x - ((width & 1) == 0);
int crows = state->crows;
uchar **rows = (uchar **) (state->rows);
uchar *tbuf = (uchar *) (state->tbuf);
int channels = state->channels;
int ker_x_n = ker_x * channels;
int ker_width_n = ker_width * channels;
int ker_right_n = ker_right * channels;
int width_n = width * channels;
int is_small_width = width < MAX( ker_x, ker_right );
int starting_flag = 0;
int width_rest = width_n & (CV_MORPH_ALIGN - 1);
int is_cross = ICV_BINARY_KERNEL_SHAPE(state->kerType) == CV_SHAPE_CROSS;
/* initialize cyclic buffer when starting */
if( stage == CV_WHOLE || stage == CV_START )
{
for( i = 0; i < ker_height; i++ )
{
rows[i] = (uchar *) (state->buffer + state->buffer_step * i);
}
crows = ker_y;
if( stage != CV_WHOLE )
dst_height -= ker_height - ker_y - 1;
starting_flag = 1;
}
if( stage == CV_END )
dst_height += ker_height - ker_y - 1;
do
{
int need_copy = is_small_width | (y == 0);
uchar *tsrc, *tdst;
uchar *saved_row = rows[ker_y];
/* fill cyclic buffer - horizontal filtering */
for( ; crows < ker_height + is_cross; crows++ )
{
if( crows < ker_height )
{
tsrc = src - ker_x_n;
tdst = rows[crows];
if( src_height-- <= 0 )
{
if( stage != CV_WHOLE && stage != CV_END )
break;
/* duplicate last row */
tsrc = rows[crows - 1];
CV_COPY( tdst, tsrc, width_n, x );
continue;
}
need_copy |= src_height == 1;
}
else
{
/* convolve center line for cross-shaped element */
tsrc = rows[ker_y] - ker_x_n;
tdst = tbuf;
need_copy = 0;
}
if( ker_width > 1 && (!is_cross || crows == ker_height) )
{
if( need_copy )
{
tsrc = tbuf - ker_x_n;
CV_COPY( tbuf, src, width_n, x );
}
else if( !is_cross )
{
CV_COPY( tbuf - ker_x_n, src - ker_x_n, ker_x_n, x );
CV_COPY( tbuf, src + width_n, ker_right_n, x );
}
if( channels == 1 )
{
/* make replication borders */
uchar pix = tsrc[ker_x];
CV_SET( tsrc, pix, ker_x, x );
pix = tsrc[width + ker_x - 1];
CV_SET( tsrc + width + ker_x, pix, ker_right, x );
/* horizontal convolution loop */
for( i = 0; i < width_n; i += 2 )
{
int j;
int t, t0 = tsrc[i + 1];
for( j = 2; j < ker_width_n; j++ )
{
int t1 = tsrc[i + j];
CV_CALC_MIN( t0, t1 );
}
t = tsrc[i];
CV_CALC_MIN( t, t0 );
tdst[i] = (uchar) t;
t = tsrc[i + j];
CV_CALC_MIN( t, t0 );
tdst[i + 1] = (uchar) t;
}
}
else if( channels == 3 )
{
/* make replication borders */
CvRGB8u pix = ((CvRGB8u *) tsrc)[ker_x];
CV_SET( (CvRGB8u *) tsrc, pix, ker_x, x );
pix = ((CvRGB8u *) tsrc)[width + ker_x - 1];
CV_SET( (CvRGB8u *) tsrc + width + ker_x, pix, ker_right, x );
/* horizontal convolution loop */
for( i = 0; i < width_n; i++ )
{
int j;
int t0 = tsrc[i];
for( j = 3; j < ker_width_n; j += 3 )
{
int t1 = tsrc[i + j];
CV_CALC_MIN( t0, t1 );
}
tdst[i] = (uchar) t0;
}
}
else /* channels == 4 */
{
/* make replication borders */
CvRGBA8u pix = ((CvRGBA8u *) tsrc)[ker_x];
CV_SET( (CvRGBA8u *) tsrc, pix, ker_x, x );
pix = ((CvRGBA8u *) tsrc)[width + ker_x - 1];
CV_SET( (CvRGBA8u *) tsrc + width + ker_x, pix, ker_right, x );
/* horizontal convolution loop */
for( i = 0; i < width_n; i++ )
{
int j;
int t0 = tsrc[i];
for( j = 4; j < ker_width_n; j += 4 )
{
int t1 = tsrc[i + j];
CV_CALC_MIN( t0, t1 );
}
tdst[i] = (uchar) t0;
}
}
if( !need_copy && !is_cross )
{
/* restore borders */
CV_COPY( src - ker_x_n, tbuf - ker_x_n, ker_x_n, x );
CV_COPY( src + width_n, tbuf, ker_right_n, x );
}
}
else
{
CV_COPY( tdst, tsrc + ker_x_n, width_n, x );
}
src += crows < ker_height ? srcStep : 0;
}
if( starting_flag )
{
starting_flag = 0;
tsrc = rows[ker_y];
for( i = 0; i < ker_y; i++ )
{
tdst = rows[i];
CV_COPY( tdst, tsrc, width_n, x );
}
}
/* vertical convolution */
if( crows != ker_height )
{
if( crows < ker_height )
break;
/* else it is cross-shaped element: change central line */
rows[ker_y] = tbuf;
crows--;
}
tdst = dst;
if( width_rest )
{
need_copy = width_n < CV_MORPH_ALIGN || y == dst_height - 1;
if( need_copy )
tdst = tbuf;
else
CV_COPY( tbuf + width_n, dst + width_n, CV_MORPH_ALIGN, x );
}
for( x = 0; x < width_n; x += 4 )
{
int val0, val1, val2, val3;
tsrc = rows[0];
val0 = tsrc[x];
val1 = tsrc[x + 1];
val2 = tsrc[x + 2];
val3 = tsrc[x + 3];
for( i = 1; i < ker_height; i++ )
{
int s;
tsrc = rows[i];
s = tsrc[x + 0];
CV_CALC_MIN( val0, s );
s = tsrc[x + 1];
CV_CALC_MIN( val1, s );
s = tsrc[x + 2];
CV_CALC_MIN( val2, s );
s = tsrc[x + 3];
CV_CALC_MIN( val3, s );
}
tdst[x + 0] = (uchar) val0;
tdst[x + 1] = (uchar) val1;
tdst[x + 2] = (uchar) val2;
tdst[x + 3] = (uchar) val3;
}
if( width_rest )
{
if( need_copy )
CV_COPY( dst, tbuf, width_n, x );
else
CV_COPY( dst + width_n, tbuf + width_n, CV_MORPH_ALIGN, x );
}
rows[ker_y] = saved_row;
/* rotate buffer */
{
uchar *t = rows[0];
CV_COPY( rows, rows + 1, ker_height - 1, i );
rows[i] = t;
crows--;
dst += dstStep;
}
}
while( ++y < dst_height );
roiSize->height = y;
state->crows = crows;
return CV_OK;
}
static CvStatus
icvErodeArb_8u( uchar * src, int srcStep,
uchar * dst, int dstStep, CvSize * roiSize, CvMorphState * state, int stage )
{
#define INIT_VAL 255
int width = roiSize->width;
int src_height = roiSize->height;
int dst_height = src_height;
int x, y = 0, i;
int ker_x = state->ker_x;
int ker_y = state->ker_y;
int ker_width = state->ker_width;
int ker_height = state->ker_height;
int ker_right = ker_width - ker_x - ((width & 1) == 0);
uchar *ker_data = state->ker1 + ker_width;
int crows = state->crows;
uchar **rows = (uchar **) (state->rows);
uchar *tbuf = (uchar *) (state->tbuf);
int channels = state->channels;
int ker_x_n = ker_x * channels;
int ker_width_n = ker_width * channels;
int width_n = width * channels;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?