IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 将YUV转成RBG属性的图片(C++) -> 正文阅读

[人工智能]将YUV转成RBG属性的图片(C++)

概念解析

YUV是指亮度参量和色度参量分开表示的像素格式,而这样分开的好处就是不但可以避免相互干扰,还可以降低色度的采样率而不会对图像质量影响太大。

RGB是一种颜色编码方法

RGB 三个字母分别代表了 红、绿、蓝,这三种颜色作为三个基底颜色,将它们以不同的比例相加,可以产生多种多样的颜色。RGB 图像中,每个像素点都有红、绿、蓝三个基底颜色,其中每种原色都占用 8 bit,也就是一个字节(0-255),那么一个像素点也就占用 24 bit,也就是3个字节

在图像显示中,一张 1280 * 720 大小的图片,就代表着它有 1280 * 720 个像素点。也就是一个矩阵,其中每一个像素点的颜色显示都采用 RGB 编码方法,将 RGB 分别取不同的值,就会展示不同的颜色,
就占用 1280 * 720 * 3(Byte) / 1024 / 1024 = 2.63 MB 存储空间。

对于图像显示器来说,它是通过 RGB 模型来显示图像的,也就是某个图片,我们可以查看他的属性,很多都是RGB模式显示的。而在传输图像数据时又是使用 YUV 模型,这是因为 YUV 模型可以节省带宽
因此就需要采集图像时将 RGB 模型转换到 YUV 模型,显示时再将 YUV 模型转换为 RGB 模型。

转换

RGB 到 YUV 的转换,就是将图像所有像素点的 R、G、B 分量转换到 Y、U、V 分量。
每个像素点有三个分量。也就是三个变量的值。
下面是互转公式
在这里插入图片描述

C++代码

#include <iostream>
#include <fstream>

using namespace std;

#define IN_IMG_FILE_NAME    "3.yuv"
#define OUT_IMG_FILE_NAME   "test.bmp"
#define IMAGE_SIZE_WIDTH    1920
#define IMAGE_SIZE_HEIGHT   1080
#define IMAGE_SIZE_COEFF    3

typedef unsigned char U8;
typedef struct
{
    unsigned int bfsize;
    unsigned short reserved1;
    unsigned short reserved2;
    unsigned int bfoffBits;
} Bitmapfileheader;

typedef struct
{
    unsigned int bisize;
    int biwidth;
    int biheight;
    unsigned short biplanes;
    unsigned short bibitcount;
    unsigned int bicompression;
    unsigned int bisizeimage;
    int bixpels;
    int biypels;
    unsigned int biclrused;
    unsigned int biclrim;
} Bitmapinfoheader;



int readImgFile(const char *filename, unsigned char *buff, ssize_t size)
{
    int err = 0;
    ifstream in_img(filename, ios::in);

    do
    {
        if (!in_img.is_open())
        {
            cout << "open img file" << filename << "error" << endl;
            err = 1;
            break;
        }

        in_img.read(static_cast<char*>(static_cast<void*>(buff)), size);
        in_img.close();

    } while (0);

    return err;
}


bool Yuv420ToRgb(U8* pYUV, U8* pRGB, int width, int height)
{
    //找到Y、U、V在内存中的首地址
    U8* pY = pYUV;
    U8* pU = pYUV + height*width;
    U8* pV = pU + (height*width / 4);

    U8* pBGR = NULL;
    U8 R = 0;
    U8 G = 0;
    U8 B = 0;
    U8 Y = 0;
    U8 U = 0;
    U8 V = 0;
    double temp = 0;
    //矩阵处理,对每个像素点进行转换
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            //找到相应的RGB首地址
            pBGR = pRGB + i*width * 3 + j * 3;

            //取Y、U、V的数据值
            Y = *(pY + i*width + j);
            U = *pU;
            V = *pV;
            //yuv转rgb公式
            //yuv转rgb公式
            temp = Y + ((1.773) * (U - 128));
            B = temp < 0 ? 0 : (temp>255 ? 255 : (U8)temp);

            temp = (Y - (0.344) * (U - 128) - (0.714) * (V - 128));
            G = temp < 0 ? 0 : (temp>255 ? 255 : (U8)temp);

            temp = (Y + (1.403)*(V - 128));
            R = temp < 0 ? 0 : (temp>255 ? 255 : (U8)temp);

            //将转化后的rgb保存在rgb内存中,注意放入的顺序b是最低位
            *pBGR = B;
            *(pBGR + 1) = G;
            *(pBGR + 2) = R;

            if (j % 2 != 0)
            {
                *pU++;
                *pV++;
            }
        }
        if (i % 2 == 0)
        {
            pU = pU - width / 2;
            pV = pV - width / 2;
        }
    }
    return true;
}

void saveBmpFile(const char *filename, unsigned char *buff, const ssize_t size)
{
    Bitmapfileheader file_header = { 0 };
    Bitmapinfoheader info_header = { 0 };
    unsigned short file_type = 0X4d42;

    file_header.reserved1 = 0;
    file_header.reserved2 = 0;
    file_header.bfsize = 2 + sizeof(short) + sizeof(Bitmapinfoheader) + sizeof(Bitmapfileheader) + size*3;
    file_header.bfoffBits = 0X36;

    info_header.bisize = sizeof(Bitmapinfoheader);
    info_header.biwidth = IMAGE_SIZE_WIDTH;
    info_header.biheight = -IMAGE_SIZE_HEIGHT;
    info_header.biplanes = 1;
    info_header.bibitcount = 24;
    info_header.bicompression = 0;
    info_header.bisizeimage = 0;
    info_header.bixpels = 5000;
    info_header.biypels = 5000;
    info_header.biclrused = 0;
    info_header.biclrim = 0;

    ofstream img(filename, ios::out | ios::trunc);
    if (!img.is_open())
    {
        cout << "open bmp file error" <<endl;
        exit(0);
    }

    img.write(static_cast<const char*>(static_cast<void*>(&file_type)), sizeof(file_type));
    img.write(static_cast<const char*>(static_cast<void*>(&file_header)), sizeof(file_header));
    img.write(static_cast<const char*>(static_cast<void*>(&info_header)), sizeof(info_header));
    img.write(static_cast<char*>(static_cast<void*>(buff)), size);
    img.close();
}

int main()
{
    int err = 0;
    ssize_t size = 0;
    unsigned char *img_yuv = NULL;
    unsigned char *img_rgb = NULL;

    size = IMAGE_SIZE_WIDTH *IMAGE_SIZE_WIDTH * 2;

    cout << "file size is : IMAGE_SIZE_WIDTH *IMAGE_SIZE_WIDTH * 2 = "<< size <<endl;

    img_yuv = (unsigned char*)malloc(size);
    img_rgb = (unsigned char*)malloc(size);

    err = readImgFile(IN_IMG_FILE_NAME, img_yuv, size);
    if (0 != err)
    {
        cout << "read img file error" <<endl;
        exit(0);
    }

    Yuv420ToRgb(img_yuv, img_rgb, IMAGE_SIZE_WIDTH, IMAGE_SIZE_HEIGHT);

    saveBmpFile(OUT_IMG_FILE_NAME, img_rgb, size);

    return 0;
}

参考链接

https://blog.csdn.net/qq_41554005/article/details/100147657

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:11:32  更:2022-04-04 12:13:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/8 4:39:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码