Hi,
I have a slated edge image and I want to know the value of required pixel shift to make it vertical. I know the pixel value at first and end point of the edge. But want to scan the image line by line and know the values of shifted pixels for each line. But I am getting an error: *Matrix dimensions must agree for the following line: dif = abs(bw(i:j)- bw(i:j+1))
close all;
clear all;
clc;
I=imread('C:\Users\swati\OneDrive\Documents\MATLAB\Examples\Cropped Image.jpg');
figure;
imshow(I); title('Original Image');
impixelinfo;
m=167;n=200;
%Averaging The Pixels
h=ones(10,10)/100; %Create a normalized pixel; averaging filter.
I_avg=imfilter(I,h); %apply filter to image
figure(); imshow(I_avg);
title(I_avg);
impixelinfo;
%Scanning of Image
v=I_avg(1,:); %scanning the I_avg Intensity
figure;plot(v);
%converting GrayScale image to Binary Image
for x=1:200
for y=1:m
if I_avg(x,y)>mean(I_avg(:))
bw(x,y)=1;
elseif I_avg(x,y)<mean(I_avg(:))
bw(x,y)=0;
end
end
end
figure; imshow(bw);
impixelinfo;
%finding first left most pixel when intensity drops to zero in first row
fisrt_value=zeros([1,m]);
fist_value=bw(1,:)
%finding first left most pixel when intensity drops to zero in last row
second_value=zeros([1,m]);
last_value=bw(200,:)
p2x=1;
p2y=56;
p1x=200;
p1y=73;
m=(p2y-p1y)/(p2x-p1x) %find the slope
theta=atand(m)
shifted_pixel=p1y-p2y % number of shifted pixels
j=55;
for i = 1:20:200
dif = abs(bw(i:j)- bw(i:j+1))
fprintf('Row Number=%0.0f',i);
pos=find(dif==1)
shift=p1y-pos
j=j+1;
i= i+1;
end
Could anyone please suggest me what is wrong in my code or is there any other way to do that?
Thanks, Swati

 Respuesta aceptada

Image Analyst
Image Analyst el 31 de Jul. de 2017

0 votos

