When I run this code:
fileFolder = fullfile(matlabroot,'toolbox','images','imdemos');
dirOutput = dir(fullfile(fileFolder,'AT3_1m4_*.tif'));
fileNames = {dirOutput.name}'
zImg=montage(fileNames, 'Size', [2 5]);
imwrite(zImg,'C:\Users\xc\Desktop\ATMtemp.png')
I get the montage image in a new figure, but can I cancel it and just store it in memory?
Furthermore, I cannot save the montage. Any reason why and how can I do it without using getframe as I do not want to show the figure generated?
The montage function in MATLAB's image processing toolbox is for display purposes only and so it only shows a figure. The only way that you'd be able to get the image data from this figure is if you assign a handle to a function as output (which is zImg in your case), then use the getframe/cdata idiom you have suggested. However, this will give you a white border as you have also noticed.
If you want to create an image that is doing the same thing as montage, you can construct what montage is doing yourself. An alternative to montage would be to read in all of the images in a cell array, then arrange them in a montage manually. I'm going to assume that you are stacking the images in row-major format, so the rows are being populated one row at a time. That means images 1 to 5 will be the first row while images 6 to 10 will be the second row.
The trick to get it into a 2D matrix is that you need to use reshape. reshape will populate elements in column-major format, so you need to construct the transpose of your result, then transpose that when you're done. After, use cell2mat to eliminate the cell arrays and make a final 2D matrix.
As such, do something like this:
%// Your code to get all of the image file names
fileFolder = fullfile(matlabroot,'toolbox','images','imdemos');
dirOutput = dir(fullfile(fileFolder,'AT3_1m4_*.tif'));
fileNames = {dirOutput.name};
%// Create a 1D cell array that will store all of the images
images = cell(1, numel(fileNames));
%// Read in the images yourself and populate the cell array
for idx = 1 : numel(fileNames);
images{idx} = imread(fileNames{idx});
end
%// Reshape the cell array so that it's a 2 x 5 matrix, then
%// convert the 2D cell array into a final 2D matrix.
zImg = cell2mat(reshape(images, [5, 2]).');
%// Write to file
imwrite(zImg,'C:\Users\xc\Desktop\ATMtemp.png')
I'm not 100% sure I understand what you're asking, but if you want to plot a bunch of figures and save them to file without having the figure windows flashing by, you could use figure('Visible', 'Off').
Related
Is there a way if I want to apply medfilt2 function to the specific pixel locations rather than the whole image? The pixel locations can be represented using a binary image called IMask.
The lazy method is to just apply medfilt2 on the whole image and then copy the specific locations. E.g.
A = magic(10); % sample matrix
IMask = logical(randi([0 1],10)); % sample locations
B = medfilt2(A);
A(IMask) = B(IMask);
Not very elegant, but will do the job unless your matrix is gigantic and IMask is mostly false.
I do not see the point but if you define the matrix you are passing to medfilt2 is a subset of your image that you want being processed but you have to take care of the padding (zeros/symmetric/etc values at the boundaries).
Afterwards, you just have to replace the processed matrix within the image at the right position.
I already had some figure that I saved before, Like this:
Now after some days, I need the original size of these images for copy these in my paper. I want to extract the main matrix of these three image for save these again with imwrite function.
I searched this problem on the internet but the people says I have to use getframe and frame2im functions. But how? I want the original matrix. Can anyone tell me how to extract the main matrix from the figured image in matlab??
Try using the following code:
imgs = findobj(gcf,'Type','image');
images = cell(1,numel(imgs));
for i = 1:numel(imgs)
images = get(imgs(i),'CData');
end
The image matrices should now be stored in the separate cells of images.
I have an image that was read in using the imread function. My goal is to collect pairs of pixels in an image in MATLAB. Specifically, I have read a paper, and I am trying to recreate the following scenario:
First, the original image is grouped into pairs of pixel values. A pair consists of two neighboring pixel values or two with a small difference value. The pairing could be done horizontally by pairing the pixels on the same row and consecutive columns, or vertically, or by a key-based specific pattern. The pairing could be through all pixels of the image or just a portion of it.
I am looking to recreate the horizontal pairing scenario. I'm not quite sure how I would do this in MATLAB.
Assuming your image is grayscale, we can easily generate a 2D grid of co-ordinates using ndgrid. We can use these to create one grid, then shift the horizontal co-ordinates to the right to make another grid and then use sub2ind to convert the 2D grid into linear indices. We can finally use these linear indices to create our pixel pairings that you have described in your comments (you should really add that to your post BTW). What's important is that you need to skip over every other column in a row to ensure unique pixel pairings.
I'm also going to assume that your image is grayscale. If we go to colour, this will be slightly more complicated, and I'll leave that to you as a learning exercise. Therefore, assuming your image was read in through imread and is stored in im, do something like this:
[rows,cols] = size(im);
[X,Y] = ndgrid(1:rows,1:2:cols);
ind = sub2ind(size(im), X, Y);
ind_shift = sub2ind(size(im), X, Y+1);
pixels1 = im(ind);
pixels2 = im(ind_shift);
pixels = [pixels1(:) pixels2(:)];
pixels will be a 2D array, where each row gives you the pixel intensities of a particular pairing in the image. Bear in mind that I processed each row independently. As such, as soon as we are done with one row, we simply move on to the next row and continue the procedure. This also assumes that your image has an even number of columns. Should it not, you have a decision to make. You need to either pad the image with one column at the end, and this column can be anything you want, or you can remove this column from the image before processing. If you want to fill in this column, you can either make it all zeroes, or perhaps replicate the last column and place this beside the last column in the original image. Therefore, an appropriate pre-processing step may look something like this:
if mod(cols,2) ~= 0
im = im(:,1:end-1);
end
The above code simply removes the last column in the image if the number of columns is odd. Once you run through this code, you can run the first bit of code that I had above.
Good luck!
I'm working on an optical character recognition project where I am trying to create a program which will recognize alphabetic letters from an image. I'm following the tutorial located on Mathworks(Digit Classification). In their example, their training images are already separated. Unfortunately, I was provided with training images which contain hundreds of letters in a single file.
Here is a sample:
I need an efficient way to segment each individual letter into an image, so I would have a 26Xn array where 26 is each letter in the alphabet and n is n image data variables containing individual letters. It would be extremely tedious to manually segment letters from each training image or attempt to segment letters by a specified length since the separation between letters isn't always equal.
Does anyone know of a MATLAB function or a simple way where I can identify the height and length of every continuous white colored object and store all the individual white objects with their black background in the 26Xn array described above (or at least stored in some type of array so I can later process it into the 26xn array)?
If you want to extract every individual character in your image, you can very easily do that with regionprops. Simply use the BoundingBox attribute to extract the bounding box surrounding each character. After you do this, we can place each character in a cell array for further process. If you want to store this into a 26 x N array, you would need to recognize what each letter was first so that you can choose the slot that the letter is supposed to go in for the first dimension. Because you want to segment out the characters first, we will focus on that. As such, let's load in the image into MATLAB. Note that the original image was in GIF and when I loaded it on my computer... it looked pretty messed up. I've resaved the image into PNG and it's shown below:
Let's read this into MATLAB:
im = imread('http://i.stack.imgur.com/q7cnA.png');
Now, you may notice that there are some discontinuities between some letters. What we can do is perform a morphological opening to close these gaps. However, we aren't going to use this image to extract what the actual characters are. We are only using these to get the bounding boxes for the letters:
se = strel('square', 7);
im_close = imclose(im, se);
Now, you'd call regionprops like this to find all of the bounding boxes in the image (after applying morphology):
s = regionprops(im_close, 'BoundingBox');
What is returned in s is a structure where each element in this structure contains a bounding box that encapsulates an object detected in the image. In our case, this is a single character. The BoundingBox property for each object is a 4 element array that is formatted like so:
[x y w h]
(x,y) are the column and row co-ordinates of the upper left corner of the bounding box and w and h are the width and height of the bounding box. What we will do next is create a 4 column matrix that encapsulates all of these bounding box properties together, where each row denotes a single bounding box:
bb = round(reshape([s.BoundingBox], 4, []).');
It's necessary to round the values because if you want to extract the letters from the image, we have to do this in integer co-ordinates as that is how the image is naturally defined. If you want a good illustration of these bounding boxes, this code below will draw a red box around each character we have detected:
imshow(im);
for idx = 1 : numel(s)
rectangle('Position', bb(idx,:), 'edgecolor', 'red');
end
This is what we get:
The final job is to extract all of the characters and place them into a cell array. I'm using a cell array because the character sizes are uneven, so putting this into a cell array will accommodate for the different sizes. As such, simply loop over every bounding box we have, then extract the bounding box of pixels to get each character and place it into a cell array. Therefore:
chars = cell(1, numel(s));
for idx = 1 : numel(s)
chars{idx} = im(bb(idx,2):bb(idx,2)+bb(idx,4)-1, bb(idx,1):bb(idx,1)+bb(idx,3)-1);
end
If you want a character, simply do ch = chars{idx}; where idx is any number from 1 to as many characters as we have. You can also see what this character looks like by doing imshow(ch);
This should hopefully give you enough to get started. Good luck!
You are looking for bwlabel to label each letter in your image.
Another tool you might find useful is regionprops, especially the 'Image' property.
In your comment you state that you struggle with the order at which Matlab is labeling your regions: Matlab's matrices and images are stored in memory in a column major order (that is column after column), thus is "discovers" new components in the binary image from top to bottom and from left to right. In order to explore the image row by row from to to bottom, you might want to consider transposing the image:
[ind map] = imread('http://i.gyazo.com/0ca8d4416a52b8bc3401da0b71a527fd.gif'); %//read indexed image
BW = max( ind2rgb(ind,map), [], 3 ) > .15; %//convert RGB image to binary mask
seg = regionprops( BW.', 'Image' ); %'// transpose input mask
seg = arrayfun( #(x) x.Image.', seg, 'Uni', 0 ); %'// flip back
Now you separate letters are in cells in cell array seg.
Note that by providing regionprops with a binary input, you do not need to explicitly call bwlabel.
For MATLAB GUI in the m-file, I want to call a set of variables. I have tagged the variables as axes1,axes2,axes3,.......axes125. How can I call it in a loop? Is it possible?
L = imread('white.jpg','jpg');
set(project.cantStop,'CurrentAxes',project.axes1);
set (imshow(L));
See the code
set(project.cantStop,'CurrentAxes',project.axes1);
I want to set it the same way for all 125 variables
Use a cell array to store the axes' tags as strings and use them as the fieldnames to handles as shown below:
%// Cell arary of strings wih the axes's tags
axes_list = {'axes1','axes2','axes3'};
%// For demo on how to use the cell array, use it to choose the axes with
%// tag - `project.axes2`
axes(project.(axes_list{2}));
Thus, you can use a for-loop to loop through the axes for your case, like this -
for k = 1:numel(axes_list)
set(project.cantStop,'CurrentAxes',project.(axes_list{k}));
end
As an example to something similar to what you are trying to achieve with your sample codes, you can show a series of images on the axes. For the demo, let's suppose if you have a set of three images that you would like to show on three axes of the GUI.
%// List of image filenames as a cell array
files_list = {'p1.jpg','p2.jpg','p3.jpg'};
%// List of axes tags as a cell array of strings
axes_list = {'axes1','axes2','axes3'};
%// Show those three images on three different axes of the GUI
for k = 1:numel(files_list)
L = imread(files_list{k},'jpg');
axes(project.(axes_list{k}));
imshow(L);
end