我能够使用以下代码在 Matlab 中重新创建 hough() 和 houghpeaks() 函数,但我目前正在努力将它们从参数空间解构到图像空间。
%%% hough() function
corridor = imread('Corridor1.jpg');
grayCorridor = rgb2gray(corridor);
Canny_img = edge(grayCorridor, 'Canny');
[rows, cols] = size(Canny_img);
theta_maximum = 90;
rho_maximum = hypot(rows,cols) - 1;
theta_range = -theta_maximum:theta_maximum-1;
rho_range = -rho_maximum:rho_maximum;
Hough = zeros(length(rho_range), length(theta_range));
for j = 1:rows
for i = 1:cols
if Canny_img(j, i) ==1
x = i - 1;
y = j - 1;
for T = theta_range
R = round((x * cosd(T)) + (y * sind(T)));
R_Index = R + rho_maximum + 1;
T_Index = T + theta_maximum + 1;
Hough(R_Index, T_Index) = Hough(R_Index, T_Index) + 1;
end
end
end
end
%%% houghpeaks() function
[X,Y] = find(Hough>0.47*max(Hough(:)))
%Visualising them
imshow(Hough,[],'XData',theta_range,'YData',rho_range,...
'InitialMagnification','fit');
xlabel('\theta'), ylabel('\rho');
axis on, axis normal, hold on;
pointsRho = rho_range(X(:));
pointsTheta = theta_range(Y(:));
plot(pointsTheta,pointsRho,'s','color','red');
这是我尝试将它们分解为图像空间。我首先将 Rho 和 Theta 对放入列表中。然后我创建了一组大小为 imageRow x imageColumn x rhotheta 对数的二进制矩阵。然后我将所有的 x 和 y 像素坐标代入函数 x cos(theta) + y sin(theta) = rho,如果 left - right == 0,我将标记二进制矩阵的位置 (x,y)作为 1,我针对所有 x 和 y 值对所有 theta 对运行它,并将它们分别存储在上面提到的二进制矩阵集中。
在第二个 for 循环中,我刚刚遍历了我获得的所有二进制矩阵集,并将它们聚合成一个二进制矩阵。我的问题来了,当它们彼此靠近时,我如何将我dehoughed的线条组合成一条线?如果我能够做到这一点,我可以通过降低我用 [X,Y] = find(Hough>0.47*max(Hough(:))) 设置的阈值来可视化更多的峰峰。因为现在如果我将阈值降低 0.01,我会有更多彼此如此接近的线条。你也许有更优雅和更好的脱壳方法?
for k = 1:length(pointsRho)
for i = 1:1280 % Shoulda put 1:size(Canny_img,1) but putting number helps me visualise my logic
% better while I am coding
for j = 1:960
r = pointsRho(k);
t = pointsTheta(k);
threshold = abs(i*cosd(t)+j*sind(t)-r);
if threshold ==0
allLines(j,i,k) = 1;
end
end
end
end
aggregatedImage = zeros(size(Canny_img));
for k = 1:length(pointsRho)
for j = 1:1280
for i = 1:960
if allLines(i,j,k) ==1
aggregatedImage(i,j) = 1;
end
end
end
end
figure,imshow(imfuse(aggregatedImage,corridor))
P/S:我认为如果我要立即在一个二进制文件中标记所有满足 x cos(theta) + y cos(theta) = r的像素坐标,我可以将两个循环变成一个 for 循环矩阵(如下代码所示)。但是,我不确定为什么当我这样做时,aggregatedImage 只是全为 0。因此我决定采用上述方法。
aggregatedImage = zeros(size(Canny_img));
for k = 1:length(pointsRho)
for i = 1:1280
for j = 1:960
r = pointsRho(k);
t = pointsTheta(k);
threshold = abs(i*cosd(t)+j*sind(t)-r);
if threshold ==0
aggregatedImage(j,i) = 1;
end
end
end
end