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

📄 iplimage.cpp

📁 一个语言识别引擎
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

/*
 * Copyright (C) 2006 Giorgio Metta
 * CopyPolicy: Released under the terms of the GNU GPL v2.0.
 *
 */

///
/// $Id: IplImage.cpp,v 1.5 2006/10/24 16:43:51 eshuy Exp $
///
///

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <yarp/sig/IplImage.h>

//using namespace yarp;
//using namespace yarp::sig;

static int implemented_yet = 1;

// this was from iplUtil.cpp
bool compareHeader(IplImage* A, IplImage* B)
{
	if( A->nChannels == B->nChannels && !strcmp(A->colorModel, B->colorModel) && !strcmp(A->channelSeq,B->channelSeq) && A->width == B->width 
		&& A->height == B->height)
		return true;
	else 
		return false;
}

///
/// this might turn out to be useful.
inline int PAD_BYTES (int len, int pad)
{
	const int rem = len % pad;
	return (rem != 0) ? (pad - rem) : 0;
}

template <class T>
T* AllocAligned (int size)
{
	T *ptr = new T[size + YARP_IMAGE_ALIGN];
	const int rem = (((unsigned int)ptr) % YARP_IMAGE_ALIGN);
	const char addbytes = YARP_IMAGE_ALIGN - rem; 
	///((rem != 0) ? (YARP_IMAGE_ALIGN - rem) : 0); 

	char *p = ((char *)ptr) + addbytes; 
	*(p - 1) = addbytes;
	return (T*)p;
}

template <class T>
void FreeAligned (T* ptr)
{
	if (ptr == NULL) return;

	const char addbytes = *(((char *)ptr) - 1);
	delete[] (T *)(((char *)ptr) - addbytes);
}

///
///
/// WARNING:
///		most of this is implemented for PAD_BYTES == 0.
///
///		fixing the functions for != 0 is trivial though.
///
///	LATER:
///		externd for PAD_BYTES != 0.
///		NOT TESTED YET!
///

/*
  typedef struct _IplConvKernel {
  int           nCols;
  int           nRows;
  int           anchorX;
  int           anchorY;
  int          *values;
  int           nShiftR;
  } IplConvKernel;
*/

IPLAPIIMPL(IplConvKernel*, iplCreateConvKernel,(int nCols, int nRows,
                                                int anchorX, int anchorY, int* values, int nShiftR))
{
	IplConvKernel *ret = new IplConvKernel;
	assert (ret != NULL);
	
	ret->anchorX = anchorX;
	ret->anchorY = anchorY;
	ret->nCols = nCols;
	ret->nRows = nRows;
	ret->nShiftR = nShiftR;
	ret->values = new int[nCols * nRows];
	assert (ret->values != NULL);
	memcpy (ret->values, values, sizeof(int) * nCols * nRows);

	return ret;
}

/*
  typedef struct _IplConvKernelFP {
  int           nCols;
  int           nRows;
  int           anchorX;
  int           anchorY;
  float        *values;
  } IplConvKernelFP;
*/

IPLAPIIMPL(IplConvKernelFP*, iplCreateConvKernelFP,(int nCols, int nRows,
                                                    int anchorX, int anchorY, float* values))
{
	IplConvKernelFP *ret = new IplConvKernelFP;
	assert (ret != NULL);

	ret->anchorX = anchorX;
	ret->anchorY = anchorY;
	ret->nCols = nCols;
	ret->nRows = nRows;
	ret->values = new float[nCols * nRows];
	assert (ret->values != NULL);
	memcpy (ret->values, values, sizeof(float) * nCols * nRows);

	return ret;
}

