⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cvmorph.cpp

📁 opencv库在TI DM6437上的移植,目前包括两个库cv.lib和cxcore.lib的工程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*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>
#include <stdio.h>

#define IPCV_MORPHOLOGY_PTRS( morphtype, flavor )               \
    icv##morphtype##Rect_##flavor##_C1R_t                       \
        icv##morphtype##Rect_##flavor##_C1R_p = 0;              \
    icv##morphtype##Rect_GetBufSize_##flavor##_C1R_t            \
        icv##morphtype##Rect_GetBufSize_##flavor##_C1R_p = 0;   \
    icv##morphtype##Rect_##flavor##_C3R_t                       \
        icv##morphtype##Rect_##flavor##_C3R_p = 0;              \
    icv##morphtype##Rect_GetBufSize_##flavor##_C3R_t            \
        icv##morphtype##Rect_GetBufSize_##flavor##_C3R_p = 0;   \
    icv##morphtype##Rect_##flavor##_C4R_t                       \
        icv##morphtype##Rect_##flavor##_C4R_p = 0;              \
    icv##morphtype##Rect_GetBufSize_##flavor##_C4R_t            \
        icv##morphtype##Rect_GetBufSize_##flavor##_C4R_p = 0;   \
                                                                \
    icv##morphtype##_##flavor##_C1R_t                           \
        icv##morphtype##_##flavor##_C1R_p = 0;                  \
    icv##morphtype##_##flavor##_C3R_t                           \
        icv##morphtype##_##flavor##_C3R_p = 0;                  \
    icv##morphtype##_##flavor##_C4R_t                           \
        icv##morphtype##_##flavor##_C4R_p = 0;

#define IPCV_MORPHOLOGY_INITALLOC_PTRS( flavor )                \
    icvMorphInitAlloc_##flavor##_C1R_t                          \
        icvMorphInitAlloc_##flavor##_C1R_p = 0;                 \
    icvMorphInitAlloc_##flavor##_C3R_t                          \
        icvMorphInitAlloc_##flavor##_C3R_p = 0;                 \
    icvMorphInitAlloc_##flavor##_C4R_t                          \
        icvMorphInitAlloc_##flavor##_C4R_p = 0;

IPCV_MORPHOLOGY_PTRS( Erode, 8u )
IPCV_MORPHOLOGY_PTRS( Erode, 32f )
IPCV_MORPHOLOGY_PTRS( Dilate, 8u )
IPCV_MORPHOLOGY_PTRS( Dilate, 32f )
IPCV_MORPHOLOGY_INITALLOC_PTRS( 8u )
IPCV_MORPHOLOGY_INITALLOC_PTRS( 32f )

icvMorphFree_t icvMorphFree_p = 0;

/****************************************************************************************\
                     Basic Morphological Operations: Erosion & Dilation
\****************************************************************************************/

static void icvErodeRectRow_8u( const uchar* src, uchar* dst, void* params );
static void icvErodeRectRow_32f( const int* src, int* dst, void* params );
static void icvDilateRectRow_8u( const uchar* src, uchar* dst, void* params );
static void icvDilateRectRow_32f( const int* src, int* dst, void* params );

static void icvErodeRectCol_8u( const uchar** src, uchar* dst, int dst_step,
                                int count, void* params );
static void icvErodeRectCol_32f( const int** src, int* dst, int dst_step,
                                 int count, void* params );
static void icvDilateRectCol_8u( const uchar** src, uchar* dst, int dst_step,
                                 int count, void* params );
static void icvDilateRectCol_32f( const int** src, int* dst, int dst_step,
                                  int count, void* params );

static void icvErodeAny_8u( const uchar** src, uchar* dst, int dst_step,
                            int count, void* params );
static void icvErodeAny_32f( const int** src, int* dst, int dst_step,
                             int count, void* params );
static void icvDilateAny_8u( const uchar** src, uchar* dst, int dst_step,
                             int count, void* params );
static void icvDilateAny_32f( const int** src, int* dst, int dst_step,
                              int count, void* params );

CvMorphology::CvMorphology()
{
    element = 0;
    el_sparse = 0;
}

