提取线形对象

Extract line shaped objects

我正在处理具有重叠线条形状的图像(左图)。最终我想分割单个对象。我正在使用霍夫变换来实现这一点,它在寻找(显着)不同方向的线条方面效果很好——例如由下方 hough space 中的两个最大值表示(中间图)。

由于不知道一个连通区域可能包含多少条线对象,我的想法是迭代提取激活最高的霍夫线对应的对象(这里画成蓝色),即去掉线图像中的形状对象,以便下一次迭代将仅找到另一条线。

但是我如何检测,哪些像素属于线形物体?

函数 hough_bin_pixels(img, theta, rho, P)(来自 here - 显示在 右图 中)给出对应于特定行的像素。但这显然太细了,无法代表物体。

有没有办法 segment/detect 整个对象沿着最强的 houghline 定向?

关键是要知道原始图像中的粗线会转化为霍夫变换上更宽的峰。此图显示了细线和粗线的峰。

您可以使用任何您喜欢的策略将每个峰的所有 pixels/accumulator 个 bin 组合在一起。我建议使用 multithresh and imquantize to convert it to a BW image, and then bwlabel 来标记连接的组件。您还可以使用任意数量的其他 clustering/segmentation 策略。唯一可能棘手的部分是确定适当的阈值水平。如果您无法获得适合您的应用程序的任何内容,则宁愿包含太多,因为您以后总能摆脱错误的像素。

这是阈值化(左)和标记(右)后霍夫变换的峰值

获得峰值区域后,您可以使用 hough_bin_pixels 找出原始图像中的哪些像素对每个累加器仓有贡献。然后,对于每个峰值区域,将 hough_bin_pixels 的结果与属于该区域的每个分箱合并。

这是我拼凑起来创建示例图像的代码。有段时间没用matlab了,最近刚入坑,代码乱七八糟的请大家见谅

% Create an image
image = zeros(100,100);

for i = 10:90
    image(100-i,i)=1;
end;

image(10:90, 30:35) = 1;

figure, imshow(image); % Fig. 1 -- Original Image

% Hough Transform
[H, theta_vals, rho_vals] = hough(image);
figure, imshow(mat2gray(H)); % Fig. 2 -- Hough Transform

% Thresholding
thresh = multithresh(H,4);
q_image = imquantize(H, thresh);
q_image(q_image < 4) = 0;
q_image(q_image > 0) = 1;
figure, imshow(q_image) % Fig. 3 -- Thresholded Peaks

% Label connected components
L = bwlabel(q_image);
figure, imshow(label2rgb(L, prism)) % Fig. 4 -- Labeled peaks

% Reconstruct the lines
[r, c] = find(L(:,:)==1);
segmented_im = hough_bin_pixels(image, theta_vals, rho_vals, [r(1) c(1)]);
for i = 1:size(r(:))
    seg_part = hough_bin_pixels(image, theta_vals, rho_vals, [r(i) c(i)]);
    segmented_im(seg_part==1) = 1;
end
region1 = segmented_im;

[r, c] = find(L(:,:)==2);
segmented_im = hough_bin_pixels(image, theta_vals, rho_vals, [r(1) c(1)]);
for i = 1:size(r(:))
    seg_part = hough_bin_pixels(image, theta_vals, rho_vals, [r(i) c(i)]);
    segmented_im(seg_part==1) = 1;
end
region2 = segmented_im;

figure, imshow([region1 ones(100, 1) region2]) % Fig. 5 -- Segmented lines

% Overlay and display
out = cat(3, image, region1, region2);
figure, imshow(out); % Fig. 6 -- For fun, both regions overlaid on original image