欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OpenCV Matlab生成視頻倒放功能

 更新時(shí)間:2022年01月07日 11:09:29   作者:jing_zhong  
這篇文章主要介紹了OpenCV Matlab生成視頻倒放功能,大家都知道不少帶聲音視頻的后綴名往往都是.mp4,那么如何獲取里面的音頻呢?本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧

引言

相信不少朋友在各大短視頻平臺(tái)看到很多運(yùn)動(dòng)健身達(dá)人的訓(xùn)練視頻,本人比較喜歡的運(yùn)動(dòng)達(dá)人有搬磚小偉大師兄歐克等,街頭徒手健身實(shí)則美妙,既能考驗(yàn)人的意志 ,又能強(qiáng)健體魄。不得不說,運(yùn)動(dòng)UFC競技、武術(shù)、拳擊)和藝術(shù)書法繪畫、歌曲、舞蹈)著實(shí)能給人帶來直觀的真實(shí)體驗(yàn),也能激發(fā)自身的運(yùn)動(dòng)潛力,對(duì)于經(jīng)常久坐從事腦力運(yùn)動(dòng)的人,他們的閑暇時(shí)間除了關(guān)注科技、軍事生活?yuàn)蕵?/strong>,還應(yīng)該接受藝術(shù)和體育的熏陶,適當(dāng)?shù)剡M(jìn)行體力勞動(dòng)也是長壽的秘訣,有利于個(gè)人和社會(huì)的可持續(xù)發(fā)展。每天鍛煉一小時(shí),健康工作五十年,幸福生活一輩子?。?!

1、需求分析

互聯(lián)網(wǎng)上海量的文本(plain text)、圖片(picture or image)聲音(audio)、視頻(video)等文件大量涌入,層出不窮,這些數(shù)據(jù)在網(wǎng)絡(luò)上存儲(chǔ)、傳輸和下載,各種硬件設(shè)備、傳感器技術(shù)的發(fā)展使得數(shù)據(jù)獲取方式變得越來越多樣化。這里關(guān)注視頻文件,視頻是由一系列連續(xù)的幀按照時(shí)間順序組合排列而形成的,因此它的本質(zhì)還是一個(gè)又一個(gè)幀,一個(gè)幀就是一個(gè)畫面,一個(gè)畫面就是一張圖片,因此連續(xù)流暢的視頻需要保證每秒的幀數(shù)大于等于24,而對(duì)于經(jīng)常玩大型網(wǎng)絡(luò)三維游戲(如吃雞PLAYERUNKNOWN'S BATTLEGROUNDS、CSGO、CF)的玩家而言,他們可能對(duì)這個(gè)更有了解,就是游戲?qū)崟r(shí)畫面都會(huì)顯示當(dāng)前幀率FPS(Frame Per Second,每秒的幀數(shù)),更高的幀率(普通電腦60以上,游戲本150~220,發(fā)燒本可能達(dá)到300)能給高端玩家?guī)砭碌挠螒蝮w驗(yàn)。因此視頻處理的本質(zhì)源于對(duì)各張圖片(每幀畫面)的處理。
與此對(duì)應(yīng),視頻倒放的核心思想就是將原始視頻中的圖片倒序,主要分為兩個(gè)步驟:
(1)獲取原始視頻的每一幀圖片以從小到大的序號(hào)命名后保存到本地;
(2)將所有圖片按照從大到小的順序,設(shè)置與原始視頻同樣或自定義的幀率FPS,寫入視頻。

2、環(huán)境配置(Win11+ VS 2015 + OpenCV 2.4.9 / Matlab R2021a)

Win 11 64位

Visual Studio 2015

OpenCV 2.4.9

Matlab R2021a

3、OpenCV實(shí)現(xiàn)視頻倒放(C++)

3.1 輸入原始視頻(帶聲音)

原始視頻文件VID_20210801_205259.mp4展示了我國短跑飛人蘇炳添在2020東京奧運(yùn)會(huì)男子100米半決賽中以9.83秒刷新亞洲紀(jì)錄,一站封神,他創(chuàng)造了亞洲人百米賽跑的記錄,成為了首位跑進(jìn)10秒大關(guān)的亞洲本土選手、首位踏上世界大賽百米飛人大戰(zhàn)決賽的亞洲選手、亞洲紀(jì)錄保持者。身高1米72的蘇神在百米賽道上要比博爾特多跑7步,因此他只有付出比別人更多的努力,才能和其他選手站到同一起跑線上。讓我們向蘇神致敬,向蘇神學(xué)習(xí),功夫不負(fù)有心人,勇敢拼搏無極限,不設(shè)限的人生更精彩?。?!

3.2 原始視頻轉(zhuǎn)聲音(mp4轉(zhuǎn)mp3)

不少帶聲音視頻的后綴名往往都是.mp4,那么如何獲取里面的音頻呢?其實(shí)有一種簡單取巧的方法,只需將mp4視頻文件的后綴名.mp4改為mp3音頻文件的后綴名.mp3就可以了,實(shí)測證明該辦法具有一定的有效性。

3.3 OpenCV代碼

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

string GetFileNameString(string inputfilename)
{
	string s = "";
	int length = 0;
	while (inputfilename[length] != '\0')
	{
		length++;
	}
	for (length = length - 1; length >= 0; length--)
	{
		if (inputfilename[length] == '\\')
			break;
	}
	while (inputfilename[++length] != '\0')
	{
		if (inputfilename[length] != '.')
			s += inputfilename[length];
		else
			break;
	}
	return s;
}

string GetFolderString(string inputfilename)//Obtain Path in FileNameWithPathString
{
	string s = "";
	int length = 0;
	while (inputfilename[length] != '\0')
	{
		length++;
	}
	for (length = length-1; length >= 0; length--)
	{
		if (inputfilename[length] == '\\')
			break;
	}
	for (int i = 0; i <= length; i++)
		s += inputfilename[i];
	return s;
}

string Replace_folder(string inputfilename) // replace \\ to /
{
	string s = "";
	int length = 0;
	bool flag = true;
	while (inputfilename[length] != '\0')
	{
		if (inputfilename[length] != '\\')
		{
			s += inputfilename[length];
		}
		else
		{
			s += '/';
		}
		length++;
	}
	return s;
}

int main()
{
	string inputVideofilename = "F:\\Users\\VID_20210801_205259.mp4";
	string videopath = GetFolderString(inputVideofilename);
	string picspath = videopath + ("pics_" + GetFileNameString(inputVideofilename));
	string command = "mkdir " + picspath;
	system(command.c_str());//Create the folder which is named pics in current folder
	string picfolder = Replace_folder(picspath) + "/", suffixname = ".jpg";
	cout << "圖片和視頻保存位置為:"+picfolder << endl;
	VideoCapture inputVideo(inputVideofilename);//Obtain input video
	if (!inputVideo.isOpened())
	{
		cout << "Could not open the input video." << inputVideofilename << endl;
		return -1;
	}
	else
	{
		double width = inputVideo.get(CV_CAP_PROP_FRAME_WIDTH);  // width of frame
		double height = inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT); //height of frame
		double frameRate = inputVideo.get(CV_CAP_PROP_FPS);  //frame per second
		double totalFrames = inputVideo.get(CV_CAP_PROP_FRAME_COUNT); //total number of frames

		cout << "視頻寬度=" << width << endl;
		cout << "視頻高度=" << height << endl;
		cout << "視頻總幀數(shù)=" << totalFrames << endl;
		cout << "幀率=" << frameRate << endl;

		namedWindow("RGB視頻", CV_WINDOW_NORMAL);
		namedWindow("B通道", CV_WINDOW_NORMAL);
		namedWindow("G通道", CV_WINDOW_NORMAL);
		namedWindow("R通道", CV_WINDOW_NORMAL);
		namedWindow("被Canny后的視頻", CV_WINDOW_NORMAL);
		Mat lastframe;
		int i = 0;
		while (1)
		{
			Mat frame;// 定義一個(gè)Mat變量,用于存儲(chǔ)每一幀的圖像
			inputVideo >> frame;//讀取當(dāng)前幀
			if (frame.data)
			{
				i++;
				int num_channels = frame.channels();//通道數(shù)
				Mat channels[3];
				split(frame, channels);
				Mat zeroRChannel = channels[2].clone();//將R通道全部置0
				zeroRChannel.setTo(0);
				Mat zeroGChannel = channels[1].clone();//將G通道全部置0
				zeroGChannel.setTo(0);
				Mat zeroBChannel = channels[0].clone();//將B通道全部置0
				zeroBChannel.setTo(0);

				Mat BChannels[3] = { channels[0] , zeroGChannel , zeroRChannel };
				Mat mergedBImage;
				merge(BChannels, 3, mergedBImage);

				Mat GChannels[3] = { zeroBChannel , channels[1] , zeroRChannel };
				Mat mergedGImage;
				merge(GChannels, 3, mergedGImage);
				
				Mat RChannels[3] = { zeroBChannel , zeroGChannel , channels[2] };
				Mat mergedRImage;
				merge(RChannels, 3, mergedRImage);

				Mat edges;
				cvtColor(frame, edges, COLOR_BGR2GRAY);
				blur(edges, edges, Size(5, 5));
				Canny(edges, edges, 0, 30, 3);
				imshow("RGB視頻", frame);//顯示當(dāng)前幀
				imshow("B通道", mergedBImage);
				imshow("G通道", mergedGImage);
				imshow("R通道", mergedRImage);
				imshow("被Canny后的視頻", edges);//顯示經(jīng)過處理后的當(dāng)前幀
				imwrite(picfolder + to_string(i) + suffixname, frame);
			}
			else
				break;
			waitKey(2);
		}
		cout << i << "張圖片生成成功,開始逆序合成視頻!" << endl;
		Mat frame;
		Mat src0 = imread(picfolder + to_string(i) + suffixname);
		Size size = src0.size();
		VideoWriter writer;
		writer.open(Replace_folder(videopath) + GetFileNameString(inputVideofilename)+"_NiZhuan.avi", CV_FOURCC('M', 'J', 'P', 'G'), frameRate, size, true);
		int j = i;
		for (; j >0; j--)
		{
			string path = picfolder + to_string(j) + suffixname;
			Mat src = imread(path);
			if (!src.empty())
			{
				writer.write(src);
				cout << "正在合成第" << j << "張照片" << endl;
			}
			else
				break;
		}
		if (j == 0)
			std::cout << "合成逆序視頻    Successed!" << std::endl;
		else
			std::cout << "合成逆序視頻    Failed!" << std::endl;
		return 0;
	}
}

3.4 OpenCV運(yùn)行結(jié)果

(a)前20米

(b)后80米

(c)開始讀取視頻

(d)讀取視頻結(jié)束

(e)結(jié)果文件

(f)圖片文件夾

代碼支持mp4、wmv格式的輸入視頻,在原始視頻文件夾中會(huì)看到生成的視頻文件結(jié)果VID_20210801_205259_NiZhuan.avi,將avi后綴名改為mp4后綴名也可播放。

4、Matlab實(shí)現(xiàn)視頻倒放

首先介紹一個(gè)Matlab生成動(dòng)態(tài)視頻示例:

Z = peaks;
surf(Z); 
axis tight manual 
set(gca,'nextplot','replacechildren'); 
v = VideoWriter('peaks.avi');
v.Quality = 95;
v.FrameRate = 40;
open(v);
for k = 1:200 
   surf(sin(2*pi*k/20)*Z,Z)
   frame = getframe(gcf);
   writeVideo(v,frame);
end
close(v);

4.1 Matlab代碼

4.1.1 Matlab讀取視頻并播放(三選一)

vidObj = VideoReader('1234.wmv');
vidWidth = vidObj.Width;
vidHeight = vidObj.Height;
vidFps = vidObj.FrameRate;
% 第一種播放方式
while hasFrame(vidObj)
    vidFrame = readFrame(vidObj);
    imshow(vidFrame)
    pause(1/vidObj.FrameRate);
end
% 第二種播放方式
currAxes = axes;
while hasFrame(vidObj)
    vidFrame = readFrame(vidObj);
    image(vidFrame, 'Parent', currAxes);
    currAxes.Visible = 'off';
    pause(1/vidFps);
end
% 第三種播放方式(推薦使用)
mov = struct('cdata',zeros(vidHeight,vidWidth,3,'uint8'),'colormap',[]);
vidObj.CurrentTime = 2.5; % 可設(shè)置開始時(shí)間
k = 1;
while hasFrame(vidObj)
    mov(k).cdata = readFrame(vidObj);
    imwrite(mov(k).cdata,['pics/', num2str(k),'.jpg']);
    k = k+1;
end
hf = figure;
set(hf,'position',[90 60 vidWidth vidHeight]);
movie(hf,mov,1,vidFps);

4.1.2 Matlab讀取視頻并逆轉(zhuǎn)

需要在原視頻文件夾新建一個(gè)pics文件夾,然后運(yùn)行以下代碼(實(shí)測適用于.mp4和.wmv格式的輸入視頻文件):
VideoProcessTest.m

filepath = 'D:/Program Files (x86)/MATLAB/myworkspace/';
filename = 'VID_20210801_205259';
suffixname = '.mp4';
vidObj = VideoReader([filepath,filename,suffixname]);
vidWidth = vidObj.Width;
vidHeight = vidObj.Height;
vidFps = vidObj.FrameRate;
% vidObj.CurrentTime = 2.5; % 可設(shè)置開始時(shí)間
k = 1;
while hasFrame(vidObj)
    frame = readFrame(vidObj);
    imwrite(frame,['pics/', num2str(k),'.jpg']);
    k = k+1;
end

v_all = VideoWriter([filepath,filename,'_NiZhuanMovie_ALL.avi']);
v_all.Quality = 95;
v_all.FrameRate = vidFps;
open(v_all);

v_rgb = VideoWriter([filepath,filename,'_NiZhuanMovie_RGB.avi']);
v_rgb.Quality = 95;
v_rgb.FrameRate = vidFps;
open(v_rgb);

v_r = VideoWriter([filepath,filename,'_NiZhuanMovie_R.avi']);
v_r.Quality = 95;
v_r.FrameRate = vidFps;
open(v_r);
v_g = VideoWriter([filepath,filename,'_NiZhuanMovie_G.avi']);
v_g.Quality = 95;
v_g.FrameRate = vidFps;
open(v_g);

v_b = VideoWriter([filepath,filename,'_NiZhuanMovie_B.avi']);
v_b.Quality = 95;
v_b.FrameRate = vidFps;
open(v_b);

set(gca,'nextplot','replacechildren'); 
for i = k-1:-1:1
    filename = ['D:/Program Files (x86)/MATLAB/myworkspace/pics/', num2str(i),'.jpg'];
    img = imread(filename);
    [m,n]=size(img(:,:,1));
    zero=zeros(m,n);
    rgb_r=img(:,:,1);
    rgb_g=img(:,:,2);
    rgb_b=img(:,:,3);
    R_img=cat(3,rgb_r,zero,zero);
    G_img=cat(3,zero,rgb_g,zero);
    B_img=cat(3,zero,zero,rgb_b);
    RGB_img=cat(3,rgb_r,rgb_g,rgb_b);
    subplot(2,2,1),imshow(R_img),title('紅色分量');
    subplot(2,2,2),imshow(G_img),title('綠色分量');
    subplot(2,2,3),imshow(B_img),title('藍(lán)色分量');
    subplot(2,2,4),imshow(RGB_img);
    frame = getframe(gcf);
    imwrite(frame.cdata,['./pics/ALL',num2str(i),'.jpg']);
    imwrite(RGB_img,['./pics/RGB',num2str(i),'.jpg']);
    imwrite(R_img,['./pics/R',num2str(i),'.jpg']);
    imwrite(G_img,['./pics/G',num2str(i),'.jpg']);
    imwrite(B_img,['./pics/B',num2str(i),'.jpg']);
    writeVideo(v_all,frame.cdata);
    writeVideo(v_rgb,RGB_img);
    writeVideo(v_r,R_img);
    writeVideo(v_g,G_img);
    writeVideo(v_b,B_img);
end
close(v_all);
close(v_rgb);
close(v_r);
close(v_g);
close(v_b);

4.2 Matlab運(yùn)行結(jié)果


R分量

G分量

B分量

RGB視頻

5、總結(jié)及應(yīng)用

本文主要通過利用OpenCV和Matlab兩種工具來實(shí)現(xiàn)視頻中圖片R、G、B三分量的提取、保存和逆轉(zhuǎn),同時(shí)視頻加工本質(zhì)是對(duì)圖片幀的處理,利用這兩種圖像處理API還可實(shí)現(xiàn)視頻截取(通過幀率fps和時(shí)間計(jì)算所需的幀并拼接成視頻)、多張圖片合成自定義視頻、多個(gè)視頻拼接分類、目標(biāo)提取追蹤、特征檢測、視頻邊緣檢測、添加字幕等功能,可應(yīng)用于短視頻剪輯、創(chuàng)作、應(yīng)用系統(tǒng)演示、錄課、科研、公共安全等多個(gè)領(lǐng)域。

到此這篇關(guān)于OpenCV Matlab生成倒放視頻的文章就介紹到這了,更多相關(guān)OpenCV Matlab視頻倒放內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言數(shù)據(jù)結(jié)構(gòu)順序表中的增刪改(尾插尾刪)教程示例詳解

    C語言數(shù)據(jù)結(jié)構(gòu)順序表中的增刪改(尾插尾刪)教程示例詳解

    這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)順序表中的增刪改教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • C/C++實(shí)現(xiàn)八大排序算法匯總

    C/C++實(shí)現(xiàn)八大排序算法匯總

    這篇文章主要為大家詳細(xì)介紹了C/C++實(shí)現(xiàn)八大排序算法匯總,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 深入VC回調(diào)函數(shù)的使用詳解

    深入VC回調(diào)函數(shù)的使用詳解

    本篇文章是對(duì)VC回調(diào)函數(shù)的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言結(jié)構(gòu)體占用內(nèi)存深入講解

    C語言結(jié)構(gòu)體占用內(nèi)存深入講解

    這篇文章主要給大家介紹了關(guān)于C語言結(jié)構(gòu)體占用內(nèi)存的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • C++中的復(fù)制構(gòu)造函數(shù)詳解

    C++中的復(fù)制構(gòu)造函數(shù)詳解

    今天小編就為大家分享一篇關(guān)于關(guān)于C++復(fù)制構(gòu)造函數(shù)的實(shí)現(xiàn)講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2021-09-09
  • C語言形參和實(shí)參傳值和傳址詳解刨析

    C語言形參和實(shí)參傳值和傳址詳解刨析

    形參出現(xiàn)在函數(shù)定義中,在整個(gè)函數(shù)體內(nèi)都可以使用, 離開該函數(shù)則不能使用。實(shí)參出現(xiàn)在主調(diào)函數(shù)中,進(jìn)入被調(diào)函數(shù)后,實(shí)參變量也不能使用,形參和實(shí)參的功能是作數(shù)據(jù)傳送。發(fā)生函數(shù)調(diào)用時(shí), 主調(diào)函數(shù)把實(shí)參的值傳送給被調(diào)函數(shù)的形參從而實(shí)現(xiàn)主調(diào)函數(shù)向被調(diào)函數(shù)的數(shù)據(jù)傳送
    2021-11-11
  • 解析C++ 浮點(diǎn)數(shù)的格式化輸出

    解析C++ 浮點(diǎn)數(shù)的格式化輸出

    本篇文章是對(duì)C++中浮點(diǎn)數(shù)的格式化輸出進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++11中的chrono庫詳解

    C++11中的chrono庫詳解

    C++11提供了日期時(shí)間相關(guān)的庫chrono,通過chrono庫可以很方便的處理日期和時(shí)間,這篇文章主要介紹了C++11中的chrono庫,需要的朋友可以參考下
    2023-03-03
  • C++學(xué)習(xí)之多態(tài)的使用詳解

    C++學(xué)習(xí)之多態(tài)的使用詳解

    這篇文章主要為大家詳細(xì)介紹了C++中多態(tài)的機(jī)制以及使用,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定的幫助,感興趣的可以了解一下
    2022-06-06
  • json格式解析和libjson的用法介紹(關(guān)于cjson的使用方法)

    json格式解析和libjson的用法介紹(關(guān)于cjson的使用方法)

    下面小編就為大家?guī)硪黄猨son格式解析和libjson的用法介紹(關(guān)于cjson的使用方法)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12

最新評(píng)論