Swati, get rid of all the programming you did for this and replace it with this:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format short g;
format compact;
fontSize = 25;
%===============================================================================
% Get the name of the image the user wants to use.
baseFileName = 'binary.jpg';
% Get the full filename, with path prepended.
folder = []; % Determine where demo folder is (works with all versions).
fullFileName = fullfile(folder, baseFileName);
%===============================================================================
% Read in a demo image.
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
grayImage = rgb2gray(grayImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
% grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the image.
subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
axis image;
caption = sprintf('Original Gray Scale Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo();
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0, 1, 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
% Create binary image from grayscale image.
binaryImage = grayImage > 128;
% Display the image.
subplot(2, 1, 1);
imshow(binaryImage, []);
axis on;
axis image;
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Find edge between row 10 and 190
for row = 10:190
x(row-9) = find(binaryImage(row, :), 1, 'last');
y(row-9) = row;
end
coefficients = polyfit(x, y, 1);
angle = atand(coefficients(1))
% Rotate the image
rotatedImage = imrotate(binaryImage, angle-90);
% Display the image.
subplot(2, 1, 2);
imshow(rotatedImage, []);
axis on;
axis image;
title('Rotated Image', 'FontSize', fontSize, 'Interpreter', 'None');

2 comentarios

Swati Jain
Swati Jain el 31 de Jul. de 2017
Editada: Swati Jain el 31 de Jul. de 2017
Could you please explain this portion of the code:
for row = 10:190
x(row-9) = find(binaryImage(row, :), 1, 'last');
y(row-9) = row;
end
What is meaning of
x(row-9)
and
find(binaryImage(row, :), 1, 'last')
here, I think it is searching for 1 in binary image. Am I correct? What does 'last' mean? And why did you use row values from 10 to 190?
Walter Roberson
Walter Roberson el 31 de Jul. de 2017
For clarity you could instead write,
rowvals = 10:190;
% Find edge between row 10 and 190
for rowidx = 1 : length(rowvals)
row = rowvals(rowidx);
x(rowidx) = find(binaryImage(row, :) ~= 0, 1, 'last');
y(rowidx) = row;
end
The syntax for find is
find( expression, number_of_matches_to_use, start_from_beginning_or_end )
so find(expression, 1, 'last') means to look for 1 value starting from the end (last position) and keep proceeding forward until the corresponding expression value is non-zero. In other words, the location of the last non-zero value.
The 1 does not mean to search for 1's: it is the number of values to take.
Another way of writing result = find(expression, N, 'last') is
temp = find(expression);
M = length(temp);
if M > N
M = N;
end
result = temp(end-M+1:end);
That is, if there are fewer than N available values then it will use what is there, but if there are more than N available values then it will use the last N of them.

Iniciar sesión para comentar.

Más respuestas (2)

Walter Roberson
Walter Roberson el 30 de Jul. de 2017

0 votos

In
abs(bw(i:j)- bw(i:j+1))
the left side, bw(i:j) has j-i+1 elements. The right side, bw(i:j+1) has j+1-i+1 = j-i+2 elements.
I suggest
abs(diff(bw(i:j+1)))

9 comentarios

Walter Roberson
Walter Roberson el 30 de Jul. de 2017
Note: your code
for x=1:200
for y=1:m
if I_avg(x,y)>mean(I_avg(:))
bw(x,y)=1;
elseif I_avg(x,y)<mean(I_avg(:))
bw(x,y)=0;
end
end
end
might not create bw at all, and if it does then it might not be the size you expect. Consider what happens if I_avg(x,y) == mean(I_avg(:)) -- such as could happen if I_avg was completely constant.
Note that mean(I_avg(:)) does not change in the loops, so there is no point in repeatedly calculating it:
mI = mean(I_avg(:));
for x=1:200
for y=1:m
if I_avg(x,y)>mI
bw(x,y)=1;
elseif I_avg(x,y)<mI
bw(x,y)=0;
end
end
end
And you can replace that all with
mI = mean(I_avg(:));
extract = I_avg(1:200, 1:m);
bw = extract > mI;
bw(extract == mI) = nan; %contents undefined in this case
Swati Jain
Swati Jain el 30 de Jul. de 2017
Hi,
Thanks for your response. When I used
abs(diff(bw(i:j+1)))
I got all the following for all the rows:
1×0 empty double row vector
Also, I am moving rows as 1:20:200 but it is showing answer from row #41. In addition to that when I use the following to my code for Binary conversion:
mI = mean(I_avg(:));
extract = I_avg(1:200, 1:m);
bw = extract > mI;
bw(extract == mI) = nan; %contents undefined in this case
I got the following error
NaN's cannot be converted to logicals.
Thanks,
Swati
Walter Roberson
Walter Roberson el 30 de Jul. de 2017
bw = double(extract > mI);
Walter Roberson
Walter Roberson el 30 de Jul. de 2017
You have
j=55;
for i = 1:20:200
dif = abs(bw(i:j)- bw(i:j+1))
fprintf('Row Number=%0.0f',i);
pos=find(dif==1)
shift=p1y-pos
j=j+1;
i= i+1;
end
so in the first iteration, i = 1, j = 55. 1:55 is valid subscripts so you could potentially get some results from the dif. Then, the j=j+1 increments j to 56. The i = i+1 changes i to 2. Then i gets overwritten with 21 by the next iteration of "for i = 1:20:200" . When you have a "for" loop, any changes you make to the loop control variable will be discarded as soon as the next iteration starts. Think of it has having a hidden "real" loop control variable.
So second iteration, i = 21, j = 56. 21:56 is valid subscripts so you could potentially get some results from the dif. j gets incremented to 57. i gets changed to 22, but that doesn't matter, as explained above.
Third iteration, i = 41, j = 57, 41:57 is valid, you might get something in dif. j becomes 58, i becomes 42 but that doesn't matter.
Fourth iteration, i = 61, j = 58, 61:58 is the empty range, so you cannot get any results from the loop. j becomes 59, i becomes 62 but that doesn't matter.
All subsequent iterations of i also lead to empty vectors because i > j.
Image Analyst
Image Analyst el 31 de Jul. de 2017
But the thing I'm wondering about is that bw starts as a 2-D matrix:
fist_value=bw(1,:)
then suddenly, without any reason or comment at to why, you're indexing bw with one index:
dif = abs(bw(i:j)- bw(i:j+1))
so, you either are using a linear index (unlikely), or you really meant to use a comma instead of a colon:
dif = abs(bw(i, j)- bw(i, j+1))
Are you 100% SURE you want to use a linear index (the first dif) instead of two indexes for row and column (the second dif)?
Swati Jain
Swati Jain el 31 de Jul. de 2017
Hi,
In that case I will have to find other way to do this. I want to know how many pixel I will need to shift for each line to get the vertical line. I don't want to know the slope neither want to rotate the image. I just want to know the pixel shift for each line to get vertical line. If you can suggest me any other solution of this problem, it will be great full.
I have one more idea but don't know how apply that. Since the image is binary and if I can scan for each line and say it as soon as it get 'Zero' value and tell me the position of that pixel.I think this can work but I don't know how to do that. Could you please help me in that?
Thanks,
Swati
Swati Jain
Swati Jain el 31 de Jul. de 2017
Image Analyst, Sir,
I wanted to know the pixel position of the transition from 1 to 0 for first row so that I can know the reference value, that's why I used
fist_value=bw(1,:)
Sorry for not providing proper comments.
dif = abs(bw(i:j)- bw(i:j+1))
Here, my try was to compare pixel by pixel, so whenever I get difference between two value 1, I will know the position of the transition and then I can subtract from ref. position to get the pixel shift. Actually, I meant to use colon to move through column for each row and find the difference. But I am not sure if my approach is correct or not. As I mentioned, I am completely new to MATLAB. If you have any suggestions please let me know.
Thanks for your kind help.!
Image Analyst
Image Analyst el 31 de Jul. de 2017
Do we really need to keep discussing this without an image to even look at? What's the big secret? Show us the image.
Swati Jain
Swati Jain el 31 de Jul. de 2017
Sorry, Please find the attached Image.

Iniciar sesión para comentar.

Image Analyst
Image Analyst el 30 de Jul. de 2017

0 votos

When you say this: abs(bw(i:j)- bw(i:j+1)), then the first vector is (j-i+1) elements long. The second vector, since you're going one element further along the array is (j+1-i+1) = (j-i+2). The second vector is one element longer so you cannot subtract them element-by-element. Not sure what you're going due to the disappointing lack of comments.
If you know the endpoints of the line, you can get the deltay and deltax and use atan2d() and imrotate() to straighten the edge (align it perfectly vertical or horizontal).

Preguntada:

el 30 de Jul. de 2017

Comentada:

el 31 de Jul. de 2017

Community Treasure Hunt

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

Start Hunting!

Translated by