// src 原始数据 是nv12 的YUV数据,直接从手机摄像头采集的数据
// dest 截取的数据 开辟的空间大小为(x1 - x0 + 1) * (y1 - y0 + 1)包含两边的点
// srcW 原始数据的宽
// srcH 原始数据的高
// x0 y0 左上角的坐标点 (必须是偶数)
// x1 y1 右下角的坐标点 (必须是奇数)
#define CLAMP(a, s, m) ((a) < (s)? (s) : ((a) > (m) ? (m) : (a)))
int NV12CutImage(unsigned char * src, unsigned char * dest, int srcW, int srcH, int x0, int y0, int x1, int y1)
{
int dstw = 0;
int dsth = 0;
int i = 0;
int j = 0;
int k = 0;
int srcwh = 0;
int dstwh = 0;
dstw = x1 - x0 + 1;
dsth = y1 - y0 + 1;
unsigned char * srcUV = src + srcW * srcH;
unsigned char * destUV = dest + dstw * dsth;
for (i = y0; i <= y1; i++)
{
for (j = x0; j <= x1; j++)
{
dest[(i - y0) * dstw + (j - x0)] = src[i * srcW + j];
destUV[((i - y0) / 2 * (dstw / 2) + (j - x0) / 2) * 2 + 0] = srcUV[((i / 2) * (srcW / 2) + (j / 2)) * 2 + 0];
destUV[((i - y0) / 2 * (dstw / 2) + (j - x0) / 2) * 2 + 1] = srcUV[((i / 2) * (srcW / 2) + (j / 2)) * 2 + 1];
}
}
return 0;
}
NV21或者NV12数据抠图后插值为指定大小
srcImage 输入数据NV12或者NV21
srcW 输入数据的宽
srcH 输入数据的高
x0 y0 x1 y1 左上角和右下角的坐标
destImage 输出指针
lineW 输出宽
lineH 输出高
int NVLinearRect(unsigned char * srcImage, int srcW, int srcH, int x0, int y0, int x1, int y1, unsigned char *destImage, int lineW, int lineH)
{
float timeX = 0.0f;
float timeY = 0.0f;
int width = x1 - x0 + 1;
int height = y1 - y0 + 1;
int i = 0;
int j = 0;
int k = 0;
float temp = 0.0f;
timeX = width * 1.0f / lineW;
timeY = height * 1.0f / lineH;
unsigned char * srcUV = srcImage + srcW * srcH;
unsigned char * destUV = destImage + lineW * lineH;
for (i = 0; i < lineH; i++)
{
for (j = 0; j < lineW; 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];
temp = (srcImage[(srcIdY * srcW + srcIdX)] * weightX[0] + srcImage[(srcIdY * srcW + CLAMP(srcIdX + 1, 0, srcW - 1))] * weightX[1]) * weightY[0] +
(srcImage[(CLAMP(srcIdY + 1, 0, srcH - 1) * srcW + srcIdX)] * weightX[0] + srcImage[(CLAMP(srcIdY + 1, 0, srcH - 1) * srcW + CLAMP(srcIdX + 1, 0, srcW - 1))] * weightX[1]) * weightY[1];
destImage[(i * lineW + j)] = (unsigned char)((int)temp);
if (0 == i % 2 && 0 == j % 2)
{
int srcVUW = srcW / 2;
int srcVUH = srcH / 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];
temp =
(srcUV[(UVsrcIdY * srcVUW + UVsrcIdX) * 2 + 0] * UVweightX[0] + srcUV[(UVsrcIdY * srcVUW + CLAMP(UVsrcIdX + 1, 0, srcVUW - 1)) * 2 + 0] * UVweightX[1]) * UVweightY[0] +
(srcUV[(CLAMP(UVsrcIdY + 1, 0, srcVUH - 1) * srcVUW + UVsrcIdX) * 2 + 0] * UVweightX[0] + srcUV[(CLAMP(UVsrcIdY + 1, 0, srcVUH - 1) * srcVUW + CLAMP(UVsrcIdX + 1, 0, srcVUW - 1)) * 2 + 0] * UVweightX[1]) * UVweightY[1];
destUV[(i / 2 * (lineW / 2) + j / 2) * 2 + 0] = (unsigned char)((int)temp);
temp =
(srcUV[(UVsrcIdY * srcVUW + UVsrcIdX) * 2 + 1] * UVweightX[0] + srcUV[(UVsrcIdY * srcVUW + CLAMP(UVsrcIdX + 1, 0, srcVUW - 1)) * 2 + 1] * UVweightX[1]) * UVweightY[0] +
(srcUV[(CLAMP(UVsrcIdY + 1, 0, srcVUH - 1) * srcVUW + UVsrcIdX) * 2 + 1] * UVweightX[0] + srcUV[(CLAMP(UVsrcIdY + 1, 0, srcVUH - 1) * srcVUW + CLAMP(UVsrcIdX + 1, 0, srcVUW - 1)) * 2 + 1] * UVweightX[1]) * UVweightY[1];
destUV[(i / 2 * (lineW / 2) + j / 2) * 2 + 1] = (unsigned char)((int)temp);
}
}
}
return 0;
}