看到http://blog.youkuaiyun.com/ihadl/article/details/12993505贴出burns的算法,写的不错。
由于以前用过该算法,并做了移植,去掉了ipp部分,这里贴出部分移植代码,供参考。
burns.h:
//#define IPP
#ifdef IPP
#include "ipp.h"
#else
typedef unsigned char Ipp8u;
typedef unsigned short Ipp16u;
typedef signed char Ipp8s;
typedef signed short Ipp16s;
#define IPP_PI180 ( 0.01745329251994329577 ) // pi/180
typedef struct {
int width;
int height;
} IppiSize;
typedef enum _IppiMaskSize {
ippMskSize1x3 = 13,
ippMskSize1x5 = 15,
ippMskSize3x1 = 31,
ippMskSize3x3 = 33,
ippMskSize5x1 = 51,
ippMskSize5x5 = 55
} IppiMaskSize;
#endif
burns.c:
#ifndef IPP
//
//my ipp function
Ipp8u *ippiMalloc_8u_C1( int widthPixels, int heightPixels, int* pStepBytes)
{
// *pStepBytes = widthPixels;
*pStepBytes = (widthPixels * sizeof(Ipp8u) + 31) / 32 * 32;
Ipp8u *pixel = (Ipp8u*)calloc(*pStepBytes * heightPixels, 1);
return pixel;
}
Ipp16s *ippiMalloc_16s_C1( int widthPixels, int heightPixels, int* pStepBytes)
{
// *pStepBytes = widthPixels;
*pStepBytes = (widthPixels * sizeof(Ipp16s) + 31) / 32 * 32;
Ipp16s *pixel = (Ipp16s*)calloc(*pStepBytes * heightPixels, 1);
return pixel;
}
void ippiFree(void* ptr)
{
if (ptr)
free(ptr);
}
void ippiFilterSobelHoriz_8u16s_C1R(const Ipp8u* pSrc, int srcStep, Ipp16s* pDst, int dstStep, IppiSize roiSize, IppiMaskSize mask)
{
if (mask == ippMskSize3x3)
{
static const int sizeOfSobelMask = 9;
static int sobelMaskHor[sizeOfSobelMask] =
{
-1, -2, -1,
0, 0, 0,
1, 2, 1
};
dstStep /= sizeof(Ipp16s);
short ts = 0, tmp = 0, idx = 0;
for (int y = 1; y < roiSize.height - 1; ++ y)
{
for (int x = 1; x < roiSize.width - 1; ++x)
{
idx = ts = 0;
for(int r = y - 1; r <= y + 1; ++r)
{
for(int c = x - 1; c <= x + 1; ++c)
{
tmp = pSrc[r * srcStep + c];
// tmp = pSrc[r * roiSize.width + c];
ts += (sobelMaskHor[idx] * tmp );
++idx;
}
}
// pDst[y * roiSize.width + x] = ts;
pDst[y * dstStep + x] = ts;
}
}
}
}
void ippiFilterSobelVert_8u16s_C1R(const Ipp8u* pSrc, int srcStep, Ipp16s* pDst, int dstStep, IppiSize roiSize, IppiMaskSize mask)
{
if (mask == ippMskSize3x3)
{
static const int sizeOfSobelMask = 9;
static int SobelMaskVer[sizeOfSobelMask] =
{
-1, 0, 1,
-2, 0, 2,
-1, 0, 1
};
dstStep /= sizeof(Ipp16s);
// memset(pDst, 0, dstStep*sizeof(Ipp16s));
// memset(pDst+(roiSize.height-1)*dstStep, 0, dstStep*sizeof(Ipp16s));
// Ipp16s *p = pDst;
// for (int i = 0; i < roiSize.height; i++)
// {
// p[i] = 0;
// p[roiSize.width-1] = 0;
// p += dstStep;
// }
short tv = 0, tmp = 0, idx = 0;
for (int y = 1; y < roiSize.height - 1; ++ y)
{
for (int x = 1; x < roiSize.width - 1; ++x)
{
idx = tv = 0;
for(int r = y - 1; r <= y + 1; ++r)
{
for(int c = x - 1; c <= x + 1; ++c)
{
tmp = pSrc[r * srcStep + c];
// tmp = pSrc[r * roiSize.width + c];
tv += (SobelMaskVer[idx] * tmp );
++idx;
}
}
// pDst[y * roiSize.width + x] = tv;
pDst[y * dstStep + x] = tv;
}
}
}
}
void ippiSet_8u_C1R(Ipp8u value, Ipp8u* pDst, int dstStep, IppiSize roiSize)
{
int x, y;
Ipp8u* p = pDst;
for (y = 0; y < roiSize.height; ++y)
{
for (x = 0; x < roiSize.width; ++x)
{
pDst[y * dstStep + x] = value;
// *p++ = value;
}
}
}
#endif