C++ 实现读取YUV文件并OSD叠加

#include <opencv2/opencv.hpp>
#include <fstream>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <./opencv2/highgui/highgui_c.h>
#include <stdio.h>

using namespace std;
using namespace cv;

const int width = 1000;
const int height = 1500;
const int framesize = width * height * 3 / 2;

int main()
{
    ifstream fin("demo.yuv", ios_base::in | ios_base::binary);
    if (!fin)
    {
        cout << "the file is error" << endl;
        return -1;
    }

    fin.seekg(0, ios::end);     // 设置文件指针到文件流的尾部
    streampos ps = fin.tellg(); // 指出当前的文件指针
    unsigned long fileSize = ps;
    cout << "file size: " << ps << endl;           // 输出指针的位置
    unsigned frameCount = ps / framesize;          // 帧大小
    cout << "frameNumber: " << frameCount << endl; // 输出帧数
    fin.close();

    FILE *fileIn = fopen("demo.yuv", "rb");
    if (!fileIn)
    {
        cout << "Error opening file." << endl;
        return -1;
    }

    // 分配足够的内存来存储整个 YUV 帧
    unsigned char *pYuvBuf = new unsigned char[framesize];

    // 创建窗口
    namedWindow("yuv", WINDOW_NORMAL);

    // 循环读取每一帧
    for (int i = 0; i < frameCount; ++i)
    {
        // 读取整个 YUV 帧
        if (fread(pYuvBuf, 1, framesize, fileIn) != framesize)
        {
            cout << "Error reading YUV data." << endl;
            break;
        }

        // 创建 Mat 对象来存储 YUV 数据
        cv::Mat yuvImg(height, width, CV_8UC1, pYuvBuf);

        // 计算矩形的位置
        int rectX = 200;
        int rectY = 300;
        int rectWidth = 300;
        int rectHeight = 300;

        // 修改 Y 分量以模拟矩形
        for (int x = rectX; x < rectX + rectWidth; x++)
        {
            if (x < rectX + rectWidth / 3 || x > (rectX + rectWidth) - rectWidth / 3)
            {
                for (int y = rectY; y < rectY + rectHeight; y++)
                {
                    if (y < rectY + rectHeight / 3 || y > (rectY + rectHeight) - rectHeight / 3)
                    {
                        if (y < rectY + 5 || y > (rectY + rectHeight) - 5 || x < rectX + 5 || x > (rectX + rectWidth) - 5)
                        {
                            // 获取 Y 分量的位置
                            int index = y * width + x;
                            // 降低 Y 分量的值以使该区域变暗
                            pYuvBuf[index] -= 50; // 降低亮度
                        }
                    }
                }
            }
        }
        // 设置中点
        //  定义圆形的中心点和半径
        int centerX = rectX + rectWidth / 2;
        int centerY = rectY + rectHeight / 2;
        int radius = 5;

        // 遍历圆形区域内的每个像素
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                // 检查当前像素是否在圆形内
                if ((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY) <= radius * radius)
                {
                    // 获取Y分量的位置
                    int yuvIndex = y * width + x;
                    // 降低亮度(例如减少50)
                    pYuvBuf[yuvIndex] -= 50; // 注意不要让Y分量小于0
                }
            }
        }

        // 显示 YUV 图像
        imshow("yuv", yuvImg);
        cvWaitKey(0);
    }

    // 清理资源
    delete[] pYuvBuf;
    fclose(fileIn);
    destroyAllWindows();

    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在MATLAB中,可以使用`VideoReader`函数来读取YUV文件,并使用`imwrite`函数将每一帧图片保存为文件。 首先,需要创建一个`VideoReader`对象,指定YUV文件的路径和格式(如420Planar、YUV422等): ```matlab videoObj = VideoReader('path/to/your/video.yuv', 'VideoFormat', 'YUV420_8'); ``` 接下来,可以使用`hasFrame`函数来检查是否还有可读的帧,然后使用`readFrame`函数读取每一帧,并使用`imwrite`函数将其保存为图片文件: ```matlab frameNum = 1; while hasFrame(videoObj) frame = readFrame(videoObj); imwrite(frame, sprintf('frame_%d.jpg', frameNum)); frameNum = frameNum + 1; end ``` 在上面的代码中,`videoObj`是`VideoReader`对象,`frame`是读取到的帧数据。`imwrite`函数将传入的帧数据保存为以帧序号命名的图片文件,如`frame_1.jpg`、`frame_2.jpg`等。 要注意的是,YUV文件中每一帧的尺寸和颜色空间可能不同,因此在读取每一帧之前,需要根据文件的格式进行适当的设置。另外,需要根据实际情况调整保存图片的格式和路径。 希望这个回答对您有帮助! ### 回答2: MATLAB可以使用VideoReader函数来读取YUV文件,并使用imwrite函数将每一帧保存为图片文件。 首先,需要使用VideoReader函数创建一个视频读取对象,指定输入的YUV文件名: ```matlab v = VideoReader('input.yuv'); ``` 接下来,可以使用readFrame函数逐帧读取YUV文件中的图像,并使用imwrite函数将每一帧保存为图片文件。可以通过循环来读取文件中的所有帧并保存: ```matlab frameIndex = 1; % 用于追踪帧的索引 while hasFrame(v) frame = readFrame(v); % 读取下一帧图像 filename = sprintf('frame%d.jpg', frameIndex); % 根据帧索引生成保存的文件名 imwrite(frame, filename); % 保存图像为JPEG文件 frameIndex = frameIndex + 1; % 帧索引自增 end ``` 上述代码中,使用sprintf函数生成每一帧保存的文件名,命名为frame1.jpg、frame2.jpg等。imwrite函数将每一帧图像保存为JPEG文件。 最终,代码将会读取YUV文件中的每一帧图像,并将每一帧保存为以帧索引命名的图片文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值