![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/177615/image.png)
Calculation of pixel shift
3 views (last 30 days)
Show older comments
Swati Jain
on 30 Jul 2017
Commented: Walter Roberson
on 31 Jul 2017
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
0 Comments
Accepted Answer
Image Analyst
on 31 Jul 2017
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');
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/177615/image.png)
2 Comments
Walter Roberson
on 31 Jul 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.
More Answers (2)
Walter Roberson
on 30 Jul 2017
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 Comments
Image Analyst
on 31 Jul 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.
Image Analyst
on 30 Jul 2017
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).
0 Comments
See Also
Categories
Find more on Red in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!