IPLAPIIMPL(void,iplGetConvKernel,(IplConvKernel* kernel, int* nCols, int* nRows,
                                  int* anchorX, int* anchorY, int** values, int *nShiftR))
{
	assert (kernel != NULL);
	assert (kernel->values != NULL);

	*nCols = kernel->nCols;
	*nRows = kernel->nRows;
	*anchorX = kernel->anchorX;
	*anchorY = kernel->anchorY;
	memcpy (*values, kernel->values, sizeof(int) * *nCols * *nRows);
	*nShiftR = kernel->nShiftR;
}

IPLAPIIMPL(void,iplGetConvKernelFP,(IplConvKernelFP* kernel,int* nCols, int* nRows,
                                    int* anchorX, int* anchorY, float** values))
{
	assert (kernel != NULL);
	assert (kernel->values != NULL);

	*nCols = kernel->nCols;
	*nRows = kernel->nRows;
	*anchorX = kernel->anchorX;
	*anchorY = kernel->anchorY;
	memcpy (*values, kernel->values, sizeof(float) * *nCols * *nRows);
}

IPLAPIIMPL(void, iplDeleteConvKernel,(IplConvKernel* kernel))
{
	if (kernel == NULL)
		return;

	delete[] kernel->values;
	delete kernel;
}

IPLAPIIMPL(void, iplDeleteConvKernelFP,(IplConvKernelFP* kernel))
{
	if (kernel == NULL)
		return;

	delete[] kernel->values;
	delete kernel;
}

// implemented for mono img. only.
// TODO: in place stuff.
IPLAPIIMPL(void, iplConvolve2D,(IplImage* srcImage, IplImage* dstImage,
                                IplConvKernel** kernel, int nKernels, int combineMethod))
{
	static char *__tmp_res = NULL;
	static int __tmp_size = -1;

	assert (nKernels == 1);
	// implemented only 1 kernel.

	// do not consider anchor, borders are not set, and assumes
	// that the kernel has odd dimensions (both x and y).

	IplConvKernel *ktmp = *kernel;
	int *values = ktmp->values;
	const int ksize = ktmp->nCols * ktmp->nRows;

	assert ((ktmp->nCols % 2) != 0);
	assert ((ktmp->nRows % 2) != 0);

	const int krows = ktmp->nRows;
	const int kcols = ktmp->nCols;
	const int borderx = kcols / 2;
	const int bordery = krows / 2;
	const int w = srcImage->width;
	const int h = srcImage->height;

	assert (compareHeader (srcImage, dstImage));
	assert (srcImage->nChannels == 1);	// Mono images only.

	if (__tmp_res == NULL)
        {
            __tmp_size = dstImage->imageSize;
            ///__tmp_res = new char[dstImage->imageSize];
            __tmp_res = AllocAligned<char> (dstImage->imageSize);
            assert (__tmp_res != NULL);
        }
	else
        {
            if (__tmp_size < dstImage->imageSize)
                {
                    // new size.
                    FreeAligned<char> (__tmp_res);
                    ///delete[] __tmp_res;
                    __tmp_size = dstImage->imageSize;
                    ///__tmp_res = new char[dstImage->imageSize];
                    __tmp_res = AllocAligned<char> (dstImage->imageSize);
                    assert (__tmp_res != NULL);
                }
        }
	
	switch (srcImage->depth)
        {
        case IPL_DEPTH_8U:
            {
                int tmp;
                for (int i = bordery; i <  h - bordery; i++)
                    {
                        for (int j = borderx; j < w - borderx; j++)
                            {
                                tmp = 0;
                                for (int k = 0; k < krows; k++)
                                    for (int l = 0; l < kcols; l++)
                                        {
                                            tmp += srcImage->imageData[(i + k - bordery) * w + j + l - borderx] 
                                                * values[ksize - k * kcols - l - 1];
                                        }
                                tmp >>= ktmp->nShiftR;
                                if (tmp > 255)
                                    tmp = 255;
                                else
                                    if (tmp < 0)
                                        tmp = 0;
                                __tmp_res[i * w + j] = char(tmp);
                            }
                    }

                memcpy (dstImage->imageData, __tmp_res, dstImage->imageSize);
            }
            break;

        case IPL_DEPTH_8S:
            {
                int tmp;
                for (int i = bordery; i <  h - bordery; i++)
                    {
                        for (int j = borderx; j < w - borderx; j++)
                            {
                                tmp = 0;
                                for (int k = 0; k < krows; k++)
                                    for (int l = 0; l < kcols; l++)
                                        {
                                            tmp += srcImage->imageData[(i + k - bordery) * w + j + l - borderx] 
                                                * values[ksize - k * kcols - l - 1];
                                        }
                                tmp >>= ktmp->nShiftR;
                                if (tmp > 127)
                                    tmp = 127;
                                else
                                    if (tmp < -128)
                                        tmp = -128;
                                __tmp_res[i * w + j] = char(tmp);
                            }
                    }

                memcpy (dstImage->imageData, __tmp_res, dstImage->imageSize);
            }
            break;
        }
}

