1.hough变换检测线
设计思路
使用Hough变换检测直线的目的是在图像中找到直线的位置和方向。首先,将原始图像转换为灰度图像,并进行边缘检测以提取直线的信息。然后,利用Hough变换在参数空间中累积直线的信息,通过寻找峰值点来确定直线的位置和方向。最后,在原始图像和Hough变换空间中绘制检测到的直线和峰值点。
实现方法
首先,使用imread函数读取原始图像,并将其转换为灰度图像。然后,利用边缘检测算法(这里使用的是Canny边缘检测)对灰度图像进行处理,得到二值化的边缘图像。接下来,利用Hough变换函数hough()计算二值化边缘图像中直线的参数空间。使用houghpeaks()函数找到参数空间中的峰值点。然后,利用houghlines()函数在原始图像上绘制检测到的直线。最后,将Hough变换空间进行可视化,标记出峰值点。
Matlab代码
% 1. 读取图像并进行预处理
originalImage = imread('daolu.jpg');
grayImage = rgb2gray(originalImage);
binaryImage = edge(grayImage, 'canny');
% 2. 使用Hough变换检测直线
[H, theta, rho] = hough(binaryImage);
peaks = houghpeaks(H, 2); % 设置峰值点数量
% 3. 在原始图像上绘制检测出的线
figure;
imshow(originalImage);
hold on;
lines = houghlines(binaryImage, theta, rho, peaks);
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1), xy(:,2), 'LineWidth', 2, 'Color', 'r');
end
hold off;
% 4. 在Hough变换空间中标记峰值点
figure;
imshow(imadjust(rescale(H)), 'XData', theta, 'YData', rho, 'InitialMagnification', 'fit');
xlabel('\theta (degrees)');
ylabel('\rho');
axis on;
axis normal;
hold on;
plot(theta(peaks(:,2)), rho(peaks(:,1)), 's', 'color', 'white');
hold off;
效果
2.hough变换检测圆
设计思路
利用Hough变换检测圆的目的是在图像中找到圆的位置和半径。首先,将原始图像转换为灰度图像,并进行边缘检测以提取圆的信息。然后,利用Hough变换在参数空间中累积圆的信息,通过寻找峰值点来确定圆的位置和半径。最后,在原始图像上绘制检测到的圆。
实现方法
首先,使用imread函数读取原始图像,并将其转换为灰度图像。然后,利用边缘检测算法(这里使用的是Canny边缘检测)对灰度图像进行处理,得到二值化的边缘图像。接下来,利用imfindcircles函数在二值化边缘图像中检测圆,设定圆的半径范围。然后,将检测到的圆在原始图像上进行可视化,使用viscircles函数绘制圆。
Matlab代码
% 1. 读取图像并进行预处理
originalImage = imread('qiu.jpg');
grayImage = rgb2gray(originalImage);
binaryImage = edge(grayImage, 'canny');
% 2. 使用Hough变换检测圆
[centers, radii, metric] = imfindcircles(binaryImage, [25 100]); % 设定半径范围
% 3. 在原始图像上绘制检测出的圆
figure;
imshow(originalImage);
hold on;
viscircles(centers, radii, 'EdgeColor', 'b');
hold off;
效果
3.区域分割(最优阈值分割)
设计思路
区域分割的目的是根据图像的灰度特性将其分为不同的区域或对象。采用最优阈值分割方法,通过计算图像的灰度直方图和累积分布函数,寻找使类间方差最大的阈值,将图像分割成两个区域,其中一个区域包含目标对象,另一个区域为背景。最后,使用找到的最优阈值对图像进行分割。
实现方法
首先,将原始图像转换为灰度图像,并计算其灰度直方图和累积分布函数。然后,通过遍历所有可能的阈值,计算每个阈值对应的类间方差,并找到使类间方差最大的阈值作为最优阈值。接下来,使用最优阈值将灰度图像分割成两个区域,其中大于阈值的像素点属于目标对象,小于阈值的像素点属于背景。最后,可视化原始图像、分割图像和直方图,并在直方图中标记出最优阈值对应的分界线。
Matlab代码
% 读取图像
image = imread('yingbi.jpg');
% 将图像转换为灰度图像
gray_image = rgb2gray(image);
% 计算灰度直方图
histogram = imhist(gray_image);
% 计算累积分布函数
cdf = cumsum(histogram) / numel(gray_image);
% 初始化变量
num_bins = 256;
optimal_threshold = 0;
max_variance = 0;
% 寻找最优阈值
for t = 1:num_bins
% 计算类间方差
class1_prob = cdf(t);
class2_prob = 1 - class1_prob;
class1_mean = sum((0:t-1)'.*histogram(1:t)) / sum(histogram(1:t));
class2_mean = sum((t:num_bins-1)'.*histogram(t+1:end)) / sum(histogram(t+1:end));
between_class_variance = class1_prob * class2_prob * (class1_mean - class2_mean)^2;
% 更新最大方差和最优阈值
if between_class_variance > max_variance
max_variance = between_class_variance;
optimal_threshold = t - 1;
end
end
% 使用最优阈值进行分割
segmented_image = gray_image > optimal_threshold;
% 显示原始图像、分割图像和直方图
figure;
subplot(2, 2, 1);
imshow(gray_image);
title('Original Image');
subplot(2, 2, 2);
imshow(segmented_image);
title('Segmented Image');
subplot(2, 2, 3);
bar(histogram);
title('Histogram');
% 在直方图空间展示分界线
hold on;
line([optimal_threshold, optimal_threshold], [0, max(histogram)], 'Color', 'r', 'LineWidth', 2);
hold off;
效果
4.区域分割(分块)
设计思路
采用分块的方法进行区域分割,目的是将图像分成多个均匀的子块,然后对每个子块独立进行阈值分割。首先,将图像划分成固定大小的块,并计算每个块的灰度直方图和累积分布函数。然后,在每个块中寻找使类间方差最大的阈值,作为该块的最优阈值。最后,根据每个块的最优阈值将相应的像素分割成目标对象和背景,从而完成整个图像的区域分割。
实现方法
首先,将原始图像转换为灰度图像,并定义分块大小。然后,将图像分成块,并在每个块中计算灰度直方图和累积分布函数。接下来,在每个块中寻找使类间方差最大的阈值,并存储在阈值矩阵中。最后,根据每个块的最优阈值对图像进行分割,并将分割结果拼接成整个图像的分割图像。可视化原始图像、分割图像和直方图,并在直方图中展示每个块的阈值分界线。
Matlab代码
% 读取图像
image = imread('yingbi.jpg');
% 将图像转换为灰度图像
gray_image = rgb2gray(image);
% 定义分块大小
block_size = 64;
% 获取图像大小
[rows, cols] = size(gray_image);
% 初始化变量
num_rows = floor(rows / block_size);
num_cols = floor(cols / block_size);
thresholds = zeros(num_rows, num_cols);
% 对每个分块进行分割
for i = 1:block_size:rows
for j = 1:block_size:cols
% 获取当前分块
block = gray_image(i:min(i+block_size-1, rows), j:min(j+block_size-1, cols));
% 计算当前分块的灰度直方图
histogram = imhist(block);
% 计算累积分布函数
cdf = cumsum(histogram) / numel(block);
% 寻找最优阈值
optimal_threshold = 0;
max_variance = 0;
for t = 1:num_bins
% 计算类间方差
class1_prob = cdf(t);
class2_prob = 1 - class1_prob;
class1_mean = sum((0:t-1)'.*histogram(1:t)) / sum(histogram(1:t));
class2_mean = sum((t:num_bins-1)'.*histogram(t+1:end)) / sum(histogram(t+1:end));
between_class_variance = class1_prob * class2_prob * (class1_mean - class2_mean)^2;
% 更新最大方差和最优阈值
if between_class_variance > max_variance
max_variance = between_class_variance;
optimal_threshold = t - 1;
end
end
% 存储最优阈值
thresholds((i-1)/block_size+1, (j-1)/block_size+1) = optimal_threshold;
end
end
% 生成分割图像
segmented_image = zeros(rows, cols);
for i = 1:block_size:rows
for j = 1:block_size:cols
threshold = thresholds((i-1)/block_size+1, (j-1)/block_size+1);
segmented_image(i:min(i+block_size-1, rows), j:min(j+block_size-1, cols)) = gray_image(i:min(i+block_size-1, rows), j:min(j+block_size-1, cols)) > threshold;
end
end
% 显示原始图像、分割图像和直方图
figure;
subplot(2, 2, 1);
imshow(gray_image);
title('Original Image');
subplot(2, 2, 2);
imshow(segmented_image);
title('Segmented Image');
subplot(2, 2, 3);
bar(imhist(gray_image));
title('Histogram');
% 在直方图空间展示分界线
hold on;
for i = 1:block_size:rows
for j = 1:block_size:cols
threshold = thresholds((i-1)/block_size+1, (j-1)/block_size+1);
line([threshold, threshold], [0, max(imhist(gray_image))], 'Color', 'r', 'LineWidth', 0.5);
end
end
hold off;