改进的canny边缘检测matlab代码
时间: 2023-10-01 18:12:33 浏览: 31
以下是改进版的Canny边缘检测的MATLAB代码:
```matlab
function [edgeImg, thresImg] = myCannyEdgeDetection(img, sigma, thresLow, thresHigh)
% img: 输入图像
% sigma: 高斯核标准差
% thresLow, thresHigh: 双阈值
% 1. 高斯滤波
G = fspecial('gaussian',[5 5],sigma);
img_smoothed = imfilter(img,G,'same');
% 2. 计算梯度幅值和方向
[dx, dy] = gradient(img_smoothed);
grad_mag = sqrt(dx.^2 + dy.^2);
grad_dir = atan2(dy, dx) * 180 / pi;
% 3. 非极大值抑制
grad_mag_pad = padarray(grad_mag,[1 1],'replicate','both');
grad_dir_pad = padarray(grad_dir,[1 1],'replicate','both');
grad_mag_suppressed = zeros(size(grad_mag));
for i = 2:size(grad_mag_pad,1)-1
for j = 2:size(grad_mag_pad,2)-1
if grad_dir_pad(i,j) < 0
grad_dir_pad(i,j) = grad_dir_pad(i,j) + 180;
end
if (grad_dir_pad(i,j) >= 0 && grad_dir_pad(i,j) < 22.5) || (grad_dir_pad(i,j) >= 157.5 && grad_dir_pad(i,j) < 180)
if grad_mag_pad(i,j) > grad_mag_pad(i-1,j) && grad_mag_pad(i,j) > grad_mag_pad(i+1,j)
grad_mag_suppressed(i-1,j-1) = grad_mag_pad(i,j);
end
elseif (grad_dir_pad(i,j) >= 22.5 && grad_dir_pad(i,j) < 67.5) || (grad_dir_pad(i,j) >= 112.5 && grad_dir_pad(i,j) < 157.5)
if grad_mag_pad(i,j) > grad_mag_pad(i-1,j-1) && grad_mag_pad(i,j) > grad_mag_pad(i+1,j+1)
grad_mag_suppressed(i-1,j-1) = grad_mag_pad(i,j);
end
elseif (grad_dir_pad(i,j) >= 67.5 && grad_dir_pad(i,j) < 112.5)
if grad_mag_pad(i,j) > grad_mag_pad(i,j-1) && grad_mag_pad(i,j) > grad_mag_pad(i,j+1)
grad_mag_suppressed(i-1,j-1) = grad_mag_pad(i,j);
end
end
end
end
% 4. 双阈值判定
thresLow = max(thresLow, 0);
thresHigh = max(thresHigh, 0);
if thresLow > thresHigh
temp = thresLow;
thresLow = thresHigh;
thresHigh = temp;
end
grad_mag_thresholded = zeros(size(grad_mag_suppressed));
for i = 1:size(grad_mag_thresholded,1)
for j = 1:size(grad_mag_thresholded,2)
if grad_mag_suppressed(i,j) > thresHigh
grad_mag_thresholded(i,j) = 1;
elseif grad_mag_suppressed(i,j) > thresLow
grad_mag_thresholded(i,j) = 0.5;
end
end
end
% 5. 联通分量分析
edgeImg = zeros(size(grad_mag_thresholded));
for i = 1:size(edgeImg,1)
for j = 1:size(edgeImg,2)
if grad_mag_thresholded(i,j) == 1 && edgeImg(i,j) == 0
edgeImg = DFS(i,j,edgeImg,grad_mag_thresholded);
end
end
end
% 6. 输出结果
edgeImg = uint8(edgeImg * 255);
thresImg = uint8(grad_mag_thresholded * 255);
end
function edgeImg = DFS(i,j,edgeImg,grad_mag_thresholded)
% DFS搜索联通分量
if i < 1 || i > size(edgeImg,1) || j < 1 || j > size(edgeImg,2) || edgeImg(i,j) == 1 || grad_mag_thresholded(i,j) < 0.5
return
end
edgeImg(i,j) = 1;
edgeImg = DFS(i-1,j,edgeImg,grad_mag_thresholded);
edgeImg = DFS(i+1,j,edgeImg,grad_mag_thresholded);
edgeImg = DFS(i,j-1,edgeImg,grad_mag_thresholded);
edgeImg = DFS(i,j+1,edgeImg,grad_mag_thresholded);
end
```
该代码与标准的Canny边缘检测流程相同,但在非极大值抑制和双阈值判定上进行了改进。非极大值抑制中,增加了对梯度方向的判断,以避免抑制非边缘处的噪声。双阈值判定中,增加了对阈值的处理,保证thresLow小于等于thresHigh。
函数返回两个结果:边缘二值图和双阈值二值图。