ایجاد ویدئو از تصاویر متوالی در متلب

ایجاد ویدئو از تصاویر متوالی

ایجاد ویدئو از تصاویر متوالی در متلب

فرض کنیم یه تعداد عکس یا تصویر داریم، می خوایم اینا رو توی یه فایل ویدئویی پشت سر هم نمایش بدیم. توی تاپیک (پست دوم) زیر یه مثال از نحوه ذخیره سازی انمیشنی که حالا مثلا با plot یا هر دستور دیگه داخل پنجره figure نمایش می دیم، وجود داره:

اما اینجا همونطور که گفتیم یه سری تصویر داریم که می خوایم به صورت ویدئو در بیاریم. من اینجا از یکی از مثال های خود متلب استفاده می کنم، عنوانش اینه: Create a New Video with the Image Sequence. دقیقا همون نیست، یه خورده شیوه نامگذاری رو عوض می کنم که نیاز به sort کردن پیدا نکنیم، فرمت ویدئو رو هم mp4 قرار میدم تا تفاوت حجمش با avi مشخص بشه، چون توضیحاتش رو هم نخوندم احتمالا متفاوت توضیح میدم.

اول از همه ما نیاز داریم که یه سری تصویر متوالی داشته باشیم، واسه اینکار می تونیم از یه ویدئو این تصاویر رو استخراج کنیم، در آخر دوباره این تصاویر استخراج شده رو به یه ویدئو تبدیل کنیم. متلب چند تا ویدئو داره، مثلا rhinos.avi که توی تولباکس Image Processing استفاده میشه، اما اینجا از shuttle.avi استفاده می کنم، که توی مثال متلب هم استفاده شده. اگه خواستین این ویدئو رو مشاهده کنین، اما نه با متلب با پلیر خودتون می تونین این دستور رو توی Command Window تایپ کنین:

کد:
winopen('shuttle.avi')

دستور winopen فایل مورد نظرتون رو باز می کنه، اما نه داخل متلب با برنامه ای که به ویندوزتون برای فایل هایی با اون پسوند در نظر گرفته، مثل اینکه روی فایل دابل کلیک کنین.

ایجاد ویدئو از تصاویر متوالی

shuttle.avi

خب الان می خوایم هر فریم ویدئو رو به صورت یه تصویر ذخیره کنیم، از دستور VideoReader استفاده می کنیم، این دستور فایلمون رو نمی خونه، بلکه فقط آدرس و مشخصاتش رو نگه میداره، اینجوری RAMمون هم بی دلیل اشغال نمیشه اگه فایل ویدئویی حجیم باشه. خط بعدش نگاه می کنیم این فایلمون چند فریم داره، بعد هم یه فولدر درست می کنیم که تصویر های خروجی رو داخل اون بریزه.

کد:
clear;
myvideo = VideoReader('shuttle.avi');
framesNum = myvideo.NumberOfFrames;

if ~exist('ShuttleImages','dir')
    mkdir('ShuttleImages');
end

for i = 1:framesNum
    myframe = read(myvideo,i);
    namewithPath = sprintf('ShuttleImages\\%03d.png',i);
    imwrite(myframe,namewithPath,'png');
end

در ادامش روی فریم های ویدئومون یه حلقه میذاریم، که فریم به فریم بخونه و ذخیره کنه. یه توضیحی هم درمورد sprintf بدم، به علامت \ برای نمایش آدرس داخل این دستور باید از \\ استفاده کنیم. برای عددهای صحیح که از d% استفاده میشه، پس اون 03 چیه که من گذاشتم، 03 در واقع مشخص میکنه عددم همیشه از سه تا کاراکتر تشکیل بشه، برای اعدادی که کمتر از سه رقم دارن به تعداد مورد نیاز سمت راستش صفر قرار بده. با این روش دیگه نیاز به مرتب کردن موقع خوندن نداریم، چون در اون صورت اعداد یه رقمی، دو رقمی و … ترتیبشون بهم می خوره (مثلا 1 و 11 پشت سر هم قرار میگیرن، چون هر دو با یک شروع میشن).

فرمت فایل ها رو هم من png گذاشتم تا فشرده سازی نداشته باشیم، با همون کیفیت اصلی ذخیره بشن. خب تصاویر توی فولدر ShuttleImages ریخته میشه:

ایجاد ویدئو از تصاویر متوالی

تصاویر استخراج شده از ویدئو

می رسیم به بخش اصلی یعنی می خوایم این تصاویری که استخراج کردیم رو به صورت یه ویدئوی جدید در بیاریم. اسم تصاویر مورد نظرمون رو با دستور dir می خونیم، دیگه نگرانی بابت ترتیبشون نداریم چون قبلا در موردش فکر کرده بودیم.می تونیم تمام تصاویر رو اول بخونیم بعد ازشون استفاده کنیم، ولی خب نمی خوایم بی دلیل حافظه RAM رو اشغال کنیم، دونه دونه می خونیم و استفاده می کنیم. برای این کار هم یه چنین کدی نیاز داریم:

کد:
clear;
ImagesList = dir('ShuttleImages\*.png');

MyNewVideo = VideoWriter('MyNewVideo.mp4','MPEG-4');
MyNewVideo.FrameRate = 10;
open(MyNewVideo)

for i = 1:numel(ImagesList)
    myImage = imread(fullfile('ShuttleImages',ImagesList(i).name));
    
    writeVideo(MyNewVideo,myImage)
end

close(MyNewVideo);

بعد از اینکه تمام اسامی تصاویرمون رو توی ImagesList ریختیم، خب یه فایل خروجی برای ویدئومون نیاز داریم، من mp4 انتخاب کردم، واسه mp4 باید نحوه ی فشرده سازی ‘MPEG-4’ هم مشخص بشه، در غیر این صورت بازم avi ذخیره می کنه. واسه avi اون خط رو باید این شکلی بنویسیم:

کد:
MyNewVideo = VideoWriter('MyNewVideo.avi');

FrameRate رو هم 10 گذاشتم، که واسه ویدئوی اصلی 30 بود، معمولا هم همون 30 استفاده میشه. واسه همین زمان ویدئوی من 3 برابر شده و خیلی نسبت به ویدئوی اصلی آهسته تر هستش.

در آخر هم با winopen نمایشش میدیم، ببینیم چی درست شده، البته اگه نام یا فرمت رو تغییر دادین، باید این خط رو هم اصلاح کنیم:

کد:
winopen('MyNewVideo.mp4')

تالار متلب نواندیشان


درباره نویسنده

مطالب مرتبط

2 نظر

نظر بدهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *