Making a gif from images - image

I have a load of data in 100 .sdf files (labelled 0000.sdf to 0099.sdf), each of which contain a still image, and I'm trying to produce a .gif from these images.
The code I use to plot the figure are (in the same directory as the sdf files):
q = GetDataSDF('0000.sdf');
imagesc(q.data');
I've attempted to write a for loop that would plot the figure and then save it with the same filename as the sdf file but to no avail, using:
for a = 1:100
q=GetDataSDF('0000.sdf');
fh = imagesc(q.dist_fn.x_px.Left.data');
frm = getframe( fh );
% save as png image
saveas(fh, 'current_frame_%02d.jpg');
end
EDIT: I received the following errors when trying to run this code:
Error using hg.image/get
The name 'Units' is not an accessible property for an instance of class 'image'.
Error in getframe>Local_getRectanglesOfInterest (line 138)
if ~strcmpi(get(h, 'Units'), 'Pixels')
Error in getframe (line 56)
[offsetRect, absoluteRect, figPos, figOuterPos] = ...
Error in loop_code (line 4)
frm = getframe( fh );
How do I save these files using a for loop, and how do I then use those files to produce a movie?

The reason for the error is that you pass an image handle to getframe, but this function excpects a figure handle.
Another problem is that you always load the same file, and that you saveas will not work for gifs. (For saving figures as static images, maybe print is the better option?)
I tried to modify my own gif-writing loop so that it works with your data. I'll try to be extra explicit in the comments, since you seem to be starting out. Remember, you can always use help name_of_command to display a short Matlab help.
% Define a variable that holds the frames per second your "movie" should have
gif_fps = 24;
% Define string variable that holds the filename of your movie
video_filename = 'video.gif';
% Create figure 1, store the handle in a variable, you'll need it later
fh = figure(1);
for a = 0:99
% Prepare file name so that you loop over the data
q = GetDataSDF(['00' num2str(a,'%02d') 'sdf']);
% Plot image
imagesc(q.dist_fn.x_px.Left.data');
% Force Matlab to actually do the plot (it sometimes gets lazy in loops)
drawnow;
% Take a "screenshot" of the figure fh
frame = getframe(fh);
% Turn screenshot into image
im = frame2im(frame);
% Turn image into indexed image (the gif format needs this)
[imind,cm] = rgb2ind(im,256);
% If first loop iteration: Create the file, else append to it
if a == 0;
imwrite(imind,cm,video_filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,video_filename,'gif','WriteMode','append','DelayTime',1/gif_fps);
end
end
One more note: When the size of the data is the same for each plot, it makes sense to only use the plot(or in this case, imagesc) command once, and in later loop iterations replace it with a set(ah,'Ydata',new_y_data) (or in this case set(ah,'CData',q.dist_fn.x_px.Left.data'), where ah is a handle of the plot axes (not the plot figure!). This is orders of magnitude faster than creating a whole new plot in each loop iteration. The downside is that the scaling (here, the color-scaling) will be the same for each plot. But in every case that I have worked on so far, that was actually desirable.

Related

Writing Macro in ImageJ to open, change color, adjust brightness and resave microscope images

I'm trying to write a code in Image J that will:
Open all images in separate windows that contains "488" within a folder
Use look up tables to convert images to green and RGB color From ImageJ, the commands are: run("Green"); and run("RGB Color");
Adjust the brightness and contrast with defined values for Min and Max (same values for each image).
I know that the code for that is:
//run("Brightness/Contrast..."); setMinAndMax(value min, value max); run("Apply LUT");
Save each image in the same, original folder , in Tiff and with the same name but finishing with "processed".
I have no experience with Java and am very bad with coding. I tried to piece something together using code I found on stackoverflow and on the ImageJ website, but kept getting error codes. Any help is much appreciated!
I don't know if you still need it, but here is an example.
output_dir = "C:/Users/test/"
input_dir = "C:/Users/test/"
list = getFileList(input_dir);
listlength = list.length;
setBatchMode(true);
for (z = 0; z < listlength; z++){
if(endsWith(list[z], 'tif')==true ){
if(list[z].contains("488")){
title = list[z];
end = lengthOf(title)-4;
out_path = output_dir + substring(title,0,end) + "_processed.tif";
open(input_dir + title);
//add all the functions you want
run("Brightness/Contrast...");
setMinAndMax(1, 15);
run("Apply LUT");
saveAs("tif", "" + out_path + "");
close();
};
run("Close All");
}
}
setBatchMode(false);
I think it contains all the things you need. It opens all the images (in specific folder) that ends with tif and contains 488. I didn't completely understand what you want to do with each photo, so I just added your functions. But you probably won't have problems with adding more/different since you can get them with macro recorder.
And the code is written to open tif files. If you have tiff just be cerful that you change that and also change -4 to -5.

Divide an image into non-overlapping blocks and applying the 2D DWT on each block

I am working on creating an image splicing detection software so I need to divide the image into non-overlapping blocsk and apply Discrete Meyer Wavelet Transform on each block of the image
I have tried the blockproc function to do that but I got no result:
I = imread('pears.png');
fun = #(block_struct)...
dwt2(block_struct.data,'dmey');
C = blockproc(I,[64 64],fun);
So how can I access the [cA,cH,cV,cD] of dwt2 using the above code?
blockproc assumes that you are outputting an actual image. You cannot use this for multiple outputs. If you truly want this to work with blockproc, you will unfortunately need to call blockproc four times, with each time extracting the different set of coefficients for the directions. Also note that the 2D DWT only works for grayscale images, so you need to convert to grayscale before actually doing any processing. The pears image you've chosen is a colour / RGB image.
I'd like to reference this post on how to select the Nth output given an input function: How do I get the second return value from a function without using temporary variables?. You will need to save this code to a file called nth_output.m, which allows you to programatically extract all output variables from a function and choose only one output.
function value = nth_output(N,fcn,varargin)
[value{1:N}] = fcn(varargin{:});
value = value{N};
end
Simply omitting the extra output arguments when you call the function only gives you the first output, which is what your blockproc code is doing. Once you do that, it's a matter of creating 4 anonymous functions to capture each output from dwt2, and running blockproc 4 times. Make sure you specify which output you want for each of the anonymous functions, so 1 up to 4 and you simply provide a handle to the function you want to run in addition to the input arguments that go into the function.
Therefore, try something like this:
I = rgb2gray(imread('pears.png'));
fun1 = #(block_struct) nth_output(1, #dwt2, block_struct.data,'dmey');
fun2 = #(block_struct) nth_output(2, #dwt2, block_struct.data,'dmey');
fun3 = #(block_struct) nth_output(3, #dwt2, block_struct.data,'dmey');
fun4 = #(block_struct) nth_output(4, #dwt2, block_struct.data,'dmey');
I = rgb2gray(I);
cA = blockproc(I,[64 64],fun1);
cH = blockproc(I,[64 64],fun2);
cV = blockproc(I,[64 64],fun3);
cD = blockproc(I,[64 64],fun4);
cA, cH, cV, and cD contain the DWT coefficients you need for each set of directions.

Working on more than one image in Matlab

I started to learn Matlab newly. I am trying to learn about classification. I will make classification for my 23 images. In my function file I am using
I = imread('img.jpg');
a = rgb2gray(I);
bw = double(imread('mask_img.jpg'))/255;
b = rgb2gray(bw);
bwi = 1-b;
And working on the original image and ground truth of the image. I can handle one image and I have loop in the my main file.
for i=1:original_images_db.Count
original = original_images_db.ImageLocation(i);
groundtruth = original_file;
[x,y] = calculateFeatures(original, groundtruth, parameters);
dataset.HorizonFeats{i} = features;
end
And i related original_images_db with imageset to files. When i run my main file, naturally everytime it reads img from function file but actually in command file main can detect other images. My question is how can i make a loop in my function file so my data can be in all other images?
Thank you
fname={'1.jpg','2.jpg','3.jpg'};
create cell like that, it contains all file-path of images
for i=1: length(fname)
im= imread(fname{i});
end
and now you can iterate the all images
or
use dir(image_path) function
fnames = dir('image_directory_path');

How to save 3d arrays in Matlab that are generated in a loop?

I'm reading in 3d arrays, subtracting all of them from one of them, and trying to save the results as the same type of arrays. They are all equal sizes to each other, 1888x3520x6.
Here is the piece of code that I have:
[FileName,PathName,FilterIndex] = uigetfile('*.x3d*','MultiSelect','on');
numfiles = size(FileName,2);
FileName{1}
entirefile1 =fullfile(PathName,FileName{1})
Im1 = x3dread(entirefile1);
for j = 2:numfiles
FileName{j}
entirefile2 =fullfile(PathName,FileName{j})
Im2 = x3dread(entirefile2);
J = num2str(j);
strcat('ImDelta', J);
ImDelta = imsubtract(Im1, Im2);
end
I see that I'm creating a character sring by using strcat. But I'm not making it into a new file name. Only one file is resulting at the end of the loop.
(x3dread function is similar to "load" for working with images, only it is specifically written to handle the type of the 3dimention files that I have.)
Any help is appreciated. I'm just a beginner.

What is the fastest way to load multiple image tiff file in matlab?

I have a multiple image tiff file (3000 frames for example) and want to load the each image into matlab (I am using 2010a now). But I found it takes longer time to read images as the index of the frame increasing. The following is the code I am using now
for i=1:no_frame;
IM=imread('movie.tif',i);
IM=double(IM);
Movie{i}=IM;
end
Is there any other way to do it faster?
The TIFF-specific syntax list for IMREAD says the following for the 'Info' parameter:
When reading images from a multi-image
TIFF file, passing the output of
imfinfo as the value of the 'Info'
argument helps imread locate the
images in the file more quickly.
Combined with the preallocation of the cell array suggested by Jonas, this should speed things up for you:
fileName = 'movie.tif';
tiffInfo = imfinfo(fileName); %# Get the TIFF file information
no_frame = numel(tiffInfo); %# Get the number of images in the file
Movie = cell(no_frame,1); %# Preallocate the cell array
for iFrame = 1:no_frame
Movie{iFrame} = double(imread(fileName,'Index',iFrame,'Info',tiffInfo));
end
You may want to preassign the array Movie (or use R2011a, where growing an array inside a loop is less of an issue)
Movie = cell(no_frame,1);
for i=1:no_frame;
IM=imread('movie.tif',i);
IM=double(IM);
Movie{i}=IM;
end
I had the same problem and found this using that I tried this code. I get different time than he did but it is still much better than other image formats. For the last method to work you should find tifflib.mexa64 in your matlab directory and copy it into your working directory.
FileTif='myfile.tif';
InfoImage=imfinfo(FileTif);
mImage=InfoImage(1).Width;
nImage=InfoImage(1).Height;
NumberImages=length(InfoImage);
t=zeros(1,1000);
FinalImage=zeros(nImage,mImage,3,NumberImages,'uint8');
for i=1:NumberImages
tic
FinalImage(:,:,:,i)=imread(FileTif,'Index',i);
t(i)=toc;
end
%disp(sprintf('test1 timing result:\n\t\t%d',toc));
mean(t)
clear
%%
FileTif='myfile.tif';
InfoImage=imfinfo(FileTif);
mImage=InfoImage(1).Width;
nImage=InfoImage(1).Height;
NumberImages=length(InfoImage);
FinalImage=zeros(nImage,mImage,3,NumberImages,'uint8');
t=zeros(1,1000);
for i=1:NumberImages
tic
FinalImage(:,:,:,i)=imread(FileTif,'Index',i,'Info',InfoImage);
t(i) = toc;
end
%disp(sprintf('test2 timing result:\n\t\t%d',toc));
mean(t)
clear
%%
FileTif='myfile.tif';
InfoImage=imfinfo(FileTif);
mImage=InfoImage(1).Width;
nImage=InfoImage(1).Height;
NumberImages=length(InfoImage);
FinalImage=zeros(nImage,mImage,3,NumberImages,'uint8');
t=zeros(1,1000);
TifLink = Tiff(FileTif, 'r');
for i=1:NumberImages
tic
TifLink.setDirectory(i);
FinalImage(:,:,:,i)=TifLink.read();
t(i) = toc;
end
TifLink.close();
%disp(sprintf('test3 timing result:\n\t\t%d',toc));
mean(t)
clear
%%
FileTif='myfile.tif';
InfoImage=imfinfo(FileTif);
mImage=InfoImage(1).Width;
nImage=InfoImage(1).Height;
NumberImages=length(InfoImage);
FinalImage=zeros(nImage,mImage,3,NumberImages,'uint8');
FileID = tifflib('open',FileTif,'r');
rps = tifflib('getField',FileID,Tiff.TagID.RowsPerStrip);
t=zeros(1,1000);
for i=1:NumberImages
tic
tifflib('setDirectory',FileID,i);
% Go through each strip of data.
rps = min(rps,nImage);
for r = 1:rps:nImage
row_inds = r:min(mImage,r+rps-1);
stripNum = tifflib('computeStrip',FileID,r);
FinalImage(row_inds,:,:,i) = tifflib('readEncodedStrip',FileID,stripNum);
end
t(i)=toc;
end
mean(t)
tifflib('close',FileID);
I have written a Matlab class to efficiently and quickly read TIFF stacks.
Load multi-page TIFF stacks into Matlab fast.
or from the file exchange:
Fast lazy-loading of TIFF stacks.
I have found that it is much faster to avoid using imread. Try this:
function data = FastTiff(filename)
warning('off','all') % Suppress all the tiff warnings
tstack = Tiff(filename);
[I,J] = size(tstack.read());
K = length(imfinfo(filename));
data = zeros(I,J,K);
data(:,:,1) = tstack.read();
for n = 2:K
tstack.nextDirectory()
data(:,:,n) = tstack.read();
end
warning('on','all')
end

Resources