JPG to GIF animation - matlab

I am using this code for conversion of JPGs to GIF animation. It works but produces strange colors (first and second picture in animation have incorrect colors and third is OK).
I would like to ask you to hep with correction of the code.
clear
clc
%// Image source: http:\\giantbomb.com
[A,map] = rgb2ind(imread('obr_0.jpg'),256);
[B,map] = rgb2ind(imread('obr_01.jpg'),256);
[C,map] = rgb2ind(imread('obr_99.jpg'),256);
ImageCell = {A;B;C};
%// Just to show what the images look like (I removed spots to make sure there was an animation created):
%// Create file name.
FileName = 'test.gif';
for k = 1:numel(ImageCell)
if k ==1
%// For 1st image, start the 'LoopCount'.
imwrite(ImageCell{k},map,FileName,'gif','LoopCount',Inf,'DelayTime',1);
else
imwrite(ImageCell{k},map,FileName,'gif','WriteMode','append','DelayTime',1);
end
end
BR
Michal

Can you try this?
clear
clc
%// Image source: http:\\giantbomb.com
[A,map] = rgb2ind(imread('obr_0.jpg'),256);
[B,~] = rgb2ind(imread('obr_01.jpg'),map);
[C,~] = rgb2ind(imread('obr_99.jpg'),map);
ImageCell = {A;B;C};
%// Just to show what the images look like (I removed spots to make sure there was an animation created):
%// Create file name.
FileName = 'test.gif';
for k = 1:numel(ImageCell)
if k ==1
%// For 1st image, start the 'LoopCount'.
imwrite(ImageCell{k},map,FileName,'gif','LoopCount',Inf,'DelayTime',1);
else
imwrite(ImageCell{k},map,FileName,'gif','WriteMode','append','DelayTime',1);
end
end

Related

MATLAB combine two avi. together

I created two avi. file and they have the same length.
I wanted to combine them on a same background and one on top another one on the bottom.
The code I used for one of the animation is below, the other one is similar.
Is there any way I can do that?
load Results.mat;
I = imread('hex08.jpg');
[rows,columns,numberOfColorChannels] = size(I);
if numberOfColorChannels >1
I = I(:,:,2);
end
background = imresize(background, [rows,columns]);
figure(1);
hold on;
for i=1:500
A=angle(i,:);
J = imrotate(I,A,'crop');
mask = J == 0;
mask = bwareafilt(mask,4);
J(mask) = background(mask);
pause(0.01)
imshow(J);
imwrite(J,[num2str(i),'.png']);
end
imageNames = dir(fullfile('*.png'));
imageNames = {imageNames.name}';
outputVideo = VideoWriter(fullfile('hex08.avi'));
outputVideo.FrameRate = 15;
open(outputVideo)
for ii = 1:length(imageNames)
img = imread(fullfile(imageNames{ii}));
writeVideo(outputVideo,img)
end
close(outputVideo)
Here is one way this can be done:
Just like you read the image into img, you can read a second image (from the second video) into img2. Then, you can create a combined image of the two: imgCombined = [img ; img2]; which will contain the first image on top and the second on bottom (This will work if both images are the same width, otherwise you will need to resize/crop). When you write to the video file, use writeVideo(outputVideo,imgCombined).

Loop for frame extraction matlab

Im currently trying to make a loop to do the same action to multiply videofiles. Currently my code looks like this:
close all
clear all
clc
movFiles = dir('*.mov');
numFiles = length(movFiles);
mydata = cell(1,numFiles);
% mydata = zeros(numFiles);
for k = 1:numFiles
mydata{1,k} = VideoReader(movFiles(k).name);
end
for k=1:numFiles
figure;
video = read(mydata{k},[1 Inf]);
for img = 60:60:360;
filename=strcat('File',num2str(img),'.jpg');
b = read(mydata{k}, img);
imwrite(b,filename);
end
end
The problem is that the frames get overwritten so what i need is a way to not make that happened. The moviefiles are named 1-200 so the filename i would like is something like 1framenr, 2framenr. Hope that somebody can help me with that
The problem is in the way you are defining the filename for each frame inside the loop. If you look at the line:
filename=strcat('File',num2str(img),'.jpg');
It is only composed of the frame number (img), which will repeat for every video file. Try replacing that line with following:
filename = ['Video_' num2str(k) '_frame_' num2str(img) '.jpg'];
This will give you files called Video_1_frame_1.jpg, Video_1_frame_2.jpg, etc.

how do i mask labeled object based on some specified threshold value for each objects area,majoraxis and minoraxis?