CvMorphology::CvMorphology( int _operation, int _max_width, int _src_dst_type,
                            int _element_shape, CvMat* _element,
                            CvSize _ksize, CvPoint _anchor,
                            int _border_mode, CvScalar _border_value )
{
    element = 0;
    el_sparse = 0;
    init( _operation, _max_width, _src_dst_type,
          _element_shape, _element, _ksize, _anchor,
          _border_mode, _border_value );
}


void CvMorphology::clear()
{
    cvReleaseMat( &element );
    cvFree( &el_sparse );
    CvBaseImageFilter::clear();
}


CvMorphology::~CvMorphology()
{
    clear();
}


void CvMorphology::init( int _operation, int _max_width, int _src_dst_type,
                         int _element_shape, CvMat* _element,
                         CvSize _ksize, CvPoint _anchor,
                         int _border_mode, CvScalar _border_value )
{
    CV_FUNCNAME( "CvMorphology::init" );

    __BEGIN__;

    int depth = CV_MAT_DEPTH(_src_dst_type);
    int el_type = 0, nz = -1;
    
    if( _operation != ERODE && _operation != DILATE )
        CV_ERROR( CV_StsBadArg, "Unknown/unsupported morphological operation" );

    if( _element_shape == CUSTOM )
    {
        if( !CV_IS_MAT(_element) )
            CV_ERROR( CV_StsBadArg,
            "structuring element should be valid matrix if CUSTOM element shape is specified" );

        el_type = CV_MAT_TYPE(_element->type);
        if( el_type != CV_8UC1 && el_type != CV_32SC1 )
            CV_ERROR( CV_StsUnsupportedFormat, "the structuring element must have 8uC1 or 32sC1 type" );

        _ksize = cvGetMatSize(_element);
        CV_CALL( nz = cvCountNonZero(_element));
        if( nz == _ksize.width*_ksize.height )
            _element_shape = RECT;
    }

    operation = _operation;
    el_shape = _element_shape;

    CV_CALL( CvBaseImageFilter::init( _max_width, _src_dst_type, _src_dst_type,
        _element_shape == RECT, _ksize, _anchor, _border_mode, _border_value ));

    if( el_shape == RECT )
    {
        if( operation == ERODE )
        {
            if( depth == CV_8U )
                x_func = (CvRowFilterFunc)icvErodeRectRow_8u,
                y_func = (CvColumnFilterFunc)icvErodeRectCol_8u;
            else if( depth == CV_32F )
                x_func = (CvRowFilterFunc)icvErodeRectRow_32f,
                y_func = (CvColumnFilterFunc)icvErodeRectCol_32f;
        }
        else
        {
            assert( operation == DILATE );
            if( depth == CV_8U )
                x_func = (CvRowFilterFunc)icvDilateRectRow_8u,
                y_func = (CvColumnFilterFunc)icvDilateRectCol_8u;
            else if( depth == CV_32F )
                x_func = (CvRowFilterFunc)icvDilateRectRow_32f,
                y_func = (CvColumnFilterFunc)icvDilateRectCol_32f;
        }
    }
    else
    {
        int i, j, k = 0;
        int cn = CV_MAT_CN(src_type);
        CvPoint* nz_loc;

        if( !(element && el_sparse &&
            _ksize.width == element->cols && _ksize.height == element->rows) )
        {
            cvReleaseMat( &element );
            cvFree( &el_sparse );
            CV_CALL( element = cvCreateMat( _ksize.height, _ksize.width, CV_8UC1 ));
            CV_CALL( el_sparse = (uchar*)cvAlloc(
                ksize.width*ksize.height*(2*sizeof(int) + sizeof(uchar*))));
        }

        if( el_shape == CUSTOM )
        {
            CV_CALL( cvConvert( _element, element ));
        }
        else
        {
            CV_CALL( init_binary_element( element, el_shape, anchor ));
        }

        if( operation == ERODE )
        {
            if( depth == CV_8U )
                y_func = (CvColumnFilterFunc)icvErodeAny_8u;
            else if( depth == CV_32F )
                y_func = (CvColumnFilterFunc)icvErodeAny_32f;
        }
        else
        {
            assert( operation == DILATE );
            if( depth == CV_8U )
                y_func = (CvColumnFilterFunc)icvDilateAny_8u;
            else if( depth == CV_32F )
                y_func = (CvColumnFilterFunc)icvDilateAny_32f;
        }
        
        nz_loc = (CvPoint*)el_sparse;

        for( i = 0; i < ksize.height; i++ )
            for( j = 0; j < ksize.width; j++ )
            {
                if( element->data.ptr[i*element->step+j] )
                    nz_loc[k++] = cvPoint(j*cn,i);
            }
        if( k == 0 )
            nz_loc[k++] = cvPoint(anchor.x*cn,anchor.y);
        el_sparse_count = k;
    }

    if( depth == CV_32F && border_mode == IPL_BORDER_CONSTANT )
    {
        int i, cn = CV_MAT_CN(src_type);
        int* bt = (int*)border_tab;
        for( i = 0; i < cn; i++ )
            bt[i] = CV_TOGGLE_FLT(bt[i]);
    }

    __END__;
}


