📄 iplimage.cpp
字号:
// -*- 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 + -