霍夫变换等价于倍频程

Hough Transform Equivalent in Octave

我在下面的 MATLAB 中附上了 霍夫变换 的代码:

%Hough Transform to find lines

%Load an Image and Convert to Grayscale to apply canny Filter
im = imread('lines.jpg');
im_gray = rgb2gray(im);
im_edge = edge(im_gray, 'canny');

figure, imshow(im), title('Original Image');
figure, imshow(im_gray), title('Grayscale Image');
figure, imshow(im_edge), title('Canny Filter Edge');

%Apply Hough Transform to Find the Candidate Lines
[accum theta rho] = hough(im_edge);
figure, imagesc(accum, 'xData', theta, 'ydata', rho), title('Hough Accumulator');

peaks = houghpeaks(accum, 100, 'Threshold', ceil(0.6 * max(accum(:))),'NHoodSize', [5,5]);
size(peaks);

%Finding the line segments in the image
line_segs = houghlines(edges, theta, rows, peaks, 'FillGap', 50,'MinLength', 100);

%Plotting
figure, imshow(im), title('Line Segments');
hold on;
for k=1:length(line_segs)
  endpoints = [line_segs(k).point1; line_segs(k).point2];
  plot(endpoints(:,1), endpoints(:,2), 'LineWidth', 2, 'Color','green');
end
hold off;

当我尝试通过更改 'hough into houghtf''houghlines to hough_line' 在 OCTAVE 中实现相同功能时和 'houghpeaks into immaximas' 如下:

%Hough Transform to find lines
pkg load image;

%Load an Image and Convert to Grayscale to apply canny Filter
im = imread('lines.jpg');
im_gray = rgb2gray(im);
im_edge = edge(im_gray, 'canny');

figure, imshow(im), title('Original Image');
figure, imshow(im_gray), title('Grayscale Image');
figure, imshow(im_edge), title('Canny Filter Edge');

%Apply Hough Transform to Find the Candidate Lines
[accum theta rho] = houghtf(im_edge); %In Octave and 'hough' in MATLAB
figure, imagesc(accum, 'xData', theta, 'ydata', rho), title('Hough Accumulator');

peaks = immaximas(accum, 100, 'Threshold', ceil(0.6 * max(accum(:))),'NHoodSize', [5,5]);
size(peaks);

%Finding the line segments in the image
line_segs = hough_line(edges, theta, rows, peaks, 'FillGap', 50, 'MinLength', 100);

%Plotting
figure, imshow(im), title('Line Segments');
hold on;
for k=1:length(line_segs)
 endpoints = [line_segs(k).point1; line_segs(k).point2];
 plot(endpoints(:,1), endpoints(:,2), 'LineWidth', 2, 'Color', 'green');
end
hold off;

执行时出现以下错误:

error: element number 3 undefined in return list
error: called from
HoughTransformLines at line 14 column 18

我收到错误消息,指出 'rho' 未定义。 我对 MATLAB 和 Octave 完全陌生。谁能帮我在 Octave 中实现霍夫变换?

Octave 告诉您 rho 未定义的原因是因为 Matlab 的 hough function and Octave's houghtf 函数不是完全等价的。

这是相应 Mathwork 网页上 hough 返回的输出参数的描述:

The function returns rho, the distance from the origin to the line along a vector perpendicular to the line, and theta, the angle in degrees between the x-axis and this vector. The function also returns the Standard Hough Transform, H, which is a parameter space matrix whose rows and columns correspond to rho and theta values respectively.

Octave的houghtf,另一方面,只有returns矩阵H:

The result H is an N by M matrix containing the Hough transform. Here, N is the number different values of r that has been attempted. This is computed as 2*diag_length - 1, where diag_length is the length of the diagonal of the input image. M is the number of different values of theta. These can be set through the third input argument arg. This must be a vector of real numbers, and is by default pi*(-90:90)/180.

现在,在您的脚本中,您调用 rho 的唯一地方是第 15 行,当试图显示 Hough 累加器时。 我建议您改为这样绘制累加器:

