canny的matlab代码
时间: 2023-05-25 18:04:23 浏览: 84
以下是Canny边缘检测的MATLAB代码实现:
clc;
clear all;
close all;
% 加载图像
img = imread('lena.png');
% 显示原始图像
subplot(2,2,1);
imshow(img);
title('Original Image');
% 灰度化
grayImg = rgb2gray(img);
% 边缘检测
edgeImg = edge(grayImg,'Canny');
% 显示Canny边缘检测的结果
subplot(2,2,2);
imshow(edgeImg);
title('Canny Edge Detection');
% 调整高斯滤波器的标准差
sigma = 2;
filterSize = 4 * sigma + 1;
% 高斯滤波
grayImg = double(grayImg);
gaussFilter = fspecial('gaussian', filterSize, sigma);
filteredImg = imfilter(grayImg, gaussFilter, 'same', 'replicate');
% 计算梯度幅值和方向
dxFilter = [-1 0 1; -2 0 2; -1 0 1];
dyFilter = [-1 -2 -1; 0 0 0; 1 2 1];
dxImg = imfilter(filteredImg, dxFilter, 'same', 'replicate');
dyImg = imfilter(filteredImg, dyFilter, 'same', 'replicate');
gradMagImg = sqrt(dxImg.^2 + dyImg.^2);
gradDirImg = atan2d(dyImg, dxImg);
% 非最大抑制
nmsImg = nonMaxSup(gradMagImg, gradDirImg);
% 双阈值处理
highThres = max(max(nmsImg)) * 0.4;
lowThres = highThres * 0.3;
edgeImg2 = threshold(nmsImg, highThres, lowThres);
% 显示自己实现的Canny边缘检测的结果
subplot(2,2,3);
imshow(edgeImg2);
title('My Own Canny Edge Detection');
% 自己实现的非最大抑制
function result = nonMaxSup(gradMagImg, gradDirImg)
[height, width] = size(gradMagImg);
result = gradMagImg;
for i = 2 : height-1
for j = 2:width-1
% 计算当前像素点的方向
angle = gradDirImg(i,j);
% 将方向归为0°到180°之间
if angle < 0
angle = angle + 180;
end
% 计算当前像素点的周围4个像素点的梯度幅值
if (0 <= angle && angle < 22.5) || (157.5 <= angle && angle <= 180)
x1 = gradMagImg(i, j+1);
x2 = gradMagImg(i, j-1);
elseif (22.5 <= angle && angle < 67.5)
x1 = gradMagImg(i+1, j-1);
x2 = gradMagImg(i-1, j+1);
elseif (67.5 <= angle && angle < 112.5)
x1 = gradMagImg(i+1, j);
x2 = gradMagImg(i-1, j);
else
x1 = gradMagImg(i-1, j-1);
x2 = gradMagImg(i+1, j+1);
end
% 判断当前像素点是否是当前方向上的局部最大值
if gradMagImg(i,j) < x1 || gradMagImg(i,j) < x2
result(i,j) = 0;
end
end
end
end
% 自己实现的双阈值处理
function result = threshold(img, highThres, lowThres)
[height, width] = size(img);
result = zeros(height, width);
% 先将像素点划分为三类:强边缘、弱边缘和非边缘
strongEdge = img > highThres;
weakEdge = img > lowThres & img < highThres;
nonEdge = img < lowThres;
% 对强边缘周围8个像素点进行扩展
strongDilated = imdilate(strongEdge, [1 1 1; 1 1 1; 1 1 1]);
% 扩展后的强边缘和弱边缘重合部分为真实的边缘
result(strongDilated & weakEdge) = 1;
% 对强边缘进行标记
strongLabeled = bwlabel(strongEdge);
numStrongLabeled = max(max(strongLabeled));
for i = 1 : numStrongLabeled
strongMap = (strongLabeled == i);
% 扩展标记的强边缘像素点
result = result | imdilate(strongMap, [1 1 1; 1 1 1; 1 1 1]);
end
% 将非边缘像素点标记为0
result(nonEdge) = 0;
% 对结果进行二值化
result = logical(result);
end
阅读全文