图像边缘检测matlab实现(LoG算子,sobel算子,prewitt算子,roberts算子,小波变换)

本文采用了LoG算子,sobel算子,prewitt算子,roberts算子,小波变换五种方法进行图像边缘检测

一、LoG算子,即Laplacian of Gaussian(高斯拉普拉斯)算子,是一种在图像处理和计算机视觉中广泛使用的边缘检测算子。它结合了高斯平滑和拉普拉斯边缘检测的特点,旨在减少噪声干扰的同时有效地提取图像边缘。LoG算子首先对图像应用高斯平滑,然后对平滑后的图像应用拉普拉斯算子。这个过程可以用下面的数学表达式描述:

LoG(x,y,\sigma)=\nabla^2G(x,y,\sigma)

特点:

噪声抑制:通过先进行高斯平滑,LoG算子减少了噪声对边缘检测的干扰。

定义LoG算子的掩膜

w=[-2 -4 -4 -4 -2;-4 0 8 0 -4;-4 8 24 8 -4;-4 0 8 0 -4;-2 -4 -4 -4 -2];

二、Sobel算子,利用图像的一阶导数来检测边缘,这些边缘通常对应于图像强度的显著变化

  1. 梯度计算

    Sobel算子通过计算图像在水平和垂直方向上的梯度来检测边缘。梯度是图像强度变化的度量,边缘通常出现在梯度幅度较大的地方。
  2. 卷积操作

    Sobel算子使用两个3x3的核(一个用于水平方向,一个用于垂直方向)与图像进行卷积操作。这些核分别检测水平和垂直方向上的边缘。
  3. 核的定义

        水平方向的Sobel核(用于检测垂直边缘):

G_x=\begin{bmatrix}-1&0&1\\-2&0&2\\-1&0&1\end{bmatrix}

        垂直方向的Sobel核(用于检测水平边缘):

G_y=\begin{bmatrix}-1&-2&-1\\0&0&0\\1&2&1\end{bmatrix}

三、prewitt算子,与Sobel算子类似,Prewitt算子通过计算图像在水平和垂直方向上的梯度来检测边缘。

水平方向的Prewitt核(用于检测垂直边缘):

G_x=\begin{bmatrix}1&0&-1\\1&0&-1\\1&0&-1\end{bmatrix}

垂直方向的Prewitt核(用于检测水平边缘):G_y=\begin{bmatrix}1&1&1\\0&0&0\\-1&-1&-1\end{bmatrix}

四、roberts算子,是一种基于对角线方向的一阶导数算子,Roberts算子使用两个2x2的核来近似图像的一阶导数,从而检测水平和垂直方向上的边缘。

水平边缘检测核

\nabla_x=\begin{bmatrix}1&0\\0&-1\end{bmatrix}

垂直边缘检测核

\nabla_y=\begin{bmatrix}0&1\\-1&0\end{bmatrix}

五、小波变换,本文采用haar小波基,后续会出一篇基于小波变换的图像边缘检测

五种边缘检测的实现:

这里对小波变换边缘检测进行了形态学操作,边缘检测效果更好。

clc,clear;
X=imread('Test Figure.tif');
X1=rgb2gray(X);
BW_sobel=edge(X1,'sobel');%使用sobel算子
BW_prewitt=edge(X1,'prewitt');%使用prewitt算子
BW_roberts=edge(X1,'roberts');%使用roberts算子
w=[-2 -4 -4 -4 -2;-4 0 8 0 -4;-4 8 24 8 -4;-4 0 8 0 -4;-2 -4 -4 -4 -2];%LoG算子的掩膜
BW_log=imfilter(X1,w);%使用LoG算子
% 小波变换参数
waveletName = 'haar';  % 小波基
level = 1;  % 分解层数 
% 小波分解
[C, S] = wavedec2(X1, level, waveletName);
% 提取细节系数(水平、垂直、对角线)
[H, V, D] = detcoef2('all', C, S, level);
% 边缘检测 - 利用小波细节系数
edge_image = sqrt(H.^2 + V.^2 + D.^2); 
% 形态学操作 - 膨胀和腐蚀
se = strel('disk', 1);
edge_image_dilated = imdilate(edge_image, se);
edge_image_eroded = imerode(edge_image_dilated, se);
subplot(2,3,1),imshow(X),title('原图');
subplot(2,3,2),imshow(BW_log>200),title('log算子');%显示二值图像,像素大于200则为1
subplot(2,3,3),imshow(edge_image,[]),title('小波变换');
subplot(2,3,4),imshow(BW_sobel),title('sobel算子');
subplot(2,3,5),imshow(BW_prewitt),title('prewitt算子');
subplot(2,3,6),imshow(BW_roberts),title('roberts算子');

效果如下:

Matlab代码转换为C代码需要经过以下步骤: 1. 理解Matlab代码的功能和算法原理。 2. 将Matlab代码转换为C语言代码。 3. 编译和测试C代码。 下面是一个参考的Matlab代码: ```matlab % Generate data x = randn(50,1); y = randn(50,1); z = x.^2 + y.^2 + 0.1*randn(50,1); % Fit a quadratic surface [X,Y] = meshgrid(-3:0.1:3,-3:0.1:3); Z = zeros(size(X)); for i = 1:numel(x) D = (X-x(i)).^2 + (Y-y(i)).^2; Z = Z + z(i)*exp(-D/2); end % Plot the data and surface figure scatter3(x,y,z,'filled') hold on surf(X,Y,Z); ``` 下面是相应的C代码: ```c #include <math.h> #include <stdio.h> #define N 50 #define M 61 int main() { int i, j, k; double x[N], y[N], z[N]; double X[M][M], Y[M][M], Z[M][M]; double D[M][M]; // Generate data for (i = 0; i < N; i++) { x[i] = randn(); y[i] = randn(); z[i] = x[i]*x[i] + y[i]*y[i] + 0.1*randn(); } // Fit a quadratic surface for (i = 0; i < M; i++) { for (j = 0; j < M; j++) { X[i][j] = -3.0 + i*0.1; Y[i][j] = -3.0 + j*0.1; Z[i][j] = 0.0; D[i][j] = 0.0; } } for (k = 0; k < N; k++) { for (i = 0; i < M; i++) { for (j = 0; j < M; j++) { D[i][j] = (X[i][j]-x[k])*(X[i][j]-x[k]) + (Y[i][j]-y[k])*(Y[i][j]-y[k]); Z[i][j] += z[k]*exp(-D[i][j]/2); } } } // Plot the data and surface FILE *fp = fopen("data.txt", "w"); for (i = 0; i < N; i++) { fprintf(fp, "%lf %lf %lf\n", x[i], y[i], z[i]); } fclose(fp); fp = fopen("surface.txt", "w"); for (i = 0; i < M; i++) { for (j = 0; j < M; j++) { fprintf(fp, "%lf %lf %lf\n", X[i][j], Y[i][j], Z[i][j]); } fprintf(fp, "\n"); } fclose(fp); return 0; } double randn() { double x1, x2, w, y1; static double y2; static int use_last = 0; if (use_last) { y1 = y2; use_last = 0; } else { do { x1 = 2.0 * rand() / RAND_MAX - 1.0; x2 = 2.0 * rand() / RAND_MAX - 1.0; w = x1 * x1 + x2 * x2; } while (w >= 1.0); w = sqrt((-2.0 * log(w)) / w); y1 = x1 * w; y2 = x2 * w; use_last = 1; } return y1; } ``` 注意,这里只是一个简单的转换示例,实际上还需要根据具体的算法和需求来编写相应的C代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宋政基

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值