Asked by user
on 19 Mar 2018

I am doing some image analysis and getting the following error message:

In an assignment A(:) = B, the number of elements in A and B must be the same.

Error in FINAL (line 37)

bottomLine(col) = find(croppedImage(:, col), 1, 'last');

I have made sure that my column vector (col) is the proper length, but it doesn't seem to be working. For some context, the purpose of this set of code is to analyze a video file of a droplet on a surface. As the droplet freezes, I see the freezing line move up.

I have also watched this video: https://blogs.mathworks.com/videos/2014/11/20/matlab-in-an-assignment-ai-b-the-number-of-elements-in-b-and-i-must-be-the-same/

When I evaluate my "problem" line of code (line 37) all of my variables are of acceptable length, the columns vector is 236 and so is the columns of the croppedImage matrix. The for loops seems to stop at column number 148 every time which I don't understand.

Here is my code:

nstart = 260;

nend = 700;

Height = (90:370); %Temporary

Width1 = (94:796); %Temporary

Width2 = (1060:1775); %Temporary

load('Crop1.mat')

%%Processing for Droplet 1

numberOfCells = length(Crop1);

freezingLine1 = zeros(1, numberOfCells);

L1 = round((length(Width1)/3)):round((2*length(Width1)/3));

for k = 1:numberOfCells

thisCell = Crop1{k};

if ~isempty(thisCell)

subplot(2, 2, 1);

imshow(thisCell);

axis on;

caption = sprintf('Frame %d of %d', k, numberOfCells);

title(caption, 'FontSize', fontSize);

% Extract columns 200-300

croppedImage = thisCell(1:length(Height), L1);

subplot(2, 2, 2);

imshow(croppedImage);

axis on;

title(caption, 'FontSize', fontSize);

% Get the bottom most pixel

[rows, columns] = size(croppedImage);

bottomLine = zeros(1, columns);

for col = 1 : columns

bottomLine(col) = find(croppedImage(:, col), 1, 'last');

end

subplot(2, 2, 3);

plot(bottomLine, 'b-', 'LineWidth', 2);

ylim([1, rows]);

xlim([1, columns]);

title('Bottom Pixels', 'FontSize', fontSize);

xlabel('Column', 'FontSize', fontSize);

ylabel('Row', 'FontSize', fontSize);

grid on;

% Throw out outliers by looking at the median absolute deviation.

medianValue = median(bottomLine);

mad = bottomLine - medianValue;

goodIndexes = mad <= 3; % Good locations have a mad of less than or equal to 3.

% Find the mean of the good indexes.

freezingLine1(k) = mean(bottomLine(goodIndexes));

subplot(2, 2, 4);

plot(freezingLine1, 'b-', 'LineWidth', 2);

grid on;

title('Freezing Line Row1', 'FontSize', fontSize);

xlabel('Frame', 'FontSize', fontSize);

ylabel('Row', 'FontSize', fontSize);

drawnow;

end

end

and attached is a .mat file that needs to be loaded to run the code.

Answer by Ahmet Cecen
on 19 Mar 2018

Edited by Ahmet Cecen
on 19 Mar 2018

Accepted Answer

I am guessing this error is due to null matrices appearing as a result of this call:

find(croppedImage(:, col), 1, 'last');

Try this instead:

for col = 1 : 236

try

bottomLine(col) = find(croppedImage(:, col), 1, 'last');

catch

bottomLine(col) = NaN;

end

end

This would mean some columns in the image simply doesn't have a non-zero value. I am dealing with them as NaNs here but you can assign them whatever you want.

user
on 19 Mar 2018

Thanks! That definitely fixed my problem, but I don't really understand why the solution fixes it. If you have some time, could you answer this:

The job of the "try" is to conduct the for-loop, and then when an error occurs it is caught by the "catch" which sets the value to "NaN" and places it into the null matrices (bottomLine in this case). Is this a correct explanation?

Ahmet Cecen
on 19 Mar 2018

Yes, when you try to assign an empty value to an indexed position, MATLAB throws an error saying that this is an invalid assignment. See this case:

a = [ 1 2 3]

b = []

a(2) = b

will give an error. I suspect this is a safety feature due to the following behavior where the array element is instead destroyed:

a = [ 1 2 3]

a(2) = []

Try will "try" to execute a statement within the try block and if there is an error "thrown" during that execution, it will "catch" that error and execute the "catch" block instead. Your understanding is correct.

Walter Roberson
on 19 Mar 2018

I recommend instead

for col = 1 : 236

loc = find(croppedImage(:,col), 1, 'last');

if isempty(loc)

bottomLine(col) = NaN;

else

bottomLine(col) = loc;

end

end

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.