arm 解决Rk1126 画框颜色变色问题(RGB转NV12)

 在Rv1126上直接对Nv12图像进行绘制时,颜色是灰色。故将Nv12转BGR后绘制图像,绘制完成后转成Nv12,BGR的图像颜色是正常的,但是NV12的图像颜色未画全,如图:

1.排查发现是RGB转NV12的函数出现问题,故百度找到一个可用的网址:RGB转换为NV12的代码_rgb转nv12-CSDN博客


//https://software.intel.com/en-us/node/503873
//YCbCr Color Model:
//    The YCbCr color space is used for component digital video and was developed as part of the ITU-R BT.601 Recommendation. YCbCr is a scaled and offset version of the YUV color space.
//    The Intel IPP functions use the following basic equations [Jack01] to convert between R'G'B' in the range 0-255 and Y'Cb'Cr' (this notation means that all components are derived from gamma-corrected R'G'B'):
//    Y' = 0.257*R' + 0.504*G' + 0.098*B' + 16
//    Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
//    Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
 
 
//Y' = 0.257*R' + 0.504*G' + 0.098*B' + 16
static float Rgb2Y(float r0, float g0, float b0)
{
    float y0 = 0.257f*r0 + 0.504f*g0 + 0.098f*b0 + 16.0f;
    return y0;
}
 
//U equals Cb'
//Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
static float Rgb2U(float r0, float g0, float b0)
{
    float u0 = -0.148f*r0 - 0.291f*g0 + 0.439f*b0 + 128.0f;
    return u0;
}
 
//V equals Cr'
//Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
static float Rgb2V(float r0, float g0, float b0)
{
    float v0 = 0.439f*r0 - 0.368f*g0 - 0.071f*b0 + 128.0f;
    return v0;
}
 
//Convert two rows from RGB to two Y rows, and one row of interleaved U,V.
//I0 and I1 points two sequential source rows.
//I0 -> rgbrgbrgbrgbrgbrgb...
//I1 -> rgbrgbrgbrgbrgbrgb...
//Y0 and Y1 points two sequential destination rows of Y plane.
//Y0 -> yyyyyy
//Y1 -> yyyyyy
//UV0 points destination rows of interleaved UV plane.
//UV0 -> uvuvuv
static void Rgb2NV12TwoRows(const unsigned char I0[],
                            const unsigned char I1[],
                            int step,
                            const int image_width,
                            unsigned char Y0[],
                            unsigned char Y1[],
                            unsigned char UV0[])
{
    int x;  //Column index
 
    //Process 4 source pixels per iteration (2 pixels of row I0 and 2 pixels of row I1).
    for (x = 0; x < image_width; x += 2)
    {
        //Load R,G,B elements from first row (and convert to float).
        float r00 = (float)I0[x*step + 0];
        float g00 = (float)I0[x*step + 1];
        float b00 = (float)I0[x*step + 2];
 
        //Load next R,G,B elements from first row (and convert to float).
        float r01 = (float)I0[x*step + step+0];
        float g01 = (float)I0[x*step + step+1];
        float b01 = (float)I0[x*step + step+2];
 
        //Load R,G,B elements from second row (and convert to float).
        float r10 = (float)I1[x*step + 0];
        float g10 = (float)I1[x*step + 1];
        float b10 = (float)I1[x*step + 2];
 
        //Load next R,G,B elements from second row (and convert to float).
        float r11 = (float)I1[x*step + step+0];
        float g11 = (float)I1[x*step + step+1];
        float b11 = (float)I1[x*step + step+2];
 
        //Calculate 4 Y elements.
        float y00 = Rgb2Y(r00, g00, b00);
        float y01 = Rgb2Y(r01, g01, b01);
        float y10 = Rgb2Y(r10, g10, b10);
        float y11 = Rgb2Y(r11, g11, b11);
 
        //Calculate 4 U elements.
        float u00 = Rgb2U(r00, g00, b00);
        float u01 = Rgb2U(r01, g01, b01);
        float u10 = Rgb2U(r10, g10, b10);
        float u11 = Rgb2U(r11, g11, b11);
 
        //Calculate 4 V elements.
        float v00 = Rgb2V(r00, g00, b00);
        float v01 = Rgb2V(r01, g01, b01);
        float v10 = Rgb2V(r10, g10, b10);
        float v11 = Rgb2V(r11, g11, b11);
 
        //Calculate destination U element: average of 2x2 "original" U elements.
        float u0 = (u00 + u01 + u10 + u11)*0.25f;
 
        //Calculate destination V element: average of 2x2 "original" V elements.
        float v0 = (v00 + v01 + v10 + v11)*0.25f;
 
        //Store 4 Y elements (two in first row and two in second row).
        Y0[x + 0]    = (unsigned char)(y00 + 0.5f);
        Y0[x + 1]    = (unsigned char)(y01 + 0.5f);
        Y1[x + 0]    = (unsigned char)(y10 + 0.5f);
        Y1[x + 1]    = (unsigned char)(y11 + 0.5f);
 
        //Store destination U element.
        UV0[x + 0]    = (unsigned char)(u0 + 0.5f);
 
        //Store destination V element (next to stored U element).
        UV0[x + 1]    = (unsigned char)(v0 + 0.5f);
    }
}
 
 
//Convert image I from pixel ordered RGB to NV12 format.
//I - Input image in pixel ordered RGB format
//image_width - Number of columns of I
//image_height - Number of rows of I
//J - Destination "image" in NV12 format.
 