void CvMorphology::init( int _max_width, int _src_type, int _dst_type,
                         bool _is_separable, CvSize _ksize,
                         CvPoint _anchor, int _border_mode,
                         CvScalar _border_value )
{
    CvBaseImageFilter::init( _max_width, _src_type, _dst_type, _is_separable,
                             _ksize, _anchor, _border_mode, _border_value );
}


void CvMorphology::start_process( CvSlice x_range, int width )
{
    CvBaseImageFilter::start_process( x_range, width );
    if( el_shape == RECT )
    {
        // cut the cyclic buffer off by 1 line if need, to make
        // the vertical part of separable morphological filter
        // always process 2 rows at once (except, may be,
        // for the last one in a stripe).
        int t = buf_max_count - max_ky*2;
        if( t > 1 && t % 2 != 0 )
        {
            buf_max_count--;
            buf_end -= buf_step;
        }
    }
}


int CvMorphology::fill_cyclic_buffer( const uchar* src, int src_step,
                                      int y0, int y1, int y2 )
{
    int i, y = y0, bsz1 = border_tab_sz1, bsz = border_tab_sz;
    int pix_size = CV_ELEM_SIZE(src_type);
    int width_n = (prev_x_range.end_index - prev_x_range.start_index)*pix_size;

    if( CV_MAT_DEPTH(src_type) != CV_32F )
        return CvBaseImageFilter::fill_cyclic_buffer( src, src_step, y0, y1, y2 );

    // fill the cyclic buffer
    for( ; buf_count < buf_max_count && y < y2; buf_count++, y++, src += src_step )
    {
        uchar* trow = is_separable ? buf_end : buf_tail;

        for( i = 0; i < width_n; i += sizeof(int) )
        {
            int t = *(int*)(src + i);
            *(int*)(trow + i + bsz1) = CV_TOGGLE_FLT(t);
        }

        if( border_mode != IPL_BORDER_CONSTANT )
        {
            for( i = 0; i < bsz1; i++ )
            {
                int j = border_tab[i];
                trow[i] = trow[j];
            }
            for( ; i < bsz; i++ )
            {
                int j = border_tab[i];
                trow[i + width_n] = trow[j];
            }
        }
        else
        {
            const uchar *bt = (uchar*)border_tab; 
            for( i = 0; i < bsz1; i++ )
                trow[i] = bt[i];

            for( ; i < bsz; i++ )
                trow[i + width_n] = bt[i];
        }

        if( is_separable )
            x_func( trow, buf_tail, this );

        buf_tail += buf_step;
        if( buf_tail >= buf_end )
            buf_tail = buf_start;
    }

    return y - y0;
}


void CvMorphology::init_binary_element( CvMat* element, int element_shape, CvPoint anchor )
{
    CV_FUNCNAME( "CvMorphology::init_binary_element" );

    __BEGIN__;

    int type;
    int i, j, cols, rows;
    int r = 0, c = 0;
    double inv_r2 = 0;

    if( !CV_IS_MAT(element) )
        CV_ERROR( CV_StsBadArg, "element must be valid matrix" );

    type = CV_MAT_TYPE(element->type);
    if( type != CV_8UC1 && type != CV_32SC1 )
        CV_ERROR( CV_StsUnsupportedFormat, "element must have 8uC1 or 32sC1 type" );

    if( anchor.x == -1 )
        anchor.x = element->cols/2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -