Turning a list of images into a movie - image

I have a folder of jpg files and I want to make them into a movie. I am using this script:
% Create video out of list of jpgs
clear
clc
% Folder with all the image files you want to create a movie from, choose this folder using:
ImagesFolder = uigetdir;
% Verify that all the images are in the correct time order, this could be useful if you were using any kind of time lapse photography. We can do that by using dir to map our images and create a structure with information on each file.
jpegFiles = dir(strcat(ImagesFolder,'\*.jpg'));
% Sort by date from the datenum information.
S = [jpegFiles(:).datenum];
[S,S] = sort(S);
jpegFilesS = jpegFiles(S);
% The sub-structures within jpegFilesS is now sorted in ascending time order.
% Notice that datenum is a serial date number, for example, if you would like to get the time difference in hours between two images you need to subtract their datenum values and multiply by 1440.
% Create a VideoWriter object, in order to write video data to an .avi file using a jpeg compression.
VideoFile = strcat(ImagesFolder,'\MyVideo');
writerObj = VideoWriter(VideoFile);
% Define the video frames per second speed (fps)
fps = 1;
writerObj.FrameRate = fps;
% Open file for writing video data
open(writerObj);
% Running over all the files, converting them to movie frames using im2frame and writing the video data to file using writeVideo
for t = 1:length(jpegFilesS)
Frame = imread(strcat(ImagesFolder,'\',jpegFilesS(t).name));
writeVideo(writerObj,im2frame(Frame));
end
% Close the file after writing the video data
close(writerObj);
(Courtesy of http://imageprocessingblog.com/how-to-create-a-video-from-image-files/)
But it gives me this error:
Warning: No video frames were written to this file. The file may be invalid.
> In VideoWriter.VideoWriter>VideoWriter.close at 289
In Movie_jpgCompilation at 37
I'm sure my jpg files are fine, and they are in the folder I specify. What is the problem?

(This is my first post ever, so I hope it helps).
If you're on Linux, don't the backslashes need to be forward slashes? When I ran it on my Mac, my jpegFiles was an empty Struct. When I changed them around it worked:
% Create video out of list of jpgs
clear
clc
% Folder with all the image files you want to create a movie from, choose this folder using:
ImagesFolder = uigetdir;
% Verify that all the images are in the correct time order, this could be useful if you were using any kind of time lapse photography. We can do that by using dir to map our images and create a structure with information on each file.
jpegFiles = dir(strcat(ImagesFolder,'/*.jpg'));
% Sort by date from the datenum information.
S = [jpegFiles(:).datenum];
[S,S] = sort(S);
jpegFilesS = jpegFiles(S);
% The sub-structures within jpegFilesS is now sorted in ascending time order.
% Notice that datenum is a serial date number, for example, if you would like to get the time difference in hours between two images you need to subtract their datenum values and multiply by 1440.
% Create a VideoWriter object, in order to write video data to an .avi file using a jpeg compression.
VideoFile = strcat(ImagesFolder,'/MyVideo.avi');
writerObj = VideoWriter(VideoFile);
% Define the video frames per second speed (fps)
fps = 1;
writerObj.FrameRate = fps;
% Open file for writing video data
open(writerObj);
% Running over all the files, converting them to movie frames using im2frame and writing the video data to file using writeVideo
for t = 1:length(jpegFilesS)
Frame = imread(strcat(ImagesFolder,'/',jpegFilesS(t).name));
writeVideo(writerObj,im2frame(Frame));
end
% Close the file after writing the video data
close(writerObj);
Edit: You can also use filesep so that the file separator is OS-specific. http://www.mathworks.com/help/matlab/ref/filesep.html

It would be simpler to use Windows Movie Maker [windows] or iMovie [mac]. For your purposes though you should use PowerPoint.

Related

Access file inside folder, matlab mac

I have about 300 files I would like to access and import in Matlab, all these files are inside 300 folders.
The first file lie in the directory users/matt/Documents/folder_1 with the filename line.csv the 2nd file lie in users/matt/Documents/folder_2 with filename line.csv
So I would like to import the data from the 300 line.csv files in Matlab so I can take the average value. Is this possible? I am using mac osx btw.
I know what do with the .csv file, but I have no clue how to access them efficiently.
This should work: All we are doing is generating the string for every file path using sprintf and the loop index i, and then reading the csv file using csvread and storing the data in a cell array.
for i = 1:300 % Loop 300 times.
% Full path pointing to the csv file.
file_path = sprintf('users/matt/Documents/folder_%d/line.csv', i);
% Read data from csv and store it in a cell array.
data{i} = csvread(file_path);
end
% Do your computations here.
% ...
Remember to replace the 300 by the actual number of folders that you have.

Cutting data appended to a .jpg file and save as mpg file

The background of my problem is that I want to extract the video data of Motion Photos (taken by my Samsung S7). Manually it is easy but time consuming. Just open the .jpg file in a HexEditor and extract all data after the line "MotionPhoto_Data". The first part is the image and the second part is the video.
My current code is
im = 'test.jpg'
with open(im, 'rb') as fin:
data = fin.read()
data_latin = data.decode('latin1')
fin.close()
position = data_latin.find('MotionPhoto_Data')
data_pic = data[:position]
data_mpg = data[position:]
My problem now is that I can´t figure out how to save these strings in a way that data_pic is saved as a working jpg and data_mpg as a working video.
I tried
with open('test_pic.jpg', 'a') as fin:
fin.write(str(data_pic))
fin.close()
But this didn´t worked. I think there is a basic issue on how I try to handle/save my data but I can´t figure out how to fix this.
I assume you use python 3 as it is tagged that way.
You should not decode with 'data.decode('latin1'). It is binary data.
data = fin.read()
Then later write it also as binary data:
with open('test_pic.jpg', 'ab') as fout:
fout.write(data_pic)
fout.close()

Raspberry timelapse movie on the fly

I have a Raspberry on which I want to create a timelapse movie.
All examples I see in the internet FIRST save a bunch of images and THEN converts them into a movie all at once.
I want to create a movie over a long period of time so I can't save thousands of images. What I need is a tool that adds an image to a movie right after the image is captured.
Is there a chance to do that?
There's a flaw in your logic, I think - by adding each image to the movie, you would necessarily be adding a full-frame, rather than only a diff frame. This will result in higher quality, sure - but it will also not save you anything in terms of space as compared to saving the entire image. The space savings you see in adding things to movies is all about that diff, rather than storing a full frame.
Doing a partial diff with check-frames at increments might work, but I'm not sure what format you're targeting, nor what codexes would be needed in order to arbitrarily tack on either a diff frame or a full frame, depending on some external condition - encoding usually takes place as a series of operations rather than singly.
An answer but it isn't finished!
I need your help making this perfect!
Running in python2
import os, cv2
from picamera import PiCamera
from picamera.array import PiRGBArray
from datetime import datetime
from time import sleep
now = datetime.now()
x = now.strftime("%Y")+"-"+now.strftime("%m")+"-"+now.strftime("%d")+"-"+now.strftime("%H")+"-"+now.strftime("%M") #string of dateandtimestart
def main():
imagenum = 100 #how many images
period = 1 #seconds between images
os.chdir ("/home/pi/t_lapse")
os.mkdir(x)
os.chdir(x)
filename = x + ".avi"
camera = PiCamera()
camera.resolution=(1920,1088)
camera.vflip = True
camera.hflip = True
camera.color_effects = (128,128) #makes a black and white image for IR camera
sleep(0.1)
out = cv2.VideoWriter(filename, cv2.cv.CV_FOURCC(*'XVID'), 30, (1920,1088))
for c in range(imagenum):
with PiRGBArray(camera, size=(1920,1088)) as output:
camera.capture(output, 'bgr')
imagec = output.array
out.write(imagec)
output.truncate(0) #trying to get more than 300mb files..
pass
sleep(period-0.5)
camera.close()
out.release()
if __name__ == '__main__':
main()
I've got this configured with with a few buttons and an OLED to select time spacing and frame numbers displayed on a OLED (code not shown above for simplicity but it is also here: https://github.com/gchennell/RPi-PiLapse )
This doesn't make videos larger than 366Mb which is some sort of limit I've reached and I don't know why - if anyone has a good suggestion I would appreciate it

How to load all files from a directory of two different types in MATLAB

I know that it is possible to load all files of type .gif by using:
files = dir('C:\myfolder\*.gif');
However, my problem is that I want to load all files of type .gif and .jpg. What would be a good way of doing this?
You can simply search for both .gif and .jpg files then load and process the images one by one.
Just invoke dir twice - one for each type of image and store the results in two separate structures. Next, concatenate all of the file names to one structure, then go ahead and do your processing for all of the images.
Something like this:
%// Specify the folder where your images are stored
folder = fullfile('path', 'to', 'your', 'folder');
%// Specify search pattern for JPEG and GIF files
jpgFileFolder = fullfile(folder, '*.jpg');
gifFileFolder = fullfile(folder, '*.gif');
%// Invoke dir for both types of images
d1 = dir(jpgFileFolder);
d2 = dir(gifFileFolder);
%// Concatenate both dir structures together into a single structure
d = [d1; d2];
%// For each image we have...
for idx = 1 : numel(d)
%// Get full path to file
f = fullfile(folder, d(idx).name);
%// Read in the image
im = imread(f);
%// Do something with this image
%//...
%//...
end
fullfile allows you to create a directory string that is OS independent. Simply take each subdirectory that is part of your string and place them as separate string arguments into fullfile and it should work fine.

Matlab image processing

I have a folder which contains images (100) from the experiment that I did. I also have another folder which contains the background images (100 also) from the detector.
I have written a code that does something like this:
% Define images directory
% Define detector bg directory
% Loop over each frame and do some processing
for a=1:length(image directory)
%read files from directory
bg_corrected_image = frame#-bg_image# % # begins with 1
n=size(image directory)
new_images=zeros(n)
% Now sort through each pixel in bg_corrected image and assign value according to a criterion
for ii=1:size(bg_corrected_image,1)
jj=1:size(bg_corrected_image,2)
pixel=bg_corrected_image(ii,jj);
if pixel>500
pix_mod=0;
elseif pixel<30
pix_mod=0;
else
pix_mod=pixel;
end
new_image(ii,jj)=pix_mod;
end
******************* CODE TO SAVE IMAGE AND NOT OVERWRITE AFTER EACH
ITERATION OF LOOP?
end
What I want to do now is to save each image(frame) after it had gone through the pixel sorting regimen so that I can just sum them all after the loop has ended. I am not too sure what is the best way to do it? I think what I need to do is to create a cell array which saves a "new_image" after each iteration and the code for that should go where I put asteriks. Please note I don't want to save images earlier in my code. Any help much appreciated.
Maybe something like the below - load in all your images to a 3D matrix "imagestack", then process them all, then output them all. Note the vectorization on the pixel replacement here will be much faster than your for-loop iteration over the pixels.
IMAGECOUNT=100;
FILEPATH_IN='images/input/%d.jpg';
FILEPATH_OUT='images/output/%d.jpg';
I=imread(sprintf(FILEPATH,1));
[hei wid]=size(I);
imagestack=zeros(hei,wid,100);
for n=1:IMAGECOUNT
imagestack(:,:,n)=imread(sprintf(FILEPATH_IN,n));
end
imagestack(imagestack>500)=0;
imagestack(imagestack<30)=0;
for n=1:IMAGECOUNT
imwrite(imagestack(:,:,n),sprintf(FILEPATH_OUT,n));
end

Resources