对外的接口有三个
1 :对NV12或NV21 数据的插值和旋转,是对整张图操作
int NV12LinearAndRo(unsigned char * srcImage, unsigned char * destImage, int srcW, int srcH, int destW, int destH, int * afterW, int * afterH, int cammeraId, int angle)
2 :修正1 ,速度可能会快一些
int NV12LinearAndRo_fix(unsigned char * srcImage, unsigned char * destImage, int srcW, int srcH, int destW, int destH, int * afterW, int * afterH, int cammeraId, int angle)
3 :功能更加强大,对原始图抠图,对抠出来的图像进行插值和旋转
int NVCutLinearRo(unsigned char * srcImage, unsigned char * destImage, int srcW, int srcH, int x0, int y0, int x1, int y1, int destW, int destH, int * afterW, int * afterH, int cammeraId, int angle)
static int ChangeWH(int angle, int destW, int destH, int * afterW, int * afterH)
{
if ((angle == 0 || angle == 180 ))
{
*afterW = destH;
*afterH = destW;
}
else
{
*afterW = destW;
*afterH = destH;
}
return 0 ;
}
static int PixelRoChannels(unsigned char * dest, int idx, int idy, int destW, int destH, int value, int cameraId, int angle, int channels, int channel)
{
int width = destW;
int height = destH;
int theRealW = 0 ;
int dx = 0 ;
int dy = 0 ;
int k = 0 ;
if (0 == cameraId)
{
if (0 == angle)
{
dx = height - 1 - idy;
dy = idx;
theRealW = height;
dest[(dy * theRealW + dx) * channels + channel] = value;
}
else if (90 == angle)
{
dx = idx;
dy = idy;
theRealW = width;
dest[(dy * theRealW + dx) * channels + channel] = value;
}
else if (270 == angle)
{
dx = width - 1 - idx;
dy = height - 1 - idy;
theRealW = width;
dest[(dy * theRealW + dx) * channels + channel] = value;
}
else if (180 == angle)
{
dx = idy;
dy = width - 1 - idx;
theRealW = height;
dest[(dy * theRealW + dx) * channels + channel] = value;
}
}
else
{
if (0 == angle)
{
dx = height - 1 - idy;
dy = width - 1 - idx;
theRealW = height;
dest[(dy * theRealW + dx) * channels + channel] = value;
}
else if (90 == angle)
{
dx = width - 1 - idx;
dy = idy;
theRealW = width;
dest[(dy * theRealW + dx) * channels + channel] = value;
}
else if (270 == angle)
{
dx = idx;
dy = height - 1 - idy;
theRealW = width;
dest[(dy * theRealW + dx) * channels + channel] = value;
}
else if (180 == angle)
{
dx = idy;
dy = idx;
theRealW = height;
dest[(dy * theRealW + dx) * channels + channel] = value;
}
}
return 0 ;
}
int NV12LinearAndRo(unsigned char * srcImage, unsigned char * destImage, int srcW, int srcH, int destW, int destH, int * afterW, int * afterH, int cammeraId, int angle)
{
float timeX = 0.0f ;
float timeY = 0.0f ;
timeX = srcW * 1.0f / destW;
timeY = srcH * 1.0f / destH;
int i = 0 ;
int j = 0 ;
int k = 0 ;
unsigned char * srcUV = srcImage + srcW * srcH;
unsigned char * destUV = destImage + destW * destH;
ChangeWH(angle, destW, destH, afterW, afterH);
for (i = 0 ; i < destH; i++)
{
for (j = 0 ; j < destW; j++)
{
int srcIdX = 0 ;
int srcIdY = 0 ;
float srcfIdX = 0.0f ;
float srcfIdY = 0.0f ;
float weightX[2 ] = { 0.0f , 0.0f };
float weightY[2 ] = { 0.0f , 0.0f };
srcfIdX = j * timeX;
srcfIdY = i * timeY;
srcIdX = (int )(srcfIdX);
srcIdY = (int )(srcfIdY);
weightX[1 ] = srcfIdX - srcIdX;
weightX[0 ] = 1.0f - weightX[1 ];
weightY[1 ] = srcfIdY - srcIdY;
weightY[0 ] = 1.0f - weightY[1 ];
int value = (srcImage[(srcIdY * srcW + srcIdX)] * weightX[0 ] + srcImage[(srcIdY * srcW + clamp_g(srcIdX + 1 , 0 , srcW - 1 ))] * weightX[1 ]) * weightY[0 ] +
(srcImage[(clamp_g(srcIdY + 1 , 0 , srcH - 1 ) * srcW + srcIdX)] * weightX[0 ] + srcImage[(clamp_g(srcIdY + 1 , 0 , srcH - 1 ) * srcW + clamp_g(srcIdX + 1 , 0 , srcW - 1 ))] * weightX[1 ]) * weightY[1 ];
PixelRoChannels(destImage, j, i, destW, destH, value, cammeraId, angle, 1 , 0 );
if (0 == i % 2 && 0 == j % 2 )
{
int srcVUW = srcW / 2 ;
int srcVUH = srcH / 2 ;
int destVUW = destW / 2 ;
int destVUH = destH / 2 ;
int destVUy = i / 2 ;
int destVUx = j / 2 ;
int UVsrcIdX = 0 ;
int UVsrcIdY = 0 ;
float UVsrcfIdX = 0.0f ;
float UVsrcfIdY = 0.0f ;
float UVweightX[2 ] = { 0.0f };
float UVweightY[2 ] = { 0.0f };
UVsrcfIdX = destVUx * timeX;
UVsrcfIdY = destVUy * timeY;
UVsrcIdX = (int )(UVsrcfIdX);
UVsrcIdY = (int )(UVsrcfIdY);
UVweightX[1 ] = UVsrcfIdX - UVsrcIdX;
UVweightX[0 ] = 1.0f - UVweightX[1 ];
UVweightY[1 ] = UVsrcfIdY - UVsrcIdY;
UVweightY[0 ] = 1.0f - UVweightY[1 ];
int value0 = (srcUV[(UVsrcIdY * srcVUW + UVsrcIdX) * 2 + 0 ] * weightX[0 ] + srcUV[(UVsrcIdY * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 0 ] * weightX[1 ]) * weightY[0 ] +
(srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + UVsrcIdX) * 2 + 0 ] * weightX[0 ] + srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 0 ] * weightX[1 ]) * weightY[1 ];
int value1 = (srcUV[(UVsrcIdY * srcVUW + UVsrcIdX) * 2 + 1 ] * weightX[0 ] + srcUV[(UVsrcIdY * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 1 ] * weightX[1 ]) * weightY[0 ] +
(srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + UVsrcIdX) * 2 + 1 ] * weightX[0 ] + srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 1 ] * weightX[1 ]) * weightY[1 ];
PixelRoChannels(destUV, destVUx, destVUy, destVUW, destVUH, value0, cammeraId, angle, 2 , 0 );
PixelRoChannels(destUV, destVUx, destVUy, destVUW, destVUH, value1, cammeraId, angle, 2 , 1 );
}
}
}
return 0 ;
}
int NV12LinearAndRo_fix(unsigned char * srcImage, unsigned char * destImage, int srcW, int srcH, int destW, int destH, int * afterW, int * afterH, int cammeraId, int angle)
{
float timeX = 0.0f ;
float timeY = 0.0f ;
timeX = srcW * 1.0f / destW;
timeY = srcH * 1.0f / destH;
int i = 0 ;
int j = 0 ;
int k = 0 ;
unsigned char * srcUV = srcImage + srcW * srcH;
unsigned char * destUV = destImage + destW * destH;
ChangeWH(angle, destW, destH, afterW, afterH);
for (i = 0 ; i < destH; i++)
{
for (j = 0 ; j < destW; j++)
{
int srcIdX = 0 ;
int srcIdY = 0 ;
float srcfIdX = 0.0f ;
float srcfIdY = 0.0f ;
float weightX[2 ] = { 0.0f , 0.0f };
float weightY[2 ] = { 0.0f , 0.0f };
srcfIdX = j * timeX;
srcfIdY = i * timeY;
srcIdX = (int )(srcfIdX);
srcIdY = (int )(srcfIdY);
weightX[1 ] = srcfIdX - srcIdX;
weightX[0 ] = 1.0f - weightX[1 ];
weightY[1 ] = srcfIdY - srcIdY;
weightY[0 ] = 1.0f - weightY[1 ];
int value = (srcImage[(srcIdY * srcW + srcIdX)] * weightX[0 ] + srcImage[(srcIdY * srcW + clamp_g(srcIdX + 1 , 0 , srcW - 1 ))] * weightX[1 ]) * weightY[0 ] +
(srcImage[(clamp_g(srcIdY + 1 , 0 , srcH - 1 ) * srcW + srcIdX)] * weightX[0 ] + srcImage[(clamp_g(srcIdY + 1 , 0 , srcH - 1 ) * srcW + clamp_g(srcIdX + 1 , 0 , srcW - 1 ))] * weightX[1 ]) * weightY[1 ];
PixelRoChannels(destImage, j, i, destW, destH, value, cammeraId, angle, 1 , 0 );
}
}
for (i = 0 ; i < destH; i++)
{
for (j = 0 ; j < destW; j++)
{
int srcVUW = srcW / 2 ;
int srcVUH = srcH / 2 ;
int destVUW = destW / 2 ;
int destVUH = destH / 2 ;
int destVUy = i / 2 ;
int destVUx = j / 2 ;
int UVsrcIdX = 0 ;
int UVsrcIdY = 0 ;
float UVsrcfIdX = 0.0f ;
float UVsrcfIdY = 0.0f ;
float UVweightX[2 ] = { 0.0f };
float UVweightY[2 ] = { 0.0f };
UVsrcfIdX = destVUx * timeX;
UVsrcfIdY = destVUy * timeY;
UVsrcIdX = (int )(UVsrcfIdX);
UVsrcIdY = (int )(UVsrcfIdY);
UVweightX[1 ] = UVsrcfIdX - UVsrcIdX;
UVweightX[0 ] = 1.0f - UVweightX[1 ];
UVweightY[1 ] = UVsrcfIdY - UVsrcIdY;
UVweightY[0 ] = 1.0f - UVweightY[1 ];
int value0 = (srcUV[(UVsrcIdY * srcVUW + UVsrcIdX) * 2 + 0 ] * UVweightX[0 ] + srcUV[(UVsrcIdY * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 0 ] * UVweightX[1 ]) * UVweightY[0 ] +
(srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + UVsrcIdX) * 2 + 0 ] * UVweightX[0 ] + srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 0 ] * UVweightX[1 ]) * UVweightY[1 ];
int value1 = (srcUV[(UVsrcIdY * srcVUW + UVsrcIdX) * 2 + 1 ] * UVweightX[0 ] + srcUV[(UVsrcIdY * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 1 ] * UVweightX[1 ]) * UVweightY[0 ] +
(srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + UVsrcIdX) * 2 + 1 ] * UVweightX[0 ] + srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 1 ] * UVweightX[1 ]) * UVweightY[1 ];
PixelRoChannels(destUV, destVUx, destVUy, destVUW, destVUH, value0, cammeraId, angle, 2 , 0 );
PixelRoChannels(destUV, destVUx, destVUy, destVUW, destVUH, value1, cammeraId, angle, 2 , 1 );
}
}
return 0 ;
}
int NVCutLinearRo(unsigned char * srcImage, unsigned char * destImage, int srcW, int srcH, int x0, int y0, int x1, int y1, int destW, int destH, int * afterW, int * afterH, int cammeraId, int angle)
{
float timeX = 0.0f ;
float timeY = 0.0f ;
int srcCutW = 0 ;
int srcCutH = 0 ;
srcCutW = x1 - x0 + 1 ;
srcCutH = y1 - y0 + 1 ;
timeX = srcCutW * 1.0f / destW;
timeY = srcCutH * 1.0f / destH;
int i = 0 ;
int j = 0 ;
int k = 0 ;
unsigned char * srcUV = srcImage + srcW * srcH;
unsigned char * destUV = destImage + destW * destH;
ChangeWH(angle, destW, destH, afterW, afterH);
for (i = 0 ; i < destH; i++)
{
for (j = 0 ; j < destW; j++)
{
int srcIdX = 0 ;
int srcIdY = 0 ;
float srcfIdX = 0.0f ;
float srcfIdY = 0.0f ;
float weightX[2 ] = { 0.0f , 0.0f };
float weightY[2 ] = { 0.0f , 0.0f };
srcfIdX = j * timeX + x0;
srcfIdY = i * timeY + y0;
srcIdX = (int )(srcfIdX);
srcIdY = (int )(srcfIdY);
weightX[1 ] = srcfIdX - srcIdX;
weightX[0 ] = 1.0f - weightX[1 ];
weightY[1 ] = srcfIdY - srcIdY;
weightY[0 ] = 1.0f - weightY[1 ];
int value = (srcImage[(srcIdY * srcW + srcIdX)] * weightX[0 ] + srcImage[(srcIdY * srcW + clamp_g(srcIdX + 1 , 0 , srcW - 1 ))] * weightX[1 ]) * weightY[0 ] +
(srcImage[(clamp_g(srcIdY + 1 , 0 , srcH - 1 ) * srcW + srcIdX)] * weightX[0 ] + srcImage[(clamp_g(srcIdY + 1 , 0 , srcH - 1 ) * srcW + clamp_g(srcIdX + 1 , 0 , srcW - 1 ))] * weightX[1 ]) * weightY[1 ];
PixelRoChannels(destImage, j, i, destW, destH, value, cammeraId, angle, 1 , 0 );
}
}
for (i = 0 ; i < destH; i++)
{
for (j = 0 ; j < destW; j++)
{
int srcVUW = srcW / 2 ;
int srcVUH = srcH / 2 ;
int destVUW = destW / 2 ;
int destVUH = destH / 2 ;
int destVUy = i / 2 ;
int destVUx = j / 2 ;
int UVsrcIdX = 0 ;
int UVsrcIdY = 0 ;
float UVsrcfIdX = 0.0f ;
float UVsrcfIdY = 0.0f ;
float UVweightX[2 ] = { 0.0f };
float UVweightY[2 ] = { 0.0f };
UVsrcfIdX = destVUx * timeX + x0 / 2 ;
UVsrcfIdY = destVUy * timeY + y0 / 2 ;
UVsrcIdX = (int )(UVsrcfIdX);
UVsrcIdY = (int )(UVsrcfIdY);
UVweightX[1 ] = UVsrcfIdX - UVsrcIdX;
UVweightX[0 ] = 1.0f - UVweightX[1 ];
UVweightY[1 ] = UVsrcfIdY - UVsrcIdY;
UVweightY[0 ] = 1.0f - UVweightY[1 ];
int value0 = (srcUV[(UVsrcIdY * srcVUW + UVsrcIdX) * 2 + 0 ] * UVweightX[0 ] + srcUV[(UVsrcIdY * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 0 ] * UVweightX[1 ]) * UVweightY[0 ] +
(srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + UVsrcIdX) * 2 + 0 ] * UVweightX[0 ] + srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 0 ] * UVweightX[1 ]) * UVweightY[1 ];
int value1 = (srcUV[(UVsrcIdY * srcVUW + UVsrcIdX) * 2 + 1 ] * UVweightX[0 ] + srcUV[(UVsrcIdY * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 1 ] * UVweightX[1 ]) * UVweightY[0 ] +
(srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + UVsrcIdX) * 2 + 1 ] * UVweightX[0 ] + srcUV[(clamp_g(UVsrcIdY + 1 , 0 , srcVUH - 1 ) * srcVUW + clamp_g(UVsrcIdX + 1 , 0 , srcVUW - 1 )) * 2 + 1 ] * UVweightX[1 ]) * UVweightY[1 ];
PixelRoChannels(destUV, destVUx, destVUy, destVUW, destVUH, value0, cammeraId, angle, 2 , 0 );
PixelRoChannels(destUV, destVUx, destVUy, destVUW, destVUH, value1, cammeraId, angle, 2 , 1 );
}
}
return 0 ;
}