Making a copy of an image via a Loop not working - matlab

Idk why the code won't work. All it does is give me a blank white image. And if you don't declare a matrix before by zeros(x, y) then it works fine. Wth is wrong here?
I tried not declaring the zeros matrix before and only that works. I even tried doing img2(i,j) = img2(i,j)+img1(i,j)
function [imgOut] = scaleLoopBased(img,s)
%UNTITLED4 Summary of this function goes here
% creating a zero matrix of the given scale
[rows,columns]=size(img);
imgTemp=zeros(rows, columns);
for i=1:rows
for j=1:columns
imgTemp(i, j) = img(i, j);
end
end
imshow(imgTemp);
imgOut = imgTemp;
end
Blank white image

This is a result of your new image (of type double, what zeros creates by default) not having the same type as your original image (typically type uint8). You can fix this by initializing your new image to have the same data type as the original using the class function and passing an additional argument to zeros:
imgTemp = zeros(rows, columns, class(img));
The reason it works correctly when you don't initialize imgTemp is because MATLAB initializes the variable for you using the data type of img by default when you perform the first indexed assignment.
The imshow utility expects one of the standard image types in MATLAB. An image of type double is expected to have values spanning the range [0 1], while images of type uint8 will have values in the range [0 255]. In your example you likely have a matrix imgTemp that is of type double but has values spanning [0 255]. Another way to fix your issue is to explicitly tell imshow what value range to use for the display (since the default [0 1] doesn't work):
imshow(imgTemp, [0 255]);
Always be aware of the data type when manipulating or processing images. You may need to scale or convert back and forth, using a double type for calculations (since integers saturate) and a uint8 type for display and reading/writing to files.

Related

How to make a GIF from a set of MATLAB images

I have an array of values which I turn into a color image like so:
my_img = imagesc(my_data(:,:,tidx)); axis off; colormap('default'); c=colorbar; c.FontSize=26; c.FontWeight='bold';
I want to know if it's possible to loop through all the index values in my_data and turn them into a GIF.
I tried this:
for tidx = 5:64
my_img = imagesc(my_data(:,:,tidx)); axis off; colormap('default'); c=colorbar; c.FontSize=26; c.FontWeight='bold';
imwrite (my_img, int2str(tidx)+"_cspattern.png");
end
Which gave me this error:
Error using imwrite (line 427)
Expected DATA to be one of these types:
numeric, logical
Instead its type was matlab.graphics.primitive.Image.
I looked it up and tried this solution out:
for tidx = 5:64
my_img = imagesc(my_data(:,:,tidx)); axis off; colormap('default'); c=colorbar; c.FontSize=26; c.FontWeight='bold';
IMG_to_write = uint8(normalize(my_img, 'range', [0 255]));
imwrite(IMG_to_write, int2str(tidx)+"_cspattern.png");
end
But that just gave me this error:
Error using normalize>checkSupportedArray (line 159)
Invalid data type. First argument must be a real numeric or logical array, a table or a timetable.
Error in normalize (line 86)
checkSupportedArray(A,method,methodType,false);
Error in GenerateFigures (line 18)
IMG_to_write = uint8(normalize(SavePattern, 'range', [0 255]));
I feel as if I am overthinking this because there must be a simple way to load the data I want and save it as an image or series of images.
imagesc produces a graphics object, not a data array. It’s meant for displaying images into figures, not saving them into files. You need to hand imwrite your image data directly, along with your desired color map.
for tidx = 5:64
imwrite(my_data(:,:,tidx),parula(),int2str(tidx)+"_cspattern.png");
end
If you want to scale each image so that the full color range is used, the way imagesc does, you can do this manually.
for tidx = 5:64
my_data_slice = double(my_data(:,:,tidx));
my_data_slice = my_data_slice - min(my_data_slice,[],'all');
my_data_slice = my_data_slice / max(my_data_slice,[],'all')*255;
my_data_slice = uint8(my_data_slice);
imwrite(my_data_slice,parula(),int2str(tidx)+"_cspattern.png");
end

Issue using imfill command in MATLAB

Hi I have a binary variable (called 'column' size 733x1) and I am trying to change the 0's in-between where I have 1's to 1's (i.e. 00001110011... to 00001111111...). I have tried using imfill, however have been unable to do so. I have converted it from type logical to uint8 to help but it hasn't worked.
column=column*255 % convert to form to work with 'imfill' command
column_fill=uint8(column)
column_fill=imfill(column);
However in between 1's within my variables I still have several 0's which I want to get rid of. Link to data. Output (from 000..000111000011101... to 000..000111111111111...) Thanks.
Try the following sample:
load data
column=column100*255 % convert to form to work with 'imfill' command
%Create column filled with 255 values.
white_column = ones(size(column))*255;
%Padd column from both sides (create 3 columns image).
im = [white_column, column, white_column];
%Apply imfill on image im
im_fill = imfill(uint8(im));
%Extract center column of im_fill.
column_fill = im_fill(:, 2);
You can also try the following code without using imfill:
column_fill = column100;
column_fill(find(column100 == 1, 1):find(column100 == 1, 1, 'last')) = 1;
You could use imfill with the 'holes' option
BW2= imfill(BW,'holes')
but you should leave your image binary and not multiply with 255.

Checking size of matrix results in error

Error:
Subscript indices must either be real positive integers or logicals.
Hi I am doing image conversion and I get an error when checking the size of the matrix. I am confused as to why I am getting it for this particular instance with the code:
size(maleGrey)
Here is the code I am running:
male = getAllFiles('male');
% Variable Initialization
size = 250*250;
numM = length(male);
maleGrey = zeros(size,numM);
% Convert to gray scale
for i = 1:numM
rgb = imread(char(male(i)));
img = single(rgb2gray(rgb));
vec = img(:); % make it a vector of (62500,1) in size
maleGrey(:,i) = vec;
end
You made the mistake of using size as a variable when calling size=250*250. Once you do that in a workspace, the function is masked (overloaded) by the variable, and Matlab will always treat further calls to size as manipulations of the variable.
Call clear size, and the function will work as intended. Also, do not use size as name for a variable (or other function names like length or double, or zeros etc), but e.g. siz, or numberOfRows (because that's what your variable stands for).
You're overwriting (locally) Matlabs native function reference size by a variable name
% Variable Initialization
size = 250*250; % <--
Hence when you call size(maleGrey) it treats maleGrey as an index in the variable size.

createMask and function call syntax

As a follow up to my question here:
What does createMask actually do? I went to the description from MathWorks here, but wan't much clear.
If you see in the answer of my question referenced above: img2(roi.createMask) = 1;, the part roi.createMask reminds me of function call, is that what we are really doing here? Calling the createMask function?
Thanks.
In the code
img = im2double(imread('cameraman.tif'));
imshow(img);
roi = imfreehand(gca);
img2 = img;
img2(roi.createMask) = 1;
imshow(img2);
roi is the handle to the object generated by imfreehand. One of the methods (~functions) available through the object (using the handle) is createMask, which can be accessed with the . operator. The method generates a type logical array of the same size as the pixel dimensions of the image. Values in the logical array are either 1 or 0 with values of 1 assigned to entries in the region corresponding to the area selected with the imfreehand operation. The operation img2(roi.createMask) =1; indexes into the image img2 (it picks elements in img2) using the positions in the logical array with value 1 and assigns those elements value 1.

Matlab rgb2hsv dimensions

I am reading in the matlab documentation that rgb2hsv will return an m-by-n-by-3 image array, yet when I call it, I get a 1-by-3 vector. Am I misunderstanding something?
Here is an sample code:
image_hsv = rgb2hsv('filepath')
and as output
image_hsv =
0.7108 0.3696 92.0000
You cannot call rgb2hsv on a filepath - it must be called on a MATLAB image matrix. Try:
image_rgb = imread('filepath'); % load the image array to MATLAB workspace
image_hsv = rgb2hsv(image_rgb); % convert this array to hsv
You can see these matrices with:
>> whos image* % display all variables whose name begins with 'image'
Name Size Bytes Class Attributes
image_hsv 480x640x3 7372800 double
image_rgb 480x640x3 921600 uint8
What your original code was doing was converting your filepath string to ascii numbers, taking the first three values of this array as RGB values and converting these to HSV.
NOTE: This example highlights dangers with MATLAB's weak typing system, where data types are silently converted from one type to another. Also maybe a lack of correct input checking to the rgb2hsv function.