Issue using imfill command in MATLAB - 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.

Related

Making a copy of an image via a Loop not working

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.

How to save matrixes as a vector

I have a text file that is a matrix 2819x10.
I have splited it into 5x5x563 matrix using code below
Matrix = dlmread('det.txt');
for j=1:1:563
for i=1:1:5
M(i,1,j) = Matrix(temp,3);
M(i,2,j)= Matrix(temp,4);
M(i,3,j)= Matrix(temp,5);
M(i,4,j) = Matrix(temp,6);
M(i,5,j) = 1;
temp=temp+1;
end
end
After this code I have Matrix 5x5x563. Right now I would like to to create a array like is presented bellow, that consist only one row, and each column is my matrix of 5x5.
I have tried with mat2cell:
MatrixNew= mat2cell(M, 5, 5);
But I have still an error. I dont have clue how to fix it. I am not try to find a ready code but just advice.
How can I accomplish this?
I think reshape should do the job for you. For example:
x=reshape(M,[1 5*5*563]);
or you can use other variations of the reshape function by playing around with it.

Plotting arrays from a cell list of strings

Suppose I have different rows loaded from a .mat file (using load filename.mat) containing float numbers following the same naming convention, e.g:
file_3try = [ 2.4, 5.2, 7.8 ]
file_4try = [ 8.7, 2.5, 4,2 ]
file_5try = [ 11.2, 9.11 ]
to plot all of these in one plot using automation (I have many more rows than in the example above) I created a cell containing the names of the arrays by using:
name{l} = sprintf('%s%02i%s','file_',num,'try');
inside a for loop with num the numbers in the names and l a counter starting from 1.
But when I try to plot the arrays using for example:
plot(name{1})
I get the error:
Error using plot
Invalid first data argument
Is there a way to solve this, or am I going about this wrong?
There is something built in to solve this
data = load ( 'filename' ); % load data and store in struct
fnames = fieldnames ( data );
for ii=1:length(fnames)
plot ( axHandle, data.(fnames{ii}) );
end
axHandle is a handle to the axes you want to plot on. Its not required but it is good practice to use it. If its not provided then the plot command will plot on the current axes, e.g. gca.
So as mentioned already you need to use eval.
Assuming the file_**X**try rows are different lengths then you could just place all of them in a cell rather than creating a cell of the variable names. So instead of assigning to separate variables the way you are doing you could assign to a cell, so:
file_try{i} = [.....];
You can then cycle through file_try and plot each entry:
for i = 1:length(file_try)
plot(file_try{i});
end
If the rows are not different lengths then stick them in a matrix and plot it.

Printing from Matlab to Excel

I am creating a dummy example for my situation. Real problem is way more complicated.
Dummy Example:
I have a struct of size 2 with an entry called 'name' and an array of size 2x1.
So, the Struct called Store looks like:
Store(1).name = 'Apple';
Store(1).Data = [1; 2];
Store(2).name = 'Orange';
Store(2).Data = [24; 57];
I want to print this to excel such that it looks like the following:
Apple 1
Apple 2
Orange 24
Orange 57
I don't even know how to start with the above example. I have used xlswrite in the past but never for mixed type data.
If all your Data fields are of size 2x1, you should be able to the following:
% prepare cell to hold your data
xlData = cell(2*numel(store), 2);
% fill column 1:
xlData(1:2:end-1,1) = {store.name};
xlData(2:2:end,1) = xlData(1:2:end-1);
% fill column 2:
xlData(:,2) = num2cell(vertcat(store.Data));
% write to excel:
xlswrite('yourExcelfile.xlsx', xlData)
Got no Matlab at hand to test, but it should help you get going.
Since xlswrite takes a cell-array, there's no issue with mixed datatypes.

How to take part of matrix if unknown number of dimension in Matlab? [duplicate]

This question already has answers here:
Using a colon for indexing in matrices of unknown dimensions
(2 answers)
Closed 9 years ago.
Suppose I want do something similar to
image(1:end-1,2:end,:)
which here is taking part of colored image
but with unknown number of dimensions, i.e. which will work automatically like
image(1:end-1,2:end)
for 2 dimensions
image(1:end-1,2:end,:)
for 3 and
image(1:end-1,2:end,:,:)
for 4 and so on.
If you always want to take all of the 3rd dim and up, you can use
>> image(1:end-1,2:end,:,:,:)
even for 2D array.
Alternatively, you can use subsref for a less ad-hoc/hacky approach:
>> [S.subs{1:ndims(image)}] = deal(':');
>> S.subs{1} = '1:end-1';
>> S.subs{2} = '2:end';
>> S.type = '()';
>> subsref(image, S )
I would have two ideas for this case.
1st way:
You could reshape your image before, e.g.
% transform image to 3d format
% do not forget to transform all used entities to this 3d-format as well
sizeIm = size(image);
image3 = reshape(image,[sizeIm(1:2),prod(sizeIm(3:end)])
% work on image3
image3(1:end-1,2:end,:) = ...;
% transform back:
image = reshape(image3,sizeIm);
2nd way:
Could be a solution to use eval and repmat, e.g.
eval(['image(1:end-1,2:end',repmat(',:',[1,length(size(image))-2]) ')'])
Depends a little bit on what you are using it for (setting, getting, ...).
Suppose you have an array A:
A = rand(2,3,2,5,7);
Then, you can fill with ':', the remaining dimensions of your selection:
nd = ndims(A);
subs = repmat({':'},1,nd-2);
A(1:end-1,2:end, subs{:})
I have there a little idea. You can formulate a function, that analyse the dimension of your Matrix with size(size(Matrix),2). Then you are able to construct a string, that contain your desired command with a little for loop and after this you execute this string with eval.
A=rand(3,3,3,3,3,3,3,3,3,3) %<--- change here dimension
dim=size(size(A),2)
addstr='';
if dim>2
for i=1:dim-2
addstr=[addstr ',:'];
end
end
command=['A(1:2,1:2' addstr ')']
eval(command)