简体   繁体   中英

Searching Across a Line in a Matrix in Octave

The attached image has a line with a break in it.

图片

My code finds the line using a hough transform resulting in r=32 and theta=2.3213 . The hough transform isn't perfect, the angle (especially with a more complex image) is always off by a little bit, and in this case, because of the edge detection, the line is offset. I want to read values across the line to find the breaks in it. In order to do this, I will need to be able to sample values on either side of the line to find where the maximum density of the line is.

Further explanation (if you want it): If you look closely at the image you can see areas where the line crosses a pixel pretty much dead on resulting in a value of nearly 1/white. Other areas have two pixels side by side with values of about .5/gray. I need to find a solution that takes into account the anti-aliasing of the line, and allows me to extract the breaks in it.

%Program Preparation
clear ; close all; clc  %clearing command window
pkg load image %loading image analyzation suite
pkg load optim  

%Import Image
I_original = imread("C:/Users/3015799/Desktop/I.jpg");

%Process Image to make analysis quicker and more effective
I = mat2gray(I_original);   %convert to black and white
I = edge(I, 'sobel');

%Perform Hough Transform
angles = pi*[-10:189]/180;
hough = houghtf(I,"line",angles);

%Detect hot spots in hough transform
detect = hough>.5*max(hough(:));

%Shrink hotspots to geometric center, and index
detect = bwmorph(detect,'shrink',inf);
[ii, jj] = find(detect);
r = ii - (size(hough,1)-1)/2;
theta = angles(jj);

%Cull duplicates. i.e outside of 0-180 degrees
dup = theta<-1e-6 | theta>=pi-1e-6;
r(dup) = [];
theta(dup) = [];

%Compute line parameters (using Octave's implicit singleton expansion)
r = r(:)'
theta = theta(:)'
x = repmat([1;1133],1,length(r)); % 2xN matrix, N==length(r)
y = (r - x.*cos(theta))./sin(theta); % solve line equation for y

%The above goes wrong when theta==0, fix that:
horizontal = theta < 1e-6;
x(:,horizontal) = r(horizontal);
y(:,horizontal) = [1;:];

%Plot
figure
imshow(I)
hold on
plot(y,x,'r-','linewidth',2)

If you are only interested in the length of the gap, this would be very easy:

clear all
pkg load image

img_fn = "input.jpg";

if (! exist (img_fn, "file"))
  urlwrite ("https://i.stack.imgur.com/5UnpO.jpg", img_fn);
endif

Io = imread(img_fn);
I = im2bw (Io);

r = max(I);
c = max(I');

ri = find (diff(r));
ci = find (diff(c));

## both should have 4 elements (one break)
assert (numel (ri) == 4);
assert (numel (ci) == 4);

## the gap is in the middle
dx = diff(ri(2:3))
dy = diff(ci(2:3))

# the length is now easy
l = hypot (dy, dx)

gives

dx =  5
dy =  5
l =  7.0711

without any hogh transform. Of course you have to also check the corener cases for horizontal and vertical lines but this should give you an idea

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM