NV12 数据的抠图


// 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;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值