// Implemented for mono images only.
// LATER: extend to color.
// TODO: allow inplace operation.
// combineMethod is not used because only 1 kernel is allowed.
IPLAPIIMPL(void, iplConvolve2DFP,(IplImage* srcImage, IplImage* dstImage,
                                  IplConvKernelFP** kernel, int nKernels, int combineMethod))
{
	// INPLACE: the first time it need to allocate the wk array.
	// I do not really like this solution, it would be much better to
	// alloc the array together with the Kernel.
	// clearly this is also a memory LEAK!
	static float *__tmp_res = NULL;
	static int __tmp_size = -1;

	assert (nKernels == 1);
	// implemented only 1 kernel.

	// do not consider anchor, borders are not set, and assumes
	// that the kernel has odd dimensions (both x and y).

	IplConvKernelFP *ktmp = *kernel;
	float *values = ktmp->values;
	const int ksize = ktmp->nCols * ktmp->nRows;

	assert ((ktmp->nCols % 2) != 0);
	assert ((ktmp->nRows % 2) != 0);

	const int kcols = ktmp->nCols;
	const int krows = ktmp->nRows;
	const int borderx = kcols / 2;
	const int bordery = krows / 2;
	const int w = srcImage->width;
	const int h = srcImage->height;

	assert (compareHeader (srcImage, dstImage));
	assert (srcImage->nChannels == 1);	// Mono images only.
	assert (srcImage->depth == IPL_DEPTH_32F);

	if (__tmp_res == NULL)
        {
            __tmp_size = dstImage->imageSize / sizeof(float);
            ///__tmp_res = new float[dstImage->imageSize / sizeof(float)];
            __tmp_res = AllocAligned<float> (dstImage->imageSize / sizeof(float));
            assert (__tmp_res != NULL);
        }
	else
        {
            if (__tmp_size < (int)(dstImage->imageSize / sizeof(float)))
                {
                    // new size.
                    ///delete[] __tmp_res;
                    FreeAligned<float> (__tmp_res);
                    __tmp_size = dstImage->imageSize / sizeof(float);
                    ///__tmp_res = new float[dstImage->imageSize / sizeof(float)];
                    __tmp_res = AllocAligned<float> (dstImage->imageSize / sizeof(float));
                    assert (__tmp_res != NULL);
                }
        }

	if (srcImage != dstImage)
        {
            float tmp;
            float *source = (float *)srcImage->imageData;
            float *dest = (float *)dstImage->imageData;
            for (int i = bordery; i <  h - bordery; i++)
                {
                    for (int j = borderx; j < w - borderx; j++)
                        {
                            tmp = 0;
                            for (int k = 0; k < krows; k++)
                                for (int l = 0; l < kcols; l++)
                                    {
                                        tmp += source[(i + k - bordery) * w + j + l - borderx] 
                                            * values[ksize - k * kcols - l - 1];
                                    }
                            dest[i * w + j] = tmp;
                        }
                }
        }
	else
        {
            // inplace.

⌨️ 快捷键说明

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