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

2 views (last 30 days)
Can you please help me to correct the above mentioned problem in the following matlab code ?
E = [5,200]; Selected edge values
X = imread('LENNA128.bmp');
N = length(X);
Y = false(N+2);
for k = 1:numel(E);
Y(2:end-1,2:end-1) = X==E(k);
Z = Y(1:end-2,2:end-1) | Y(3:end,2:end-1) | Y(2:end-1,3:end) | Y(2:end-1,1:end-2);
X(Z) = round((X(end-3,3:end-2) + X(end-3,4:end-1))/2);
end
The 'entire' error message is:
In an assignment A(:) = B, the number of elements in A and B must be the same.
  2 Comments
Stephen23
Stephen23 on 20 Jan 2016
Please edit your question and give the complete error message. This means all of the red text. It helps us understand the problem.
Gobert
Gobert on 20 Jan 2016
@Stephen Cobeldick The 'entire' error message is: In an assignment A(:) = B, the number of elements in A and B must be the same.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 20 Jan 2016
There are two issues with your code, one which may not cause you problem right now:
Problem 1: The use of length with a 2D matrix
If your image is not square, N will be the size of the largest dimension of your image. Y will always be a square image two pixels larger in both dimensions than the largest dimension of your image. The assignment
Y(2:end-1,2:end-1) = X==E(k)
will then fail as you're trying to assign a non-square matrix to a square matrix.
The simplest way to fix this is to declare:
N = size(X); %%assuming that |X| is a greyscale or indexed image.
Problem 2: Most likely the one that causes the error message:
X(Z) = round((X(end-3,3:end-2) + X(end-3,4:end-1))/2)
Z is a logical array which will select as many element of X as there are true values in Z. The other side of the assignment is the moving average of one the last row of the image excluding the first two pixels. It is a row vector with 2 less elements than the number of columns of X. I don't see why this would have as many values as there are true values in Z.
I can't tell you how to fix that because I've no idea what you're trying to do.
  4 Comments
Guillaume
Guillaume on 20 Jan 2016
X(end-3, ...) only select pixels from the 3rd row from the end, regardless of the row where you find your pixels. That is obviously wrong. The way to do this is to create a matrix of replacement values the same size as X and use Z to select the replaced and replacement on both side of the equation.
I'm not sure what you call the two adjacent pixel values, there are usually 4 (up, down, left, right) or 8 (last 4 + diagonals).If it's the left and right pixels (right or left taken to be zero when on the edge)
%make sure that X is of type double, not uint8!
Xreplacement = round(([zeros(size(X, 2), 1), X(:, 1:end-1)] + [X(:, 2:end), zeros(size(X, 1), 1)])/2);
X(Z) = Xreplacement(Z);
Note that the 1st line above is the same as a convolution:
Xreplacement = round(conv2(X, [0.5 0 0.5], 'same'))
Your whole code can also be simplified using ismember:
E = [5,200]; Selected edge values
X = imread('LENNA128.bmp');
paddedX = padarray(X, [1 1]); %if you have the imaging toolbox
toreplace = ismember(paddedX(1:end-2, 2:end-1), E) | ...
ismember(paddedX(3:end, 2:end-1), E) | ...
ismember(paddedX(2:end-1, 1:end-2), E) | ...
ismember(paddedX(2:end-1, 3:end), E);
Xconv = round(conv2(X, [0.5 0 0.5], 'same'));
X(toreplace) = Xconv(toreplace)

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!