i am currently using bwconnomp to label each connected object and regionpropsto find area, majoraxis, minoraxis of each labeled object respectively. i am also displaying each labeled object its area,majoraxis and minoraxis. now i want to set some threshold for area,majoraxis and minoraxis and if the value of area,majoraxis and minoraxis is above specified threshold then that object has to be masked.how this can be done??
here is my code
clc
clear all
close all
Index = 1;
scrsz = get(0,'ScreenSize');
%read an image
while Index ~= 0
% Open a dialog and select an image file
[FileName,FilePath,Index] = uigetfile('*.png', 'Open Imagefile ');
if Index == 0
disp('Procedure Done')
break;
end
inimage = imread([num2str(FilePath) FileName]);
D=inimage;
A=inimage;
subplot(2,3,1);
imshow(inimage);
title('original image');
%labeling algorithm
B=im2bw(inimage);
C=imfill(B,'holes');
label=bwlabel(C);
max(max(label))
CC = bwconncomp(B);
data = regionprops(CC,'all');
for j=1:max(max(label))
[row, col] = find(label==j);
len=max(row)-min(row)+2;
breadth=max(col)-min(col)+2;
target=uint8(zeros([len breadth] ));
sy=min(col)-1;
sx=min(row)-1;
for i=1:size(row,1)
x=row(i,1)-sx;
y=col(i,1)-sy;
target(x,y)=A(row(i,1),col(i,1));
end
mytitle=strcat('Object Number:' ,num2str(j),'area:', num2str(data(j).Area),'MajorAxis: ',num2str(data(j).MajorAxisLength),'MinorAxis: ',num2str(data(j).MinorAxisLength));
figure,imshow(target);title(mytitle);
a=size(target);
ax=a(1);
ay=a(2);
pos=[1,1,ay,ax];
rectangle('Position',pos,'EdgeColo','r')
end
next = input('next image? press Enter: ');
if next == 0
channelactivity = 0;
break
else
close all
disp('==================================')
pause(0.2)
continue
end
end
Here is a way to do it. The code is commented so easy to follow; the important line is the following:
AboveAreaIndices = find(vertcat(data.Area) > SomeValue)
In which you store the indices of the objects whose area is larger than SomeValue. In the example I color them red but you can do whatever you want with them or remove them altogether from the data structure.
You can also use logical operators to combine multiple conditions for example using the MinorAxis and MajorAxis properties. Note that I used AllArea as anew variable to store the concatenated areas to make things clearer, but you can keep them as vertcat(data.Area).
AboveIndices = find(vertcat(data.Area) > SomeValue & vertcat(data. MinorAxis) > SomeValue & Bla bla bla...);
Whole code:
clear
clc
close all
%// Read and clean up sample image
A = imread('rice.png');
A = im2bw(A,.5);
A = bwareaopen(A,50);
CC = bwconncomp(A);
%// Same as you.
data = regionprops(CC,'all');
%// Concatenate all the areas into an array.
AllArea = vertcat(data.Area);
%//========================================
%//==== Apply threshold on area here \\====
AboveAreaIndices = find(AllArea > 150);
%// If you wish to remove the entries from the data structure
% data(AllArea>150) = [];
%//========================================
%// Same for centroids...for display purposes
AllCentroids = vertcat(data.Centroid);
%// Display original and thresholded objects. Use the indices calculated
%// above to "mask" large areas if you want
imshow(A);
hold on
scatter(AllCentroids(:,1),AllCentroids(:,2),40,'b','filled')
scatter(AllCentroids(AboveAreaIndices,1),AllCentroids(AboveAreaIndices,2),40,'r','filled')
And sample output:

Matlab get vector of specific pixels

