轮廓检测详解
目录
目标
掌握轮廓检测和分析的基本方法,包括轮廓检测的基本步骤、轮廓的属性计算以及轮廓的绘制与分析。
知识点
1. 轮廓检测概述
• 定义 :轮廓检测是图像处理中的一个关键步骤,用于识别图像中的物体边界。
• 应用 :广泛应用于目标识别、图像分析、形状分类等领域。
2. 轮廓检测的基本步骤
1. 图像预处理 :
• 转换为灰度图像 :使用 rgb2gray 函数将彩色图像转换为灰度图像。
• 去除噪声 :使用高斯滤波器去除图像中的噪声,如 imgaussfilt 函数。
• 边缘检测 :使用边缘检测算法(如Canny)检测图像中的边缘,生成边缘图像。
2. 轮廓提取 :
• 使用 imcontour 函数检测图像中的轮廓,返回轮廓的坐标信息
3. 轮廓分析 :
• 计算轮廓属性 :使用 regionprops 函数计算轮廓的面积、周长、偏心率等属性。
• 绘制轮廓 :使用 plot 函数在图像上绘制轮廓。
3. 轮廓的属性
• 面积(Area) :轮廓包围的区域大小。
• 周长(Perimeter) :轮廓的长度。
• 偏心率(Eccentricity) :描述轮廓的形状,范围在0到1之间,0表示完全圆形,1表示完全拉长的椭圆。
4. 轮廓的绘制与分析
• 绘制轮廓 :在图像上绘制轮廓,便于直观观察。
• 分析轮廓属性 :根据轮廓的属性进行分类或识别。
示例代码
- 读取图像并进行预处理
matlab
% 读取图像
img = imread('peppers.png');
% 转换为灰度图像
grayImg = rgb2gray(img);
% 去除噪声(高斯滤波)
filteredImg = imgaussfilt(grayImg, 1); % 标准差为1
% 应用Canny边缘检测
edgeImg = edge(filteredImg, 'Canny', [0.1, 0.2], 3); % 标准差为3,低阈值0.1,高阈值0.2
% 显示结果
figure;
subplot(1, 2, 1);
imshow(filteredImg);
title('Filtered Image');
subplot(1, 2, 2);
imshow(edgeImg);
title('Edge Detection');
代码解释 :
• rgb2gray 函数用于将彩色图像转换为灰度图像。
• imgaussfilt 函数用于应用高斯滤波,去除噪声。
• edge 函数用于进行Canny边缘检测,参数包括图像、算法名称、高低阈值和高斯滤波器尺寸。
运行结果:
- 轮廓检测与绘制
matlab
% 检测轮廓
contours = imcontour(filteredImg, 10); % 检测10个轮廓
% 绘制轮廓
figure;
imshow(filteredImg);
hold on;
plot(contours);
title('Contours');
代码解释 :
• imcontour 函数用于检测图像中的轮廓,参数包括图像和检测的轮廓数量。
• plot 函数用于在图像上绘制轮廓。
运行结果:
- 轮廓属性计算
matlab
% 计算轮廓的属性
stats = regionprops(contours, 'Area', 'Perimeter', 'Eccentricity');
% 显示属性
for i = 1:length(stats)
fprintf('Contour %d:\n', i);
fprintf('Area: %d\n', stats(i).Area);
fprintf('Perimeter: %d\n', stats(i).Perimeter);
fprintf('Eccentricity: %f\n', stats(i).Eccentricity);
end
代码解释 :
• regionprops 函数用于计算轮廓的属性,参数包括轮廓和需要计算的属性。
• fprintf 函数用于显示每个轮廓的属性。
运行结果:
示例二:
% 读取图像
img = imread('coins.png'); % 使用MATLAB内置的coins.png图像
% 转换为灰度图像
grayImg = rgb2gray(img);
% 应用阈值分割生成二值图像
binaryImg = imbinarize(grayImg);
% 提取轮廓
boundaries = bwboundaries(binaryImg);
% 显示原始图像和二值图像
figure;
subplot(1, 2, 1);
imshow(grayImg);
title('Grayscale Image');
subplot(1, 2, 2);
imshow(binaryImg);
title('Binary Image');
% 计算并显示轮廓属性
figure;
imshow(img);
hold on;
for k = 1:length(boundaries)
boundary = boundaries{k}; % 获取第k个轮廓的坐标
plot(boundary(:, 2), boundary(:, 1), 'r', 'LineWidth', 2); % 绘制轮廓
% 计算面积
area = polyarea(boundary(:, 2), boundary(:, 1));
% 计算周长
perimeter = sum(sqrt(sum(diff(boundary).^2, 2)));
% 输出属性
fprintf('轮廓 %d: 面积 = %.2f, 周长 = %.2f\n', k, area, perimeter);
end
hold off;
title('Contours with Properties');
% 使用regionprops计算更多属性
stats = regionprops(binaryImg, 'Area', 'Perimeter', 'Circularity');
disp('使用regionprops计算的属性:');
disp(stats);
代码讲解
1、图像预处理
• imread(‘coins.png’):读取图像(这里使用MATLAB内置的coins.png)。
• rgb2gray:转换为灰度图像。
• imbinarize:自动阈值分割生成二值图像。
2、轮廓提取
• bwboundaries(binaryImg):从二值图像中提取所有轮廓,返回一个单元数组,每个元素是一个轮廓的坐标矩阵。
• 坐标格式为 [行, 列],即 [y, x]。
3、轮廓绘制
• 使用 plot 在原始图像上绘制轮廓,boundary(:, 2) 是x坐标,boundary(:, 1) 是y坐标。
4、属性计算
• 面积:polyarea 计算多边形面积。
• 周长:通过计算轮廓点间距离的和来近似周长。
• regionprops:更方便地计算面积、周长和圆形度等属性。
5、显示结果
• 显示原始灰度图像、二值图像和带轮廓的图像。
• 在命令窗口输出每个轮廓的面积和周长。
运行结果:
练习
1. 轮廓检测与绘制 :
• 读取一张图像,进行预处理,检测并绘制轮廓。
matlab
% 读取图像
img = imread('peppers.png');
% 转换为灰度图像
grayImg = rgb2gray(img);
% 去除噪声(高斯滤波)
filteredImg = imgaussfilt(grayImg, 1);
% 检测轮廓
contours = imcontour(filteredImg, 10);
% 绘制轮廓
figure;
imshow(filteredImg);
hold on;
plot(contours);
title('Contours');
运行结果:
2. 轮廓属性分析 :
• 计算检测到的轮廓的面积、周长和偏心率,进行分析。
matlab
% 计算轮廓的属性
stats = regionprops(contours, 'Area', 'Perimeter', 'Eccentricity');
% 显示属性
for i = 1:length(stats)
fprintf('Contour %d:\n', i);
fprintf('Area: %d\n', stats(i).Area);
fprintf('Perimeter: %d\n', stats(i).Perimeter);
fprintf('Eccentricity: %f\n', stats(i).Eccentricity);
end
运行结果:
3. 复杂场景下的轮廓检测 :
• 处理一张包含多个物体的图像,检测并分析不同物体的轮廓。
matlab
% 读取图像
img = imread('coins.png'); % 假设有一张包含多个硬币的图像
% 转换为灰度图像
grayImg = rgb2gray(img);
% 去除噪声(高斯滤波)
filteredImg = imgaussfilt(grayImg, 1);
% 应用Canny边缘检测
edgeImg = edge(filteredImg, 'Canny', [0.1, 0.2], 3);
% 检测轮廓
contours = imcontour(filteredImg, 20); % 检测20个轮廓
% 绘制轮廓
figure;
imshow(filteredImg);
hold on;
plot(contours);
title('Contours');
% 计算轮廓的属性
stats = regionprops(contours, 'Area', 'Perimeter', 'Eccentricity');
% 显示属性
for i = 1:length(stats)
fprintf('Contour %d:\n', i);
fprintf('Area: %d\n', stats(i).Area);
fprintf('Perimeter: %d\n', stats(i).Perimeter);
fprintf('Eccentricity: %f\n', stats(i).Eccentricity);
end
运行结果:
总结
通过今天的学,我掌握了轮廓检测和分析的基本方法。轮廓检测是图像处理中的重要环节,能够帮助我提取图像中的物体