OpenCV3.4.16 Visual Studio将.MP4文件转换成YUV420格式

VS2017

下载

Releases - OpenCV

挑一个中意的版本 (3.4.16) windows下载

解压提取后这个样子

加入环境变量

进行相关配置:


注意:网上很多教程没有这一步,会报那种找不到dll文件的错误,是因为没有将opencv里面的相关文件复制到C盘中的文件夹里面

操作方法:

将bin目录下面的opencv_worldxxxx.dll和opencv_worldxxxd.dll文件复制到C:\Windows\SysWOW64这个文件夹里面; (xxx是你具体的一个号 比如 我的是)

将bin目录里面的opencv_videoio_ffmpeg450_64.dll和opencv_world450d.dll文件复制到C:\Windows\System32这个文件夹里面;

如果报错找不到 opencv_xxxxxxx.lib文件,就试试看把相关lib文件复制到C:\Windows\System32和C:\Windows\SysWOW64这两个文件夹里面!)

之后打开VS2017


1、新建一个项目,我这里建了一个空项目

2、进入属性管理器,菜单栏->视图->其他窗口->属性管理器

3、对Debug|X64进行配置,右键Microsoft.Cpp.x64.user,点击属性

4、这里我们对属性中的 VC++目录->包含目录和VC++目录->库目录进行添加相关路径,对 链接器->输入->附加依赖项进行添加相关路径

5、包含目录中加入

D:\Program Files\opencv\build\include

D:\Program Files\opencv\build\include\opencv2

库目录中加入

D:\Program Files\opencv\build\x64\vc15\lib

6、链接器->输入->附加依赖项中加入

!!!!!!!补充:opencv_world450.lib是release模式的、opencv_world450d.lib是Debug模式下的。如若在Debug模式下读不出来图片,那么请删除opencv_world450.lib再尝试一下

opencv_world450.lib

opencv_world450d.lib

之后整个测试代码:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
int main()
{
	Mat src = imread("D:\\desktop\\landi.jpg");
	if (src.empty())
	{
		printf("could not load image…\n");
		return -1;
	}
	namedWindow("test opencv setup", 100);
	imshow("test opencv setup", src);
	waitKey(0);
	return 0;
}

就OK了

原文链接:Opencv4.5.0+VS2019+win10环境配置_opencv4.5.10配置-CSDN博客

 将.MP4文件转换成YUV420格式

#define _CRT_SECURE_NO_WARNINGS
#include <opencv2/opencv.hpp>

int main() {
	// 打开MP4文件
	cv::VideoCapture cap("input.mp4");

	if (!cap.isOpened()) {
		std::cerr << "Error: Could not open MP4 file." << std::endl;
		return -1;
	}

	// 获取视频帧的宽度和高度
	int frame_width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
	int frame_height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));

	// 打开YUV文件以供写入
	FILE* yuvFile = fopen("output.yuv", "wb");

	if (!yuvFile) {
		std::cerr << "Error: Could not create YUV output file." << std::endl;
		return -1;
	}

	// 用于存储帧的Mat对象
	cv::Mat frame;

	while (true) {
		cap >> frame;

		if (frame.empty()) {
			break;
		}

		// 将BGR帧转换为YUV420(I420)格式
		cv::Mat yuv420Frame;
		cv::cvtColor(frame, yuv420Frame, cv::COLOR_BGR2YUV_I420);
		//8*4
		// 从I420格式提取Y、U和V分量
		const unsigned char* yuv_data = yuv420Frame.data;
		const unsigned char* y_data = yuv_data;
		const unsigned char* u_data = y_data + frame_width * frame_height;
		const unsigned char* v_data = u_data + (frame_width * frame_height / 4); // U和V分量大小相同

		// 将Y分量写入YUV文件
		fwrite(y_data, 1, frame_width * frame_height, yuvFile);

		// 将U和V分量写入YUV文件
		fwrite(u_data, 1, frame_width * frame_height / 4, yuvFile);
		fwrite(v_data, 1, frame_width * frame_height / 4, yuvFile);
	}

	// 释放VideoCapture和关闭YUV文件
	cap.release();
	fclose(yuvFile);

	return 0;
}

 将.MP4文件转换成NV12格式

注意文件尾缀并不影响,NV12指的是图像内部的存储格式,文件尾缀随便 可以是.yuv 

#define _CRT_SECURE_NO_WARNINGS
#include <opencv2/opencv.hpp>

int main() {
	// 打开MP4文件
	cv::VideoCapture cap("input.mp4");

	if (!cap.isOpened()) {
		std::cerr << "Error: Could not open MP4 file." << std::endl;
		return -1;
	}

	// 获取视频帧的宽度和高度
	int frame_width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
	int frame_height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));

	// 打开YUV文件以供写入
	FILE* yuvFile = fopen("output.yuv", "wb");

	if (!yuvFile) {
		std::cerr << "Error: Could not create YUV output file." << std::endl;
		return -1;
	}

	// 用于存储帧的Mat对象
	cv::Mat frame;

	while (true) {
		cap >> frame;

		if (frame.empty()) {
			break;
		}

		// 将BGR帧转换为YUV420(I420)格式
		cv::Mat yuv420Frame;
		cv::cvtColor(frame, yuv420Frame, cv::COLOR_BGR2YUV_I420);

		// 从I420格式提取Y、U和V分量
		const unsigned char* yuv_data = yuv420Frame.data;
		const unsigned char* y_data = yuv_data;
		const unsigned char* u_data = yuv_data + frame_width * frame_height;
		const unsigned char* v_data = u_data + (frame_width * frame_height / 4); // U和V分量大小相同

		// 将Y分量写入YUV文件
		fwrite(y_data, 1, frame_width * frame_height, yuvFile);

		// 将UV分量按交替顺序写入YUV文件
		for (int i = 0; i < frame_width * frame_height / 4; i++) {
			fwrite(u_data + i, 1, 1, yuvFile);
			fwrite(v_data + i, 1, 1, yuvFile);
		}
	}

	// 释放VideoCapture和关闭YUV文件
	cap.release();
	fclose(yuvFile);

	return 0;
}

注意两者的区别仅仅是 uv分量的存储方式. 只要明确知道nv12格式uv分量是交替存储这个核心知识点

播放yuv类型的播放器是

先调整分辨率,根据代码和 真实的自己数据  

(

int frame_width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
 int frame_height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));

)

改成2560*1440(点击 Size  -> custom)  然后Color切换成NV12格式

就变成了下面  当然还要点击Zoom缩放下

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值