I am pretty new to Matlab and encountered a problem when working with images.
I want to get a pixel that is in a specific colour (blue) in the following image:
image
My current code looks something like this:
function p = mark(image)
%// display image I in figure
imshow(image);
%// first detect all blue values higher 60
high_blue = find(image(:,:,3)>60);
%cross elements is needed as an array later on, have to initialize it with 0
cross_elements = 0;
%// in this iteration the marked values are reduced to the ones
%where the statement R+G < B+70 applies
for i = 1:length(high_blue)
%// my image has the size 1024*768, so to access the red/green/blue values
%// i have to call the i-th, i+1024*768-th or i+1024*768*2-th position of the "array"
if ((image(high_blue(i))+image(high_blue(i)+768*1024))<...
image(high_blue(i)+2*768*1024)+70)
%add it to the array
cross_elements(end+1) = high_blue(i);
end
end
%// delete the zero element, it was only needed as a filler
cross_elements = cross_elements(cross_elements~=0);
high_vector = zeros(length(cross_elements),2);
for i = 1:length(cross_elements)
high_vector(i,1) = ceil(cross_elements(i)/768);
high_vector(i,2) = mod(cross_elements(i), 768);
end
black = zeros(768 ,1024);
for i = 1:length(high_vector)
black(high_vector(i,2), high_vector(i,1)) = 1;
end
cc = bwconncomp(black);
a = regionprops(cc, 'Centroid');
p = cat(1, a.Centroid);
%// considering the detection of the crosses:
%// RGB with B>100, R+G < 100 for B<150
%// consider detection in HSV?
%// close the figure
%// find(I(:,:,3)>150)
close;
end
but it is not optimized for Matlab, obviously.
So i was wondering if there was a way to search for pixels with specific values,
where the blue value is larger than 60 (not hard with the find command,
but at the same time the values in the red and green area not too high.
Is there a command I am missing?
Since English isn't my native language, it might even help if you gave me some suitable keywords for googling ;)
Thanks in advance
Based on your question at the end of the code, you could get what you want in a single line:
NewImage = OldImage(:,:,1) < SomeValue & OldImage(:,:,2) < SomeValue & OldImage(:,:,3) > 60;
imshow(NewImage);
for example, where as you see you provide a restriction for each channel using logical operators, that you can customize of course (eg. using | as logical OR). Is this what you are looking for? According to your code you seem to be looking for specific regions in the image like crosses or coins is that the case? Please provide more details if the code I gave you is completely off the track :)
Simple example:
A = imread('peppers.png');
B = A(:,:,3)>60 & A(:,:,2)<150 & A(:,:,1) < 100;
figure;
subplot(1,2,1);
imshow(A);
subplot(1,2,2)
imshow(B);
Giving this:

MATLAB: Print contents of uipanel to PNG image

I don't know how to accomplish the following in MATLAB. I have a figure which looks like this:
In the figure, I have a panel with many subplots and a scrollbar that allows me to view a portion of the panel.
I want to save the whole contents of the panel to a PNG image file (not just the visible portion), i.e. I want to have a file which is a tall rectangle, and doesn't require scrolling.
The code for generating the figure is as follows:
function draw(obj)
figure;
panel1 = uipanel('Parent',1);
panel2 = uipanel('Parent',panel1);
panelheight = obj.nIterations / 2;
set(panel1,'Position',[0 0 0.97 1]);
set(panel2,'Position',[0 1-panelheight 1 panelheight]); %%
nPlot = 1;
for i=1:obj.nIterations
models = obj.iterations{i};
for nModel=1:length(models)
subplot(obj.nIterations,length(models)*2,nPlot);
nPlot = nPlot + 1;
drawTransitions(models{nModel});
set(gca,'Parent',panel2);
subplot(obj.nIterations,length(models)*2,nPlot);
nPlot = nPlot + 1;
drawRewards(models{nModel});
set(gca,'Parent',panel2);
end
end
s = uicontrol('Style','Slider','Parent',1,...
'Units','normalized','Position',[0.97 0 0.03 1],...
'Value',1,'Callback',{#slider_callback1,panel2,panelheight});
end
I have tried the following, without success.
The saveas funstion saves the whole figure, not just the panel. Also, it clips the invisible portion of the panel.
export_fig(panel2.'file.png') gives just a solid gray image.
Why don't you just scroll your panel and grab the frames and concatenate them all together? Here's some code that will basically do that. I would have posted am image, but I guess I don't have enough points for that. You may need to fiddle with the scrolling, and maybe making the slider invisible, but it works.
function printPanel(pnl,filename)
fig = figure(ancestor(pnl,'figure'));
pnl_units = get(pnl,'units');
fig_units = get(fig,'units');
set(pnl,'units','pixels')
set(fig,'units','pixels')
pnl_rect = getpixelposition(pnl);
fig_rect = getpixelposition(fig);
pnl_height = pnl_rect(4);
fig_height = fig_rect(4);
pnl_rect(2) = -pnl_height;
set(pnl,'position',pnl_rect)
N = ceil(pnl_height/fig_height);
CDATA = cell(N,1);
for i = 1:N
F = getframe(fig);
CDATA{i} = F.cdata;
pnl_rect(2) = pnl_rect(2)+fig_height;
set(pnl,'position',pnl_rect)
drawnow
end
set(pnl,'units',pnl_units)
set(fig,'units',fig_units)
imwrite(cat(1,CDATA{:}),filename)
end
You could get rid of the ui elements and just make a figure with all the subplots, and then export that one, using e.g. print -dpng ....
saveas takes a handle as a first argument. Maybe this does not have to be a figure or model handle, but could be a reference to the contents of the panel.