MATLAB 亚像素边缘检测代码优化:解决显示小白点问题
MATLAB 亚像素边缘检测代码优化:解决显示小白点问题
在使用MATLAB进行亚像素边缘检测时,可能会遇到显示图像是一个小白点的问题。这通常是因为在计算亚像素边缘位置时,没有对亚像素边缘位置进行取整处理。
问题描述:
以下代码展示了常见的亚像素边缘检测方法,但运行后可能只显示一个小白点:
% 读取图像
image = imread('lena.jpg');
image = rgb2gray(image);
% 使用Canny边缘检测算法获取二值化图像
bw_image = edge(image, 'canny');
% 计算图像的Zernike矩
order = 10; % Zernike矩的阶数
moments = zernike_moments(bw_image, order);
% 亚像素边缘检测
subpixel_image = subpixel_edge_detection(image, moments);
% 显示结果
figure;
subplot(1, 2, 1);
imshow(bw_image);
title('Binary Edge Image');
subplot(1, 2, 2);
imshow(subpixel_image);
title('Subpixel Edge Detection');
function moments = zernike_moments(image, order)
[rows, cols] = size(image);
moments = zeros(order+1, order+1);
% 计算图像的归一化矩
for p = 0:order
for q = 0:order
if mod(p+q, 2) == 0
for x = 1:rows
for y = 1:cols
if image(x, y) > 0
rho = sqrt((2*x-rows-1)^2 + (2*y-cols-1)^2) / sqrt(rows^2 + cols^2);
theta = atan2((2*y-cols-1), (2*x-rows-1));
moments(p+1, q+1) = moments(p+1, q+1) + image(x, y) * zernike_polynomial(p, q, rho, theta);
end
end
end
moments(p+1, q+1) = moments(p+1, q+1) * ((p+1)/(pi*(rows*cols)));
end
end
end
end
function value = zernike_polynomial(p, q, rho, theta)
value = 0;
for s = 0:(p-q)/2
value = value + (-1)^s * factorial(p-s) / (factorial(s) * factorial((p+q)/2-s) * factorial((p-q)/2-s)) * rho^(p-2*s);
end
value = value * sqrt((p+1)/pi) * cos(q*theta);
end
function subpixel_image = subpixel_edge_detection(image, moments)
[rows, cols] = size(image);
subpixel_image = zeros(rows, cols);
for x = 1:rows
for y = 1:cols
if image(x, y) > 0
rho = sqrt((2*x-rows-1)^2 + (2*y-cols-1)^2) / sqrt(rows^2 + cols^2);
theta = atan2((2*y-cols-1), (2*x-rows-1));
% 使用moments参数计算亚像素边缘位置
subpixel_x = (rows+1)/2 + rho * cos(theta) + moments(1, 1);
subpixel_y = (cols+1)/2 + rho * sin(theta) + moments(1, 2);
% 判断亚像素边缘位置是否在图像范围内
if subpixel_x >= 1 && subpixel_x <= rows && subpixel_y >= 1 && subpixel_y <= cols
subpixel_image(subpixel_x, subpixel_y) = 255;
end
end
end
end
end
解决方案:
要解决这个问题,需要在计算亚像素边缘位置时使用round函数对subpixel_x和subpixel_y进行取整操作。
修改后的代码:
% 读取图像
image = imread('lena.jpg');
image = rgb2gray(image);
% 使用Canny边缘检测算法获取二值化图像
bw_image = edge(image, 'canny');
% 计算图像的Zernike矩
order = 10; % Zernike矩的阶数
moments = zernike_moments(bw_image, order);
% 亚像素边缘检测
subpixel_image = subpixel_edge_detection(image, moments);
% 显示结果
figure;
subplot(1, 2, 1);
imshow(bw_image);
title('Binary Edge Image');
subplot(1, 2, 2);
imshow(subpixel_image);
title('Subpixel Edge Detection');
function moments = zernike_moments(image, order)
[rows, cols] = size(image);
moments = zeros(order+1, order+1);
% 计算图像的归一化矩
for p = 0:order
for q = 0:order
if mod(p+q, 2) == 0
for x = 1:rows
for y = 1:cols
if image(x, y) > 0
rho = sqrt((2*x-rows-1)^2 + (2*y-cols-1)^2) / sqrt(rows^2 + cols^2);
theta = atan2((2*y-cols-1), (2*x-rows-1));
moments(p+1, q+1) = moments(p+1, q+1) + image(x, y) * zernike_polynomial(p, q, rho, theta);
end
end
end
moments(p+1, q+1) = moments(p+1, q+1) * ((p+1)/(pi*(rows*cols)));
end
end
end
end
function value = zernike_polynomial(p, q, rho, theta)
value = 0;
for s = 0:(p-q)/2
value = value + (-1)^s * factorial(p-s) / (factorial(s) * factorial((p+q)/2-s) * factorial((p-q)/2-s)) * rho^(p-2*s);
end
value = value * sqrt((p+1)/pi) * cos(q*theta);
end
function subpixel_image = subpixel_edge_detection(image, moments)
[rows, cols] = size(image);
subpixel_image = zeros(rows, cols);
for x = 1:rows
for y = 1:cols
if image(x, y) > 0
rho = sqrt((2*x-rows-1)^2 + (2*y-cols-1)^2) / sqrt(rows^2 + cols^2);
theta = atan2((2*y-cols-1), (2*x-rows-1));
% 使用moments参数计算亚像素边缘位置
subpixel_x = (rows+1)/2 + rho * cos(theta) + moments(1, 1);
subpixel_y = (cols+1)/2 + rho * sin(theta) + moments(1, 2);
% 判断亚像素边缘位置是否在图像范围内
if subpixel_x >= 1 && subpixel_x <= rows && subpixel_y >= 1 && subpixel_y <= cols
subpixel_image(round(subpixel_x), round(subpixel_y)) = 255;
end
end
end
end
end
通过对亚像素边缘位置进行取整处理,可以有效改善边缘图像显示效果,解决显示小白点的问题。
总结:
本文介绍了在MATLAB亚像素边缘检测中解决显示小白点问题的方案,通过对亚像素边缘位置进行取整操作,可以有效改善边缘图像显示效果。
原文地址: https://www.cveoy.top/t/topic/fv9m 著作权归作者所有。请勿转载和采集!