I am trying to load an image and show it in MATLAB. It used to work on my other computer a while ago but on this computer the picture looks completely wrong and I am not sure why.
Thanks for all the help in advance.
This is the image I am loading:
https://dl.dropboxusercontent.com/u/13524574/(1).png
This is how MatLAB shows it:
https://dl.dropboxusercontent.com/u/13524574/WrongImage.png
Here is my code:
function main()
workingDir = 'E:\MASTERS\MatLAB\FullVideo_R_OF_HOF\Images';
S4A = zeros(360,640,3,256);
%getting 256 frames of the images
for ii = 1:256
S4A(:,:,:,ii) = imread(fullfile(workingDir,'S4A',strcat('(',int2str(ii),').png')));
end
%showing first frame only
imshow(S4A(:,:,:,1));
end
I'm not exactly sure what's going on in there with all those indices but I think I may be able to offer an alternative. Check out the third paragraph of the documentation, here, for return value information. I suggest using a cell array for clarity.
function main()
workingDir = 'E:\MASTERS\MatLAB\FullVideo_R_OF_HOF\Images';
S4A = zeros(360,640,3,256);
%getting 256 frames of the images
for ii = 1:256
A{ii} = imread(fullfile(workingDir,'S4A',strcat('(',int2str(ii),').png')));
end
%showing first frame only
imshow(A{1});
end
Related
I need to save all the captured images in MATLAB but I am able to save one picture at a time.
mycam = webcam();
img = snapshot(mycam);
imwrite(img,'img.jpg');
If somebody knows how to save all the pictures taken at a time in MATLAB, please help me with the code.
I would save the images as a movie and then access the frames later. This is untested but it would work like this.
mycam = webcam();
% if you know the number of images use that here
% a movie is just a collection of frames
% if not then just don't initialize F
F(nFrames) = struct('cdata', [], 'colormap, []);
for i = 1:nFrames
F(i) = im2frame(snapshot(mycam));
end
% save F
movie2avi(F, 'MyMovie.avi', 'compression', 'None');
Then you can load the movie and look at the frames. This example uses the older movie2avi but VideoWriter is also an option
v = VideoWriter('MyMovie.avi');
open(v);
for i = 1:nFrames
writeVideo(v, snapshot(mycam));
end
close(v);
Again untested as I don't have a webcam attached to this computer. But it works for animated graphs. See doc readFrame for the way to read frames
As they have already told you, you should use a for loop with the sprintf function in order to not overwrite the previous images. Try with the following command:
%capture the frames
for i =1:n;% n is the number of frames you want to capture
frames{i} = getsnapshot(mycam);
end
%save in the current folder
for i = 1:n;
imwrite(frames{i}, sprintf('imageName%d.jpg',i))
end
You will have all the captured frames saved in the Current Folder.
i'm am very new to Matlab but really want improve. For my experiment i want to show a picture which the participant response yes/no to, using two different keys (f&g) and then the next picture is presented and it repeats so onward.
Presenting the picture, using the keys works for far, but i can't get it to repeat the trial. Thus my question is how can i get the program to repeat/loop my trial?
Is there something wrong in my code so far or is there additional coding i should use?
this is my code so far
function try1_6()
cleanupObj= onCleanup(#() myCleanupFxn);
% PRETEST
% Initialize screen with black background
winID = Screen('openWindow',0, [0 0 0]);
%Parameter
backcol=255;
textcol=0;
% Load image file(s)
structimages= [];
TheImagesdir = dir('theImagesdir/*.jpg');
for i=1: length(TheImagesdir);
TheImages = imread(['theImagesdir/' TheImagesdir(i).name], 'JPEG');
% Get width and height
imageX = size(TheImages,2);
imageY = size(TheImages,1);
% Convert to texture
myTexture = Screen('MakeTexture', winID, TheImages);
% Set destination rectangle
destRect = [50 100 50+imageX 100+imageY];
%save to structure
structimages(end+1).filename=TheImagesdir(i).name;
structimages(end).destRect= destRect;
structimages(end).texture= myTexture;
end
%Make triallist
numberOfItems= [5]; %list of all possible items
Nrepeats=4;
Response=0;
TrialList=HH_mkTrialList({numberOfItems Response},Nrepeats);
%PRESENTATION
for trialnum=1:size(TrialList,1)
nitems = TrialList(trialnum,1);
Screen('FillRect', winID,backcol); % makes the screen blank
%displays text
DrawFormattedText(winID,'dkjfghaslkdfglksdjgfh','center','center',textcol);
Screen('Flip', winID)
HH_waitForKeyPress({'space'}); % waits for spacebar to be pressed
Screen('FillRect',winID,backcol);
Screen('Flip',winID);
WaitSecs(1);
%display picture
whichTheImages= randi(length(TheImagesdir)); % randomly selects image for directory
Screen('FillRect',winID,backcol);
Screen('DrawTexture', winID, myTexture, [], destRect);
Screen('Flip', winID);
HH_waitForKeyPress({'f','j'},5)
if resp==-1
break
end
TrialList(trialnum,4)= response; %records response
end
end
function myCleanupFxn()
Screen('CloseAll')
end
There are a number of problems with you code that you need to address. First of all, TrialList is used before it is declared/initialized. The Make triallist block of code seems out of place in the body of the for loop, and should probably be placed before you loop TrialList.
Your second problem is the inner for loop that loads images. Right now, it loads every image found in the directory, on every trial! There is no reason for you to be doing this, and you should be placing this for loop outside the trial loop as well. Furthermore, your original code never worked as intended, because you never save the loaded texture anywhere; myTexture is overwritten by the last image in your folder and that's the only texture you're ever gonna get. So in addition to pre-loading the images before the loop, you need to save them in a data structure so that you can use them later in your trial loop. A simple struct will work nicely here:
structImages = [];
TheImagesdir = dir('theImagesdir/*.jpg');
for i = 1:length(TheImagesdir);
TheImages = imread(['theImagesdir/' TheImagesdir(i).name], 'JPEG');
% Get width and height
imageX = size(TheImages,2);
imageY = size(TheImages,1);
% Convert to texture
myTexture = Screen('MakeTexture', winID, TheImages);
% Set destination rectangle
destRect = [50 100 50+imageX 100+imageY];
%save to structure
structImages(end+1).filename = TheImagesdir(i).name;
structImages(end).destRect = destRect;
structImages(end).texture = myTexture;
end
There are other inconsistencies in your code:
whichTheIamges is defined but not used
resp is used in the comparison if resp==-1 but is not defined
response is saved into TrialList before it is defined
Finally, the biggest problem is Screen('CloseAll', winID); is inside the trial loop, so you tear down your whole presentation platform after the first trial.
FYI, as noted in my comment wrapping your entire script in a try block is really poor practice. I suspect you do this because you want to be able to Ctrl+C mid-task, but there's a better way to do this. If you make your entire script a function then you can use the onCleanup method to execute code whenever your function exits (whether normally, by error, or by interruption). The method goes like this:
function myScript()
%//make your script a function. There is an additional advantages to doing this:
%//function performance is better than script performance.
%//blah-blah-blah
%//setup the cleanup object before opening screen
cleanupObj = onCleanup(#() myCleanupFxn);
%//open the screen
winID = Screen('openWindow',0, [0 0 0]);
%//blah-blah-blah
end
function myCleanupFxn()
%//local function, not visible outside of this file
Screen('CloseAll');
end
Below is a function I wrote in Matlab. The function works correctly but the output displays three different images of different outputs.
function Img = power_Law(Img)
temp = Img;
[a,b]=size(Img);
C=0.2;
omega=0.2;
for i=1:a
for j=1:b
img(i,j)=C*power(temp(i,j),omega);
end
end
imshow(img);
end
My Question is am I missing any conversions? Why wouldn't the output be a single Image.
Here is a link of the output.
https://www.dropbox.com/s/p6vuhzodk29qaul/image.png
You will notice that in Matlab and Octave operation performed for matrices are dramatically faster comparing to loops over their elements. Also loops will create a possibility to make a mistake.
Let say Img is of size 900x1200x3, then img will be of size 900x3600 because [a,b]=size(img) returns a = 900, b = 3600 as Img is three dimensional array.
Then proper code will look something like this, note it doesn't change dimensionality of img2
function img2 = power_law(img, C, omega)
img2 = C * power(img, omega);
imshow(img2);
end
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 have an extremely bizzare situation: I have a function in MATLAB which calls three other main functions and produces two figures for me. The function reads in an input jpeg image, crops it, segments it using kmeans clustering, and outputs 2 figures to the screen - the original image and the clustered image with the cluster centers indicated. Here is the function in MATLAB:
function [textured_avg_x photo_avg_x] = process_database_images()
clear all
warning off %#ok
type_num_max = 3; % type is 1='texture', 2='graph', or 3='photo'
type_num_max = 1;
img_max_num_photo = 100; % 400 photo images
img_max_num_other = 100; % 100 textured, and graph images
for type_num = 1:2:type_num_max
if(type_num == 3)
img_num_max = img_max_num_photo;
else
img_num_max = img_max_num_other;
end
img_num_max = 1;
for img_num = 1:img_num_max
[type img] = load_image(type_num, img_num);
%img = imread('..\images\445.jpg');
img = crop_image(img);
[IDX k block_bounds features] = segment_image(img);
end
end
end
The function segment_image first shows me the color image that was passed in, performs kmeans clustering, and outputs the clustered image. When I run this function on a particular image, I get 3 clusters (which is not what I expect to get).
When I run the following commands from the MATLAB command prompt:
>> img = imread('..\images\texture\1.jpg');
>> img = crop_image(img);
>> segment_image(img);
then the first image that is displayed by segment_image is the same as when I run the function (so I know that the clustering is done on the same image) but the number of clusters is 16 (which is what I expect).
In fact, when I run my process_database_images() function on my entire image database, EVERY image is evaluated to have 3 clusters (this is a problem), whereas when I test some images individually, I get in the range of 12-16 clusters, which is what I prefer and expect.
Why is there such a discrepancy? Am I having some syntax bug in my process_database_images() function? If more code is required from me (i.e. segment_images function, or crop_image function), please let me know.
Thanks.
EDIT:
I found the source of the problem. In my load_image function, after I call img = imread(filename), I convert the image to double: `img = im2double(img);'. When I comment this line out, I get the desired result. Anyone know why this happens? (and also how I can 'close' this question since I have located the problem).
clear all at the top of your function is unnecessary and may be the source of your trouble.
Also, turning off all warnings is a bad idea since it may mask other problems.
Let's look at this code, simplified by removing redundant code or unused code:
function [textured_avg_x photo_avg_x] = process_database_images()
type_num_max = 1;
img_max_num_photo = 100; % 400 photo images
img_max_num_other = 100; % 100 textured, and graph images
for type_num = 1:2:type_num_max %% 1:2:1 => 1
img_num_max = 1; %This nullfiies everything in the if block above anyways
for img_num = 1:img_num_max %% 1:1 => 1
[type img] = load_image(type_num, img_num); %% Input (1,1)
img = crop_image(img);
[IDX k block_bounds features] = segment_image(img);
end
end
end
It looks like this code runs through the double nested for loop exactly once, maybe that is why you get only one answer, three clusters.
Try calling your function on the command line with the same amount of return values as in the function you wrote. Instead of
>> segment_image(img);
Try:
>> [IDX k block_bounds features] = segment_image(img);
Functions in Matlab check how many return values are expected, and may behave differently depending on that.