figure, imagesc(H),xlabel('xData'),ylabel('ydata'),title('Hough accumulator')

让我知道这是否适合您!

[H] = houghtf(edges);

您必须以这种方式传递参数,因为八度 returns 只是一个值矩阵。您不能将三个不同的变量分配给一个矩阵。
所以,给它分配一个变量,你就会得到结果。

我建议对原始代码进行以下更新:

%Hough Transform to find lines
pkg load image;

%Load an Image and Convert to Grayscale to apply canny Filter
im = imread('lines.jpg');
im_gray = rgb2gray(im);
im_edge = edge(im_gray, 'canny');

figure 1, imshow(im),      title('Original Image');
figure 2, imshow(im_gray), title('Grayscale Image');
figure 3, imshow(im_edge), title('Canny Filter Edge');

%Apply Hough Transform to Find the Candidate Lines
accum       = houghtf(im_edge);
theta       = -90:90;
diag_length = (size(accum)(1) - 1) / 2;
rho         = -diag_length:diag_length;
figure 4, imagesc(theta, rho, accum), title('Hough Accumulator');

peaks = houghpeaks(accum, 100, 'Threshold', ceil(0.6 * max(accum(:))), 'NHoodSize', [5,5]);

%Finding the line segments in the image
line_segs = houghlines(im_edge, theta, rho, peaks, 'FillGap', 50, 'MinLength', 100);

%Plotting
figure 5, imshow(im), title('Line Segments');
hold on;
for k=1:length(line_segs)
    endpoints = [line_segs(k).point1; line_segs(k).point2];
    plot(endpoints(:,1), endpoints(:,2), 'LineWidth', 2, 'Color', 'green');
end
hold off;

让我们浏览所有更新并查看它们:

%Hough Transform to find lines
pkg load image;

%Load an Image and Convert to Grayscale to apply canny Filter
im = imread('lines.jpg');
im_gray = rgb2gray(im);
im_edge = edge(im_gray, 'canny');

figure 1, imshow(im),      title('Original Image');
figure 2, imshow(im_gray), title('Grayscale Image');
figure 3, imshow(im_edge), title('Canny Filter Edge');

只有很小的变化 - 添加了数字索引以将它们划分为一致的单独 windows(参见 Multiple Plot Windows)。

之后我们应用霍夫变换并恢复 Octave 中的 "lost" thetarho 值:

%Apply Hough Transform to Find the Candidate Lines
accum       = houghtf(im_edge);
theta       = -90:90;
diag_length = (size(accum)(1) - 1) / 2;
rho         = -diag_length:diag_length;
figure 4, imagesc(theta, rho, accum), title('Hough Accumulator');

根据 houghtf function's docs, it returns only an accumulator with rows corresponding to indices of rho values, and columns - to indices of theta values. How can we restore the original rho and theta values? Well, the number of rho values (rows in the accum matrix variable) goes up to 2*diag_length - 1, where diag_length is the length of the diagonal of the input image. Knowing this, we should restore the diagonal length (it is a reversed action): diag_length = (size(accum)(1) - 1) / 2. Then we can restore rho values, which go from minus diagonal to diagonal: rho = -diag_length:diag_length. With thetas everything is easier - they are in the range of pi*(-90:90)/180, but we will use degrees instead: theta = -90:90. I've added the index for figure as did before and changed the call to imagesc according to its docs - 它应该被称为 imagesc (x, y, img)

之后我们使用houghpeaks函数得到峰值:

peaks = houghpeaks(accum, 100, 'Threshold', ceil(0.6 * max(accum(:))), 'NHoodSize', [5,5]);

然后我们使用 houghlines 来获取结果线段(猜测有一些带有变量名称的勘误表):

line_segs = houghlines(im_edge, theta, rho, peaks, 'FillGap', 50, 'MinLength', 100);

最后是绘制代码 - 它根本没有改变,因为它工作正常。