//I is pixel ordered RGB color format (size in bytes is image_width*image_height*3):
//RGBRGBRGBRGBRGBRGB
//RGBRGBRGBRGBRGBRGB
//RGBRGBRGBRGBRGBRGB
//RGBRGBRGBRGBRGBRGB
//
//J is in NV12 format (size in bytes is image_width*image_height*3/2):
//YYYYYY
//YYYYYY
//UVUVUV
//Each element of destination U is average of 2x2 "original" U elements
//Each element of destination V is average of 2x2 "original" V elements
//
//Limitations:
//1. image_width must be a multiple of 2.
//2. image_height must be a multiple of 2.
//3. I and J must be two separate arrays (in place computation is not supported). 
void Rgb2NV12(const unsigned char I[], int step,
              const int image_width, 
              const int image_height,
              unsigned char J[])
{
    //In NV12 format, UV plane starts below Y plane.
    unsigned char *UV = &J[image_width*image_height];
 
    //I0 and I1 points two sequential source rows.
    const unsigned char *I0;  //I0 -> rgbrgbrgbrgbrgbrgb...
    const unsigned char *I1;  //I1 -> rgbrgbrgbrgbrgbrgb...
 
    //Y0 and Y1 points two sequential destination rows of Y plane.
    unsigned char *Y0;    //Y0 -> yyyyyy
    unsigned char *Y1;    //Y1 -> yyyyyy
 
    //UV0 points destination rows of interleaved UV plane.
    unsigned char *UV0; //UV0 -> uvuvuv
 
    int y;  //Row index
 
    //In each iteration: process two rows of Y plane, and one row of interleaved UV plane.
    for (y = 0; y < image_height; y += 2)
    {
        I0 = &I[y*image_width*step];        //Input row width is image_width*3 bytes (each pixel is R,G,B).
        I1 = &I[(y+1)*image_width*step];
 
        Y0 = &J[y*image_width];            //Output Y row width is image_width bytes (one Y element per pixel).
        Y1 = &J[(y+1)*image_width];
 
        UV0 = &UV[(y/2)*image_width];    //Output UV row - width is same as Y row width.
 
        //Process two source rows into: Two Y destination row, and one destination interleaved U,V row.
        Rgb2NV12TwoRows(I0,
                        I1,
                        step,
                        image_width,
                        Y0,
                        Y1,
                        UV0);
    }
}
 
 

调用:

cv::Mat m_stJpg_640x384 = cv::imread("D:\\ImageToNv12\\111.jpg");
    if (!m_stJpg_640x384.empty()) {
        cv::cvtColor(m_stJpg_640x384, m_stJpg_640x384, COLOR_BGR2RGB);

        unsigned char* pData = new unsigned char[1920 * 1080 * 3];

        Rgb2NV12(m_stJpg_640x384.data, 3/*RGB为3,RGBA为4*/, m_stJpg_640x384.cols, m_stJpg_640x384.rows, pData);
        WriteFile("m.yuv", "wb+", pData, m_stJpg_640x384.cols * m_stJpg_640x384.rows * 3 / 2);

        delete[] pData;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/482164.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【JS】滑动验证实现

功能需求&#xff1a;&#xff08;图片可根据自行更换&#xff09; 1.、右侧标签的位置是随机生成&#xff0c;左侧标签和右侧标签的垂直位置是一致的&#xff0c; 2、通过滑动条控制左侧标签与右侧标签重叠&#xff08;误差控制在2px&#xff09;表示验证通过&#xff0c; …

安卓手机系统跳过app启动广告软件

跳过广告关于此应用声明&#xff1a; 应用利用了安卓系统的辅助功能API&#xff0c;可以读取您手机屏幕上显示的所有内容&#xff0c;并且可以以您的名义进行屏幕点击等操作。* 轻量无广告&#xff0c;不联网&#xff0c;也不需要任何权限&#xff1b;* 请务必在系统设置中开启…

链表oj测试题(上)

链表的申明&#xff1a; struct ListNode {int val;struct ListNode* next; }; 1.题1 删除指定元素 例如&#xff1a;链表1 2 6 3 4 5 6&#xff0c;然后选择删除元素6&#xff0c;返回的链表为1 2 3 4 5 。 代码演示&#xff1a; typedef struct ListNode ListNode;List…

Linux文件 profile、bashrc、bash_profile区别

Linux系统中&#xff0c;有三种文件 出现的非常频繁&#xff0c;那就是 profile、bash_profile、bashrc 文件。 1、profile 作用 profile&#xff0c;路径&#xff1a;/etc/profile&#xff0c;用于设置系统级的环境变量和启动程序&#xff0c;在这个文件下配置会对所有用户…

学习刷题-12

3.22 hw机试【双指针】 Leetcode674 最长连续递增序列 给定一个未经排序的整数数组&#xff0c;找到最长且 连续递增的子序列&#xff0c;并返回该序列的长度。 双指针 一个慢指针一个快指针 慢指针记录递增子序列起点&#xff0c;快指针去寻找还在当前递增子序列的最后一…

C++例子

#include<iostream> using namespace std;//抽象类 //抽象cpu类 class CPU { public:virtual void calcuate()0; }; //抽象显卡类 class VideoCard { public:virtual void display()0; }; //抽象内存条类 class Memory { public:virtual void storage()0;};//电脑类 clas…

leetcode 150.逆波兰表达式求值

题目 思路 逆波兰表达式也是经典的栈的应用问题。 先说什么是逆波兰表达式&#xff08;也叫后缀表达式&#xff09; 我们习惯的是这样的表达式&#xff1a;1 2 / 3 ,这也叫中缀表达式。 但是对于计算机来说不好理解&#xff0c;当从左扫描到 2 的时候还需要再判断2后面是什…

损失函数篇 | YOLOv8更换损失函数之CIoU / DIoU / EIoU / GIoU / SIoU / WIoU

前言:Hello大家好,我是小哥谈。损失函数是机器学习中用来衡量模型预测值与真实值之间差异的函数。在训练模型时,我们希望通过不断调整模型参数,使得损失函数的值最小化,从而使得模型的预测值更加接近真实值。不同的损失函数适用于不同的问题,例如均方误差损失函数适用于回…

vue2从基础到高级学习笔记

在实际的工作中,我常使用vue的用法去实现效果,但是你要是问我为什么这样写,它的原理是啥就答不上来了。对vue的认知一直停留在表面,写这篇文章主要是为了理清并弄透彻vue的原理。 学习目标 1 学会一些基本用法的原理 2 弄懂vue核心设计原理 3 掌握vue高级api的用法 一 vue…

基于springboot+vue的小型诊疗预约平台

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

蓝桥杯-单片机基础8——上下位机的串口通信设置(附小蜜蜂课程代码)

蓝桥杯单片机组备赛指南请查看这篇文章&#xff1a;戳此跳转蓝桥杯备赛指南文章 本文章针对蓝桥杯-单片机组比赛开发板所写&#xff0c;代码可直接在比赛开发板上使用。 型号&#xff1a;国信天长4T开发板&#xff08;绿板&#xff09;&#xff0c;芯片&#xff1a;IAP15F2K6…

知识管理平台企业要怎么用?看完你就会了

在信息爆炸的现代社会&#xff0c;知识管理的重要性不言而喻。一个强大的知识管理平台&#xff0c;可以让团队分享和查找知识变得更容易&#xff0c;提升知识管理效率和整体工作效率。本文将引导你了解如何有效地利用知识管理平台。 1.确定目标和需求 在使用知识管理平台之前…

每日一题 --- 设计链表[力扣][Go]

设计链表 题目&#xff1a;707. 设计链表 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则…

使用ollama + webui 运行任意大模型

安装ollama https://hub.docker.com/r/ollama/ollama docker run -d -v ~/Documents/work/softs/docker/ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama验证安装 # 进入容器docker exec -it ollama bash # 运行大模型 ollama run llama2 # 发送请求&…

硬件学习件Cadence day15 做个笔记--PCB需要生成的文件格式

1.PCB生产文件类型 如下&#xff1a; 1、*.ASM 文件&#xff1a;为电子装配图文件。焊接厂可能需要。 2、*.CAM 文件&#xff1a;为PCB制版厂所需文件。 3、*.DXF 文件&#xff1a;为导出的PCB结构CAD文件。 4、*.PCB 文件&#xff1a;为PCB设计文件。 5、*.SMD 文件&#xff1…

什么是浏览器指纹识别?Maskfog指纹浏览器有用吗?

浏览器指纹识别是好是坏&#xff1f;这现在确实是一个有争议的话题。83%的消费者经常或偶尔会根据浏览历史记录看到广告。其实这就是利用了浏览器指纹技术。 如果您想了解浏览器指纹识别是什么&#xff0c;那就看下去&#xff01; 一、什么是浏览器指纹识别 浏览器指纹是指无…

JavaSE——数据类型与变量

1. 数据类型 在 Java 中数据类型主要分为两类&#xff1a; 基本数据类型 和 引用数据类型 。 基本数据类型有 四类八种 &#xff1a; 1. 四类&#xff1a;整型、浮点型、字符型以及布尔型 2. 八种&#xff1a; 数据类型关键字内存占用范围字节型byte1 个字节-128~127短整型…

计算机实体安全

计算机实体安全定义&#xff1a; 对场地环境、设施、设备和载体、人员采取的安全对策和措施。 一、计算机可靠性与故障分析 1.1 计算机的可靠性 可靠性 (狭义) ■计算机在规定时间与条件下完成规定功能的 概率 ■规定条件&#xff1a;环境条件&#xff0c;使用条件&#xff0…

iOS应用审核问题解决方案及优化方法 ✨

摘要 本文将针对iOS应用提交审核时可能遇到的问题&#xff0c;如“你必须在Xcode中添加com.apple.developer.game-center密钥”&#xff0c;以及突然间提交送审报错情况进行探讨。通过大量查询资料和尝试&#xff0c;结合案例分析&#xff0c;提供了解决方案和优化方法&#x…

常用相似度计算方法总总结

一、欧几里得相似度 1、欧几里得相似度 公式如下所示&#xff1a; 2、自定义代码实现 import numpy as np def EuclideanDistance(x, y):import numpy as npx np.array(x)y np.array(y)return np.sqrt(np.sum(np.square(x-y)))# 示例数据 # 用户1 的A B C D E商品数据 [3.3…