基于FPGA的视频监控系统 | 边缘检测和灰度图像 | Sobel算子和Robert算子 | VGA液晶显示 | OV7670

1 项目目的与意义

        近年来,随着计算机技术和数字图像处理技术的不断发展和提高,以及交通监控及视频图像压缩等领域的深入研究,使得城市道路的监控越来越受到人们的重视和关注。在二十世纪的时候,人们就希望借助于图像处理这种方式给人们来来便利,通过一定的图像处理的技术,服务人们的生活。近年来,随着计算机技术和数字图像处理技术的不断发展和提高,以及交通监控及视频图像压缩等领域的深入研究,使得城市道路的监控越来越受到人们的重视和关注。就计算机来说,不管是硬件技术的发展,还是软件技术的发展,都大大推动了图像处理技术的发展,越来越多的研究者开始利用计算机这样一种高效的工具进行图像处理技术的研究,后来图像处理就成为了一个独立的学科分支,研究内容越来越广,涉及到生活的方方面面,不管是在尖端的航天领域还是人们普通的生活中,都可以看到该技术的身影,所以本系统选择了图像处理的这个领域进行研究,也是具有很好的研究意义。

2 项目原理简述

        本系统在边缘检测部分能够实现的功能就是,首先系统需要从外部存储器SDRAM 中读取图像数据,这些读取的数据就是接下来进行边缘检测的原始数据,然后利用 Sobel 算子的 3×3 矩阵模板,对图像的各个像素点进行卷积计算,然后通过设定阈值,来判断该像素点是否是该图像的边缘,最后将判断的结果,也就是图像的边缘数据传输到 VGA 接口的液晶屏中进行显示。边缘检测是实现图像分割、目标区域识别和区域形状提取等图像处理技术的基础。通过计算图像灰度分布的梯度可以反映出图像灰度的变化情况。

3 方案分析与总体设计

        系统主要包括OV7670摄像头模块,SDRAM模块,VGA显示模块,图像处理模块,系统的设计框图如图所示。

        OV7670摄像头模块负责图像的实时釆集工作。OV7670内部相关寄存器的配置信息被写入到控制模块,在程序运行时通过I²C总线与OV7670的I²C接口进行信息交互,将OV7670初始化为VGA分辨率、输出RGB565格式数据的模式。釆集到的图像信息经过写FIFO后,在釆用Verilog HDL设计的SDRAM控制器的控制下,被送至SDRAM进行存储。图像数据经过图像处理模块被发送到VGA控制器,经VGA接口电路,显示在VGA显器上。

4 OV7670 CMOS图像采集传感器

       人眼对于相同强度的单色光的主观亮度感觉不同,假如把混色后所得白光亮度定为100%,人的主观感觉是绿光仅次于白光,红光次之,蓝光最弱。把白光的亮度用红、绿、蓝三色表示,常用度量公式为

                                                         Y=0.299R+0.578G+0.114B

 

图像传感器通常分为CCD传感器或者CMOS传感器。相比CCD传感器,CMOS传感器的优点是几何尺寸小、集成性高、外围电路简单、功耗低、编程方便、成本低。设计时选择美国Omnivision公司的CMOS图像传感器OV7670。它体积小,工作电压低,价格低廉,提供单片VGA摄像头和影像处理器的所有功能。其VGA图像采 集速率最高达到30帧/S,感光阵列共有656×488个像素,其中有效像素为640×480个。通过I²C总 线 控 制,可 以 输 出RawRGB,RGB 5:6:5/5:5:5/4:4:4,YCbCr(YUV)4:2:2等数据格式,并具有曝光控制、伽马曲线、白平衡、增益控制、饱和度、色度调整等图像处理功能。

5 I²C总线时序

