基于 Sobel 算子的边缘检测的FPGA 算法实现和MATLAB的实现
1. 背景知识
边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。 这些包括(i)深度上的不连续、(ii)表面方向不连续、(iii)物质属性变化和(iv)场景照明变化。 边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域。
2. 边缘检测算子
一阶:Roberts Cross 算子,Prewitt 算子,Sobel 算子, Kirsch 算子,罗盘算子;
二阶: Marr-Hildreth,在梯度方向的二阶导数过零点,Canny 算子,Laplacian 算子。
今天要说的是基于 Sobel 算子的边缘检测的 FPGA 算法和MATLAB的实现。
3. Sobel滤波原理
Sobel 滤波,也称Sobel算子,是像素边缘检测中最重要的算子之一,在机器学习、数字媒体、计算机视觉等信息科技领域起着举足轻重的作用。边缘点其实是图像灰度跳变剧烈的点,所以先计算梯度图像,然后将梯度图像中较亮的那一部分提取出来就是简单的边缘部分。根据该原理,Sobel算子首先用两组3×3的滤波器分别对图像横向及纵向进行滤波,从而得到横向和纵向的梯度图像(亮度差分近似值)。若A表示原始图像,和分别代表经横向及纵向边缘检测的图像,其公式如下:
图像的每一个像素的横向及纵向梯度近似值可用结合。然后计算梯度方向: 此外,计算梯度图像时一般会使用,用绝对值消除梯度方向的影响。
如果以上的角度Θ等于零,即代表图像该处拥有纵向边缘,左方较右方暗。
缺点是Sobel算子并没有将图像的主题与背景严格地区分开来,换言之就是Sobel算子并没有基于图像灰度进行处理,由于Sobel算子并没有严格地模拟人的视觉生理特征,所以提取的图像轮廓有时并不能令人满意。
首先一篇他文让大家了解下sobel的工作原理 : 彻底理解数字图像处理中的卷积-以Sobel算子为例
clear all;
close all;
imag = imread('sobel.jpg'); %读取关键帧
subplot(131);imshow(imag);title('原图');
imag = rgb2gray(imag); %转化为灰度图
[high,width] = size(imag); % 获得图像的高度和宽度
F2 = double(imag);
U = double(imag);
uSobel = imag;
for i = 2:high - 1 %sobel边缘检测
for j = 2:width - 1
Gx = (U(i+1,j-1) + 2*U(i+1,j) + F2(i+1,j+1)) - (U(i-1,j-1) + 2*U(i-1,j) + F2(i-1,j+1));
Gy = (U(i-1,j+1) + 2*U(i,j+1) + F2(i+1,j+1)) - (U(i-1,j-1) + 2*U(i,j-1) + F2(i+1,j-1));
uSobel(i,j) = sqrt(Gx^2 + Gy^2);
end
end
subplot(132);imshow(im2uint8(uSobel));title('边缘检测后'); %画出边缘检测后的图像
% Matlab自带函数边缘检测
% K为获取得到的关键帧的灰度图
BW3 = edge(imag,'sobel', 0.07);
subplot(133);imshow(BW3,[]);title('Matlab自带函数边缘检测');
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 18:56:27 09/11/2019
// Design Name:
// Module Name: sobel
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module sobel#(
parameter DW = 8,
parameter LINE_N = 3,
parameter iTHRESHOLD = 150
)
(
input pixelclk_i,
input rst_n,
input clk,
input [DW-1:0] din,
output pixelclk_o,
output dout
);
localparam DATA_IN_WIDTH = 11;
//Sobel x
localparam X1 = 3'd1, X2 = 3'd0, X3 = 3'd1,
X4 = 3'd2, X5 = 3'd0, X6 = 3'd2,
X7 = 3'd1, X8 = 3'd0, X9 = 3'd1;
//Sobel y
localparam Y1 = 3'd1, Y2 = 3'd2, Y3 = 3'd1,
Y4 = 3'd0, Y5 = 3'd0, Y6 = 3'd0,
Y7 = 3'd1, Y8 = 3'd2, Y9 = 3'd1;
reg [DW-1:0] din_r0[0:LINE_N-1];
reg [DW-1:0] din_r1[0:LINE_N-1];
reg [DW-1:0] din_r2[0:LINE_N-1];
wire matrix_clken;
matrix_3x3 uut_matrix_3x3(
.clk(clk),
.rst_n(rst_n),
.per_clken(pixelclk_i),
.per_img(din),
.matrix_clken(matrix_clken),
.matrix_p11(din_r0[0]),
.matrix_p12(din_r0[1]),
.matrix_p13(din_r0[2]),
.matrix_p21(din_r1[0]),
.matrix_p22(din_r1[1]),
.matrix_p23(din_r1[2]),
.matrix_p31(din_r2[0]),
.matrix_p32(din_r2[1]),
.matrix_p33(din_r2[2])
);
//1clk
//1.Gx = P ★Sobelx -- 原始图像与 Sobel 算子 X 方向卷积;
reg [9:0] Gx_temp1;//postive result
reg [9:0] Gx_temp2;//negetive result
reg [9:0] Gx_data;//Horizontal grade data
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
Gx_temp1 <= 10'd0;
Gx_temp2 <= 10'd0;
Gx_data <= 10'd0;
end
else begin
Gx_temp1 <= din_r0[2]*X3 + din_r1[2]*X6 + din_r2[2]*X9;//postive result
Gx_temp2 <= din_r0[0]*X1 + din_r1[0]*X4 + din_r2[0]*X7;//negetive result
Gx_data <= (Gx_temp1 >= Gx_temp2)? Gx_temp1 - Gx_temp2 : Gx_temp2 - Gx_temp1;
end
end
// 2. Gy = P★Sobely -- 原始图像与 Sobel 算子 Y 方向卷积;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
Gy_temp1 <= 10'd0;
Gy_temp2 <= 10'd0;
end
else begin
Gy_temp1 <= din_r0[0]*X1 + din_r0[1]*X2 + din_r0[2]*X3;//postive result
Gy_temp2 <= din_r2[0]*X1 + din_r2[1]*X2 + din_r2[2]*X3;//negetive result
end
end
//得到GY和GX 1clk
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
Gx_data <= 10'd0;
Gy_data <= 10'd0;
end
else begin
Gx_data <= (Gx_temp1 >= Gx_temp2)? Gx_temp1 - Gx_temp2 : Gx_temp2 - Gx_temp1;
Gy_data <= (Gy_temp1 >= Gy_temp2)? Gy_temp1 - Gy_temp2 : Gy_temp2 - Gy_temp1;
end
end
// 3. 实现平方和
wire [10:0] dim;
assign dim = Gx_data + Gy_data;
// 4. 阈值比较形成边缘查找后的二值图像
//1clk
reg post_img_bit_r;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
post_img_bit_r <= 1'b0;
else if(dim >= iTHRESHOLD)
post_img_bit_r <= 1'b1;
else
post_img_bit_r <= 1'b0;
end
assign dout = post_img_bit_r;
//per_clken delay 3clk
reg [2:0] per_clken_r;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
per_clken_r <= 3'b0;
else
per_clken_r <= {per_clken_r[1:0], matrix_clken};
end
assign pixelclk_o = per_clken_r[2];
endmodule
相关文章
- Matlab实现:图像边缘提取
- matlab 二维或三维三角剖分
- matlab 点云轮廓边缘检测
- matlab坐标轴设置
- [转] Matlab与C++混合编程(依赖OpenCV)
- Atitit java c# php c++ js跨语言调用matlab实现边缘检测等功能attilax总结
- Matlab:序列分析法MATLAB代码
- 一种用于环境声源的被动到达角(AoA)提取算法(Matlab代码实现)
- 基于SUSAN算法的边缘检测方法研究(Matlab代码实现)
- 【数学建模】单、多因素试验的方差分析(Matlab代码实现)
- 混合整数规划的机组组合(Matlab代码实现)
- 基于场景分析法的电动车优化调度(Matlab代码实现)
- 【图像处理】基于二维FIR的特定角度边缘检测(Matlab代码实现)
- 【MATLAB】matlab实现最大熵法图像分割程序
- m一种基于QPSK信号的准最大似然译码器误码率matlab仿真
- 基于GA算法的TSP最短路径搜索matlab仿真
- m基于高斯滤波和八方向sobel边缘提取的道路检测和提取算法matlab仿真
- 【数字信号处理】卷积编程实现 ( Matlab 卷积和多项式乘法 conv 函数 | 使用 matlab 代码求卷积并绘图 )
- 【MATLAB】三维图形绘制 ( 绘制网格 + 等高线 | meshc 函数 | 绘制平面 + 等高线 | surfc 函数 )
- 【MATLAB】MATLAB 2017A 软件安装
- MATLAB学习笔记(六)——MATLAB数据分析与多项式计算
- Matlab:MATLAB GUI不同控件函数间变量传递的三种方法详解
- 一种基于分类的旋转机械故障诊断频段选择的新方法研究(Matlab代码实现)
- 【车间调度】基于卷积神经网络的柔性作业车间调度问题的两阶段算法(Matlab代码实现)
- 基于matlab的分簇异构无线传感器网络选举协议
- Simulink与MATLAB的接口方式