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.
Related
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.
I do not understand the function 'regionprops' properly. For example if I create a binary matrix with three different areas, it only gives me a single centerpoint as output:
a = zeros(100,100);
a(1:49,1:49) = 1;
a(1:25,75:100) = 1;
a(51:100,51:100)= 1;
spy(a)
regionprops(a,'Centroid')
But if I add the line
a=bwmorph(a,'erode',0);
which does absolutely nothing, I get three different center points as output, one for each area. Why do they give different outputs and is it really necesarry to add a useless line of code?
The input to regionprops should be a logical array. If it's not, then it's assumed that the input is a labels matrix, as such it's processed as if all of the 1 values are part of the same object.
You can fix this by explicitly converting it to a logical matrix
regionprops(logical(a), 'Centroid') % or regionprops(a == 1, 'Centroid')
The better option may be to make a a logical to begin with by using false rather than zeros to construct a.
a = false(100, 100);
a(1:49,1:49) = 1;
a(1:25,75:100) = 1;
a(51:100,51:100)= 1;
The reason why the no-op erode causes it to work, is that the output of bwmorph is a logical matrix.
I have 40 structures in my Workspace. I Need to write a script to calculate the directional derivatives of all the elements. Here is the code :
[dx,dy] = gradient(Structure_element_1.value);
dxlb = min(min(dx));
dxub = max(max(dx));
dylb = min(min(dy));
dyub = max(max(dy));
[ddx,ddy] = gradient(gradient(Structure_element_1.value));
ddxlb = min(min(ddx));
ddxub = max(max(ddx));
ddylb = min(min(ddy));
ddyub = max(max(ddy));
This is the code for one element. I Need to find out the same for all the 40 elements and then use it later. Can anyone help with this.
To answer your literal question, you should store the variables in a structure array or at least a cell array. If all of your structures have the same fields, you can access all of them by indexing a single array variable, say Structure_element:
for i = 1:numel(Structure_element)
field = Structure_element(i).value
% compute gradients of field
end
Now to address the issue of the actual gradient computation. The gradient function computes an approximation for , where is your matrix of data. Normally, a MATLAB function is aware of how many output arguments are requested. When you call gradient(gradient(F)), the outer gradient is called on the first output of the inner gradient call. This means that you are currently getting an approximation for .
I suspect that you are really trying to get . To do this, you have to get both outputs from the inner call to gradient, pass them separately to the
outer call, and choose the correct output:
[dx,dy] = gradient(F);
[ddx, ~] = gradient(dx);
[~, ddy] = gradient(dy);
Note the separated calls. The tilde was introduced as a way to ignore function arguments in MATLAB Release 2009b. If you have an older version, just use an actual variable named junk or something like that.
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.
I'm using matlab and am quite new to it. I'm used to Java and other langauges.
Some background: I'm manipulating images, I work with the imread, imshow etc. commands. I want to store multiple images in an array.
So what I do is
img_list = zeroes(num_images, 1200, 1600, 3) % height,width,RGB
and then I load the images with img_list(i,:,:,:) = my_image; iteratively. That is all working fine.
Now I can display the images as I want by doing imshow(squeeze(img_list(1,:,:,:))). I can't stand this. I would like something as simple as imshow(img_list(1)).
Any idea how I can do this?
I definetly am open to change the type of img_list. Any hints is appreciated. Maybe I could do something so all my images in img_list don't have to be of the same size?
Thanks in advance. :)
The easiest solution would be to use a cell array. Each element of a cell array is a container that can hold a variable of any type and size. You access the element of a cell array as array(i) (which returns a 1-by-1 cell). To access the contents of an element of a cell array, you use curly brackets, i.e array{i}. Also have a look at CELLFUN, which allows you to perform operations on each image.
%# initialize the cell array
img_list = cell(num_images);
%# add an image to the cell array
img_list{4} = someImage;
%# display the image
imshow(img_list{4})
%# display only the red channel
imshow(img_list{4}(:,:,3))
Using cell arrays, as Jonas suggested, is probably the Right Thing -- especially if you want to be able to have images of different sizes. But it's worth mentioning that you can make the simple 4-dimensional-array approach a little nicer: make the image number the last index instead of the first. Then you can say img_list(:,:,:,i) = my_image; and imshow(img_list(:,:,:,1)); with no need for squeezing. That's probably a little better for memory locality (hence for performance) too, though it won't be any better than using cell arrays.
Define a local anonymous function:
% Get image list from somewhere.
img_list = ...;
% ...
% Easy-access to individual frames.
nth_image = #(k) squeeze(img_list(k,:,:,:));
image_count = size(img_list,1);
% Loop over images.
% ...
This allows you to write the following list:
% Process each image.
for i = 1 : image_count,
img = nth_image(i);
% ...
end
If you have multiple image lists or this pattern occurs often, you can write more generic functions:
function [ img ] = get_nth_image ( img_list, k )
img = squeeze(img_list(k,:,:,:));
end
function [ img_list ] = set_nth_image ( img_list, img, k )
img_list(k,:,:,:) = img;
end