I'm trying to convert a video file into greyscale. When I try running the Matlab script I get a "Invalid video data-must be a numeric or logical data type". Can someone help me with what I am doing wrong? I am also new to matlab.
filename = 'Project1.m4v';
vid = VideoReader(filename);
newVid = VideoWriter('NewVid');
open(newVid);
numFrames = vid.NumberOfFrames;
for frame = 1 : numFrames
% Extract the frame from the movie structure.
thisFrame = read(vid, frame);
%Convert each frame to black and white
gray = rgb2gray(thisFrame);
writeVideo(newVid,gray);
end
close(newVid);
implay(newVid);
Use implay('NewVid.avi') instead of implay(newVid);
The only problem in your code is the last line: implay(newVid);.
newVid is a VideoWriter object - you create it using newVid = VideoWriter('NewVid');.
I recommend you to add '.avi' file extension to 'NewVid' file name:
Use: newVid = VideoWriter('NewVid.avi');
implay does't take VideoWriter object as input parameter.
Instead of displaying an error message in Matlab workspace, it displays the error message in the video window.
All you need to do, is replacing last code line with implay('NewVid.avi').
Related
I have a brain MRi image in .png format. I read the image and extract the K-Space and set some of the K-Space as 0
img_fft = fftshift(fft2(img));
sizes = size(img_fft);
row_half = sizes(1)/2;
flag = true;
for r = row_half:sizes(1)
for c = 1:sizes(2)
img_fft(r,c) = 0+1i*0;
end
end
After this I change the image back to image space using
img_back = ifft2(ifftshift(img_fft));
and after this I cast the image to uint8 as that was the original image format.
When I try to plot my image using imshow() I get a different output compared to when I write the image using imwrite. Also if I use abs(img_back) in imwrite I get an error.
Error using abs: Complex integers are not supported.
My plotting code is below:
img_back = ifft2(ifftshift(img_fft));
img_back = cast(img_back,'uint8');
subplot(1,3,1), imshow(img)
subplot(1,3,2), imshow(img_back)
subplot(1,3,3), imshow(abs(img_fft),[])
imwrite(abs(img_back),'back_img.png','png')
Can someone tell me what I am doing wrong here?
Take absolute value after inverse Fourier transform and then cast the result to uint8 type:
img_back = abs(ifft2(ifftshift(img_fft)));
img_back = cast(img_back,'uint8');
I have this code to create an animation:
obj = VideoWriter(pvideo);
open(obj);
pic=dir(strcat(outputs,'/','*.tif'));
num=length(pic);
for i=1:num
im = imread(strcat(outputs,'/',pic(i).name));
writeVideo(obj,im);
end
close(obj)
It is giving me the following error:
Error using VideoWriter/writeVideo (line 368)
Frame must be 1768 by 1326
I understand that my video dimensions are off, but I'm not sure what part of my code needs to be changed to fix this.
Possible Size Mismatch
I believe a possible issue is that the images being combined into the video file may not match in resolution/dimensional size. Here is a sample script that creates a video file from built-in MATLAB images. Here all the images are written as size 500 by 500. If one of the images are not matching the error is thrown. They're are two ways to handle the issue resize the image using the imresize() function or crop the image using the imcrop() function or indexing (this can be done in the for-loop). Can one of the 500 dimensions in the script below throws the same error which might be an indicator of this problem.
%Creating test images to combine into video file%
Folder_Path = "";
Image = imresize(imread('moon.tif'),[500 500]);
imwrite(Image,fullfile(Folder_Path,"Image_1.tif"));
Image = imresize(imread('circuit.tif'),[500 500]);
imwrite(Image,fullfile(Folder_Path,"Image_2.tif"));
Image = imresize(imread('autumn.tif'),[500 500]);
imwrite(Image,fullfile(Folder_Path,"Image_3.tif"));
%Starting to create video%
Pictures = dir(fullfile(Folder_Path,'*.tif'));
%Creating a video object to save the video structure to%
Video_Object = VideoWriter('Saved_Video.mp4','MPEG-4');
Video_Object.FrameRate = 1;
Video_Object.Quality = 100;
Number_Of_Frames = length(Pictures);
open(Video_Object);
%Scanning the frames into the video structure%
for Frame_Index = 1: Number_Of_Frames
writeVideo(Video_Object,imread(fullfile(Folder_Path,Pictures(Frame_Index).name)));
end
close(Video_Object);
implay('Saved_Video.mp4');
I have a set of .raw depth images. The image format is 500X290 with 32 bytes per pixel. When I open them with IrfanView image viewer I see the depth image correctly like this:
displayed image in IrfanView
Now I want to read and display the same depth image in Matlab. I do like this:
FID=fopen('depthImage.raw','r');
DepthImage = fread(FID,[290,500],'bit32');
fclose(FID);
colormap winter;
imshow(DepthImage);
DepthImage is a 290X500 type double matrix.
what I get from this code is this image:
displayed image in Matlab viewer
when I change fread parameter from 'bit32' to 'bit24' I get this:
displayed image in Matlab with bit24
I guess each element in DepthImage contains 32 bits where each 8 bits corresponds to R,G,B and D values. but how can I read the image correctly and display it like the one in IrfanView?
the raw file: https://drive.google.com/file/d/1aHcRmMKvi5gtodahR5l_Dx8SbK_920c5/view?usp=sharing
There might be an issue with image metadata header, like "date and time of the shot", "camera type". Open your image with notepad++ to check for "date and time". If you upload your original raw image, it will be easier to try things.
Upd: Ok, this is something. Check if it helps
FID=fopen('camera00000000000014167000.raw','r');
DepthImage = fread(FID,290*500*4,'int8');
DepthImageR = DepthImage(1:4:end);
DepthImageG = DepthImage(2:4:end);
DepthImageB = DepthImage(3:4:end);
DepthImageD = DepthImage(4:4:end);
dataR = reshape(DepthImageR, 500,290);
dataG = reshape(DepthImageG, 500,290);
dataB = reshape(DepthImageB, 500,290);
dataD = reshape(DepthImageD, 500,290); % all equal to 64 - useless
figure()
subplot(2,2,1)
image(dataR)
subplot(2,2,2)
image(dataG)
subplot(2,2,3)
image(dataB)
subplot(2,2,4)
data = zeros(500,290,3);
data(:,:,1) = dataR;
data(:,:,2) = dataG;
data(:,:,3) = dataB;
image(data)
I am newly working with Matlab. I want to read a video file and do some calculations every frame and display every frame. I wrote the following code but every time it only displays the first frame. can anybody please help.
mov=VideoReader('c:\vid\Akiyo.mp4');
nFrames=mov.NumberOfFrames;
for i=1:nFrames
videoFrame=read(mov,i);
imshow(videoFrame);
end
Note: mmreader API has been discontinued by MATLAB so prefer using VideoReader.
See comment by #Vivek.
I usually do this:
obj=mmreader('c:\vid\Akiyo.mp4');
nFrames=obj.NumberOfFrames;
for k=1:nFrames
img=read(obj,k);
figure(1),imshow(img,[]);
end
As far as your code is concerned, I saw MATLAB's documentation. You should do the things in following order:
mov=VideoReader('c:\vid\Akiyo.mp4');
vidFrames=read(mov);
nFrames=mov.NumberOfFrames;
for i=1:nFrames
imshow(vidFrames(:,:,i),[]); %frames are grayscale
end
Function read() and the field NumberOfFrames() are now deprecated, Matlab suggests using
xyloObj = VideoReader(file);
vidHeight = xyloObj.Height;
vidWidth = xyloObj.Width;
mov = struct('cdata',zeros(vidHeight, vidWidth, 3,'uint8'), 'colormap',[]);
while hasFrame(xyloObj)
mov(k).cdata = readFrame(xyloObj,'native');
end
In case you want to estimate a number of frames in the video, use nFrames = floor(xyloObj.Duration) * floor(xyloObj.FrameRate);
Below suggested code is showing only one frame
imshow(vidFrames(:,:,i),[]);
I am doing following things to store each frame
obj = VideoReader('path/to/video/file');
for img = 1:obj.NumberOfFrames;
filename = strcat('frame',num2str(img),'.jpg');
b = read(obj,img);
imwrite(b,filename);
end
This will store all the frames in your home directory.And yes, as also suggested by Vivek and Parag
You need to use VideoReader as mmreader has been discontinued by
MATLAB.
*=I was making a function to play any .avi file as a set of frames in a figure. Here's what a did. A bit of a combo of what you've done, except my NumberOfFrames wasn't working: (noteL this also shows it in colour)
function play_video(filename)
% play_video Play a video file
% play_video(filename) plays the video file specified by filename in a MATLAB Figure window.
figure
set(figure, 'Visible', 'on')
mov=VideoReader(filename);
vidFrames=read(mov);
duration = mov.Duration;
frame_rate = mov.FrameRate;
total_frames = duration .* frame_rate
for i=1:1:total_frames
imshow(vidFrames(:, :, :, i), []);
drawnow
end
I run this code in MATLAB but it returns a Cyan frame
obj = videoinput('winvideo', 1);
% Select the source to use for acquisition.
set(obj, 'SelectedSourceName', 'input1')
% View the properties for the selected video source object.
src_obj = getselectedsource(obj);
get(src_obj)
% Acquire and display a single image frame.
frame = getsnapshot(obj);
image(frame);
% Remove video input object from memory.
delete(obj);
But preview video works well.
Perhaps the problem is with the input to image command.
Try to run
class(frame)
max(frame(:))
min(frame(:))
And see what the results are.
Double values should be between [0-1], whereas uint8 should be in the range of [0-255].
Adding obj.ReturnedColorSpace = 'rgb'; in the second line solved it.