OV7670传感器支持I²C总线,且OV7670的SCCB标准总线遵循I²C总线的协议。在视频采集接口模块中,主要工作是对I²C总线的控制来完成CMOS OV7670传感器的初始化配置。I²C总线是由两根总线构成,分别是串行时钟/SCL 和串行数据/SDA。其因接口总线少、控制方式简单、通信速率高等优点被广泛设计为多种通信配置。串行模式下,8 位双向数据总线接口的传输速度是不同的,一般标准下可达到100Kbit/s,最高可达 3.4Mbit/s。I²C总线结构是主/从节点方式,主节点负责初始化总线,控制总线通信,并产生开始/结束传送、发送信息信号以及传输数据的时钟信号,其他寻址访问的节点模块被认为是从节点模块。每个从节点模块在该总线范围内都有唯一一个地址作为标识。从节点的 7 位地址加 1 位读写位组成主节点对从节点的寻址字节。在写操作过程中,从节点一旦被住节点寻址,就执行特点的功能。在读操作过程中,主节点由从节点获得数据。在整个主从发送、传送过程中,通过主节点的 SCL 总线,所有发生实践都达到同步。须注意的是,连接到总线上的设备的接口形式必须是集电极开路或者漏极开路的输出状态。通过上拉电阻和电源,使两根总线一直保持高电平状态。这样,I²C 总线具有了线与功能,当总线上的所有器件都处于高电平时,I²C 总线才能达到高电平状态,使得总线上的器件,不管是高速还是慢速期间,都可以同步工作。在传送数据过程中,I²C 总线共有 3 种类型特征信号,分别是:开始信号:当 SCL 为高电平时,一旦检测到 SDA 由高电平向低电平发生跳变,就就发出开始信号,总线开始传送数据。结束信号:当 SCL 为高电平时,一旦检测到 SDA由低电平向高电平跳变,就发出结束信号,总线结束传送数据。

6 图像处理模块

这里只介绍sobel算法边缘检测,Robert算法和灰度图像见附录。

边缘检测是实现图像分割、目标区域识别和区域形状提取等图像处理技术

的基础。通过计算图像灰度分布的梯度可以反映出图像灰度的变化情况。梯度是一阶导数的二维等效式,定义为向量:

这个向量的方向角和幅度分别为:a(x,y)=arctan(\frac{Gy}{Gx})        |G(x,y)|=\sqrt{Gx^{2}+Gy^{2}}

梯度幅值的计算通常采用计算量更小的绝对值来近似:

实际的应用中,计算偏导数常常是采用小区域模板卷积的方法来近似计算。

采用的 Sobel 算法,对空间域中的图像进行卷积计算,通过查阅的文献,可以知道,该算法在水平方向上的计算模板为Gx而在垂直方向上的模板为Gy,分别为如下所示的矩阵;

边缘检测的计算公式为:

7 测试结果与分析(这里只展示sobel算法边缘检测,Robert算法和灰度图像见附录

图像边缘检测及灰度图像实验图像如下(代码见附录)

下图为实验原图与Sobel边缘检测图像(Matlab实现)

下图为Robert边缘检测图像(Matlab实现)

下图为FPGA实验版实验结果图

 

 

 

 

 

 

8 附录

自编小论文下载地址(pdf格式)

https://download.csdn.net/download/qq_31421117/11817388

Sobel算子边缘检测(压缩包)

https://download.csdn.net/download/qq_31421117/11817836

Robert算子边缘检测(压缩包)

https://download.csdn.net/download/qq_31421117/11817820

 

 

 

摘录其中部分代码:

matlab实现sobel算子图像边缘检测

clear;
sourcePic=imread('X:/XXX.jpg');%读取原图像
grayrgb=rgb2gray(sourcePic);%图像转换为灰图
output = adapthisteq(grayrgb);

grayPic=mat2gray(output);%实现图像矩阵的归一化操作
[m,n]=size(grayPic);

newGrayPic=grayPic;%为保留图像的边缘一个像素
sobelNum=0;%经sobel 算子计算得到的每个像素的值

sobelThreshold=0.6;%设定阈值
for j=2:m-1 %进行边界提取
    for k=2:n-1
        sobelNum=abs(grayPic(j-1,k+1)+2*grayPic(j,k+1)+grayPic(j+1,k+1)-grayPic(j-1,k-1)-2*grayPic(j,k-1)-grayPic(j+1,k-1))+abs(grayPic(j-1,k-1)+2*grayPic(j-1,k)+grayPic(j-1,k+1)-grayPic(j+1,k-1)-2*grayPic(j+1,k)-grayPic(j+1,k+1));
        if(sobelNum > sobelThreshold)
            newGrayPic(j,k)=0;
        else
            newGrayPic(j,k)=1;
        end
    end
end

figure,imshow(newGrayPic);
title('Sobel 算子的处理结果')
clear;

Verilog实现sobel图像边缘检测模块

module sobel(
clk,
rst_n,
en,
data1,
data2,
data3,
data_out
);
input clk;
input rst_n;
input en;
input [15:0] data1;
input [15:0] data2;
input [15:0] data3;
output reg [15:0] data_out;
parameter THRE = 160;//100-200
reg [15:0] data11;
reg [15:0] data12;
reg [15:0] data13;
reg [15:0] data21;
reg [15:0] data22;
reg [15:0] data23;
reg [15:0] data31;
reg [15:0] data32;
reg [15:0] data33;
reg [17:0] Gy_temp1; //postive result
reg [17:0] Gy_temp2; //negetive result
reg [17:0] Gy_data; //Vertical grade data
reg [17:0] Gx_temp1; //postive result
reg [17:0] Gx_temp2;
reg [17:0] Gx_data;
reg [36:0] data_temp;
wire [15:0] data_sqrt;
wire [16:0] data_remainder;
always @ ( posedge clk or negedge rst_n )
begin
  if( !rst_n ) begin
    data11 <= 16'b0;
    data12 <= 16'b0;
    data13 <= 16'b0;
    data21 <= 16'b0;
    data22 <= 16'b0;
    data23 <= 16'b0;
    data31 <= 16'b0;
    data32 <= 16'b0;
    data33 <= 16'b0;
  end
  else begin
    data11 <= data1;
    data12 <= data11;
    data13 <= data12;
    data21 <= data2;
    data22 <= data21;
    data23 <= data22;
    data31 <= data3;
    data32 <= data31;
    data33 <= data32;
  end
end
//Caculate vertical Grade with |abs|
always@(posedge clk or negedge rst_n)
begin
  if(!rst_n) begin
    Gy_temp1 <= 0;
    Gy_temp2 <= 0;
    Gy_data <= 0;
  end
  else begin
    Gy_temp1 <= data11 + (data12 << 1) + data13; //postive result
    Gy_temp2 <= data31 + (data32 << 1) + data33; //negetive result
    Gy_data <= (Gy_temp1 >= Gy_temp2) ? Gy_temp1 - Gy_temp2 : Gy_temp2 - Gy_temp1;
  end
end
//Caculate h Grade with |abs|
always@(posedge clk or negedge rst_n)
begin
  if(!rst_n) begin
    Gx_temp1 <= 0;
    Gx_temp2 <= 0;
    Gx_data <= 0;
  end
  else begin
    Gx_temp1 <= data13 + (data23 << 1) + data33;
    Gx_temp2 <= data11 + (data21 << 1) + data31;
    Gx_data <= ( Gx_temp1 >= Gx_temp2 ) ? Gx_temp1 - Gx_temp2 : Gx_temp2 - Gx_temp1;
  end
end
always@(posedge clk or negedge rst_n)
begin
  if(!rst_n) begin
    data_temp <= 37'b0;
  end
  else begin
    data_temp <= Gx_data*Gx_data + Gy_data*Gy_data;
    //data_temp <= Gy_data;
  end
end

sqrt sqrt1(
.radical( data_temp[31:0] ),
.q(data_sqrt),
.remainder(data_remainder)
);

always @ ( posedge clk or negedge rst_n )
begin
  if( !rst_n ) begin
    data_out <= 16'b0;
  end
  else if( !en ) begin
    data_out <= data1;
  end
  else begin
      if( data_sqrt >= THRE ) begin
          data_out <= 16'b0;
      end
      else begin
          data_out <= 16'b1111111111111111;
      end
  end
end
endmodule

 

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于FPGAOV7670 Verilog驱动是一种用于控制OV7670图像传感器的Verilog硬件描述语言代码。OV7670是一款可编程的摄像头芯片,广泛应用于嵌入式系统和数字图像处理领域。 Verilog驱动的主要目的是配置OV7670传感器并捕获图像数据。该驱动需要通过FPGAOV7670进行通信,并使用适当的协议对其进行控制。驱动的核心功能包括发送配置命令、读取图像数据和控制传感器的各种功能。 在驱动中,首先需要初始化OV7670传感器。这包括设置寄存器的初始值、选择捕获模式和分辨率以及配置图像处理选项。初始化完成后,驱动可以开始捕捉图像。 驱动通过FPGAOV7670传感器进行通信,使用的协议通常是I2C或SPI。通过发送适当的命令和参数,驱动可以配置OV7670传感器,并从传感器中读取图像数据。 图像数据通常以像素阵列的形式从OV7670传感器输出。驱动需要对这些数据进行适当的处理和解码,以提取有用的图像信息。这可以包括图像增强、格式转换、裁剪或任何其他必要的处理步骤。 最后,驱动还应该提供用于读取和处理图像数据的接口。这可能包括存储图像数据到帧缓冲区、传输数据到其他设备或进行图像处理算法等。 基于FPGAOV7670 Verilog驱动在嵌入式系统中具有广泛的应用。它为用户提供了对OV7670传感器的完全控制,并允许他们在数字图像处理应用中实现各种功能。通过适当的配置和处理,驱动可以将OV7670传感器捕获的图像数据转化为实际可用的图像。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值