2016-05-25 16:53:54 Times_poem 阅读数 2316
  • FPGA入门

    本课程向大家介绍FPGA的基本概念和功能,并结合实际操作讲解实现原理和操作步骤,讲师也会带着大家演示一个实验。

    2315 人正在学习 去看看 腾讯云布道师团队

需求说明:图像处理FPGA实现前期算法准备

当前算法:已通过matlab验证成功


function scaler_bilinear()


%-----------------------------0:配置输入输出--------------------------------
m=2; %放大或缩小的高度
n=2; %放大或缩小的宽度


I=imread('F:\book\Digital image processing and machine vision\640480\plane.jpg');


[height,width,l]=size(I);    %输入分辨率 640*480


O=zeros(height*m,width*n,l); %输出分辨率 1920*1080


%-----------------------------1:开始输出计算--------------------------------


rot=[m,0,0;0,n,0;0,0,1];     %变换矩阵


for i=1:height*m
    for j=1:width*n
       pix=[i,j,1]/rot;
      
  float_Y=pix(1)-floor(pix(1)); %水平宽度小数部分 floor 向下取整
  float_X=pix(2)-floor(pix(2)); %垂直高度小数部分 floor 向下取整
  
%-----------------------------2:边界处理--------------------------------
  
if pix(1)<1      %边界处理
    pix(1)=1;
end


if pix(1)>height %边界处理
    pix(2)=height;
end


if pix(2)<1      %边界处理
    pix(2)=1;
end


if pix(2)>width  %边界处理
    pix(2)=width;
end


%-----------------------------3:原坐标四个相邻点----------------------------
 %四个相邻的点
 pix_up_left   = [floor(pix(1)) , floor(pix(2))]; 
 pix_up_right  = [floor(pix(1)) , ceil(pix(2))];  %floor 向下取整  ceil 向上取整
 pix_down_left = [ceil(pix(1))  , floor(pix(2))];
 pix_down_right= [ceil(pix(1))  , ceil(pix(2))];
 
%-----------------------------4:权重计算-----------------------------------
 
 %计算临近四个点的权重
 value_up_left   = (1-float_X) * (1-float_Y);     
 value_up_right  = float_X     * (1-float_Y);
 value_down_left = (1-float_X) * float_Y;
 value_down_right= float_X     * float_Y;            
 
  %按权重进行双线性插值
  
%  O(i,j,:) = value_up_left   * I(pix_up_left(1)   ,pix_up_left(2),:)   +...
%             value_up_right  * I(pix_up_right(1)  ,pix_up_right(2),:)  +...
%             value_down_left * I(pix_down_left(1) ,pix_down_left(2),:) +...
%             value_down_right* I(pix_down_right(1),pix_down_right(2),:);


%-----------------------------5:计算输出图像数值----------------------------
 O(i,j,1) = value_up_left   * I(pix_up_left(1),   pix_up_left(2)   ,1) +...
            value_up_right  * I(pix_up_right(1),  pix_up_right(2)  ,1) +...
            value_down_left * I(pix_down_left(1), pix_down_left(2) ,1) +...
            value_down_right* I(pix_down_right(1),pix_down_right(2),1);
 
 O(i,j,2) = value_up_left   * I(pix_up_left(1),   pix_up_left(2)   ,2) +...
            value_up_right  * I(pix_up_right(1),  pix_up_right(2)  ,2) +...
            value_down_left * I(pix_down_left(1), pix_down_left(2) ,2) +...
            value_down_right* I(pix_down_right(1),pix_down_right(2),2);


 O(i,j,3) = value_up_left   * I(pix_up_left(1),   pix_up_left(2)   ,3) +...
            value_up_right  * I(pix_up_right(1),  pix_up_right(2)  ,3) +...
            value_down_left * I(pix_down_left(1), pix_down_left(2) ,3) +...
            value_down_right* I(pix_down_right(1),pix_down_right(2),3);  


    end
    
end


% figure,imshow(uOt8(O))


%-----------------------------6:输出显示------------------------------------
figure,imshow(I);       title('输入图像640*480');


figure,imshow(uint8(O));title('输出图像1920*1080');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


设计来自:时间的诗


2016-08-16 13:27:43 sinat_25326461 阅读数 4586
  • FPGA入门

    本课程向大家介绍FPGA的基本概念和功能,并结合实际操作讲解实现原理和操作步骤,讲师也会带着大家演示一个实验。

    2315 人正在学习 去看看 腾讯云布道师团队

我的目的是实现sobel edge detection,linebuffer是其中必不可少的一部分。

linebuffer的实现如下:

1. http://blog.csdn.net/lzy272942518/article/details/46660383, 这里的实现方法是用了经典的书《基于FPGA的嵌入式图像处理系统设计》,英文版

下载链接:http://download.csdn.net/detail/lzy272942518/6949349

但是这个博客里面的代码我尝试了,不成功,但是思路是很清晰的,值得我们看看

2. 第二种是基于altera的FPGA,运用其中的IP核可以直接生产,这是很棒的,但是我的xilinx里面没有可以移位linebuffer的IP核,所以自己写了以下的程序。
好吧 actually,也不是我写的,是我傍边的巴基斯坦男写的,他真的很厉害。
 
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    13:09:59 08/13/2016 
// Design Name: 
// Module Name:    shift_ram 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module shift_ram(
	CLK,
	nRESET,
	data_in,
	data_out,
	Ready_DE
    );
	 
	input CLK;
	input nRESET;
	input Ready_DE;
	
	input [7:0]data_in;
	output [7:0]data_out;
	reg [7:0]ShiftRegister[0:647];
	
	reg [9:0]i;
	
	always@(posedge CLK)
	begin
		if(Ready_DE)
		begin
			ShiftRegister[0] <= data_in;
		end
		
		else
		begin
			ShiftRegister[0] <= ShiftRegister[0];
		end
		
		for (i = 1; i <= 647 ; i = i + 1)
				if(Ready_DE)
				begin
					ShiftRegister[i] <= ShiftRegister[i-1];	
				end
				
				else
				begin
					ShiftRegister[i] <= ShiftRegister[i];
				end				
	end
	
	assign data_out = ShiftRegister[647];
	
	

endmodule

在if语句中用了for语句进行循环,上面的647比较诡异,是因为我实现的是摄像头的处理,所以分辨率是648*494,如果大家用HDMI或者VGA的话,请参照各自的分辨率。

这样就可以实现linebuffer

http://www.cnblogs.com/oomusou/archive/2008/08/25/verilog_sobel_edge_detector.html 真爱无双的博客

虽然程序很难用(因为早),但是很清晰的讲解了思路。值得借鉴

2019-02-25 15:07:47 dyq1995 阅读数 1970
  • FPGA入门

    本课程向大家介绍FPGA的基本概念和功能,并结合实际操作讲解实现原理和操作步骤,讲师也会带着大家演示一个实验。

    2315 人正在学习 去看看 腾讯云布道师团队

下面简要分析了 FPGA 技术,包括 FPGA 技术原理和技术特点等,随后介绍一下FPGA 的图像处理系统算法的实现,包括存储模块、运算单元、控制模块以及数据传输模块等内容。

智能机器人、多媒体已经计算机的诞生都离不开数字图象处理技术,随着计算机智能化图像处理技术的不断发展,几乎所有领域当中都有数字图象技术的身影。例如军事、公共安全、工业、航天航空、卫星遥感以及生命科学等各种领域。因此对图象处理技术的要求也逐渐提高,需要数字图象设计朝着高效性和时效性的方向发展,FPGA技术下的图像处理系统算法越来越受到重视。

1、FPGA技术原理

FPGA通常包括两个部分,分别是储存编程数据的软件SRAM和三项可编程电路,这三种可编程电路分别是互连资源、输入模块、输出模块和可编程逻辑模块。FPGA中主要部分就是可编程逻辑模块,这一模块能够落实逻辑功能,同时还可以参考设计要求,灵活选择设置或是连接,从而实现各种逻辑功能。而输送模块则是芯片与外部环境进行连接的主要通道,能够促进内部逻辑阵列和器件引脚的连接,同时实现各种电气特征下的输送功能要求。芯片四周通常会排列IOB。

2、FPGA技术特点

FPGA既包含ASIC中的高度可靠性、高集成度和大规模等优势,同时还包括ASIC设计中灵活性差、投资大、设计时间长等问题,
除了上述优势外,FPGA还包括下面几项优点,首先是FPGA能够反复进行擦除和编程。在外部电路保持不变的状态下,通过设计不同逻辑可以完成各种电路功能。其次是投资较小,同时设计比较灵活,在发现问题后可以对设计直接进行更改,从而降低了投片风险程度。

3、FPGA的图象处理系统算法的实现

图像算法处理系统中的存储模块能够将提前准备好的图象数据进行存储,运算单元负责各项计算任务,促进实现各种图像处理算法,只需要将其中的数值进行更换即可。控制模块负责图像算法处理系统中的各种控制工作,辅助图像算法实施,并进行传输。

3.1、存储模块

随着FPGA技术的不断发展,从前众多优秀设计人员留下了大量数字系统成果。为了让其中部分成果能够有效应用于Altera特定设
备结构中,并进行有效应用,Altera企业根据Altera设备中的结构特征在上述成果的基础上进行了有效的优化,从而形成一种LPM
函数和可参数化模块,为此设计人员需要参考相应的设计要求,通过硬件或是图形将语言模块中功能板块恰当地表述出来,并设置好一定的参数,尽量贴近系统要求。在这种设计模式下,能够提升设计效率和可靠性。

3.2、运算单元

运算单元的工作其实就是输出数据信息、落实数字图像算法和读取ROM数字图象中的灰度信息。当一个是三乘三中值邻域滤波器模板对目标图象进行作用时,首先应该了解这一滤波器中的九个数据信息,随后才能更好地使用中值滤波算法,而ROM中所储存的灰度数据主要可以在Verilog HDL的编程下,将其中的具体数值解读出来,同时FPGA技术下的编程工作中是不存在二维数组理念的,为此主要是通过移位寄存器RAM来储存IP核的,并落实邻域图象处理操作,实现各种数字图像处理算法。在一个全面的系统设计当中,例如设计DSP应用系统,需要通过数据缓冲移位寄存器,以移位寄存器RAM为基础的IP核就是一种高效的处理措施。以移位寄存器RAM为基础的IP核属于一种参数化的移位寄存器,同时TAPS值在一定程度上也影响了系统中移位寄存器在一时间点中的输出数据总路数,这种IP核十分适用于有限冲击响应滤波器和线性反馈寄存器。对于以移位寄存器RAM为基础的IP
核想要发挥出应有的作用,就应该先为IP核进行适当的参数设置,主要包括所有TAP的对应数据深度、TAP输出路数、shiftout端
口宽度、shiftin数据宽度、RAM模块类型等。

3.3、控制模块

控制模块在整个系统中是一种核心部件,可以辅助系统的运行,同时融入到整个系统内部。主要负责工作包括辅助运算单元在
ROM中准确读取数据信息,操作运算单元落实图像处理算法,帮助运算单元和数据传输子系统进行信息流通等。

3.4、数据传输模块

数据传输模块其中包含两部分内容,分别是串口通信模块和FIFO传输模块。将图像处理子系统中的时钟设置成五十毫赫兹,将串口通信模块设置成九千六百赫兹波特率。为此可以通过异步FIFO促进图像通信模块和子系统串口之间的跨时钟数据传播,联系。为了让图像算法子系统和上位机PC之间的通信过程更加便捷,通常都是通过通信串口进行数据信息交流。

通过FPGA技术进行图象处理,能够拥有更多的使用优势,比如成本较低、方便落实以及适用范围较广等特点。同时还拥有实时性、集成化、小型化等特点。随着我国微电子技术的发展,图象处理逐渐应用于图象通信以及多媒体等各个领域,而FPGA技术
可以有效促进硬件对实时图象的有效处理,以FPGA技术为基础的图象处理研究也将成为未来信息领域发展的热点。

 

 

 

 

2019-05-29 11:17:57 qq_22168673 阅读数 674
  • FPGA入门

    本课程向大家介绍FPGA的基本概念和功能,并结合实际操作讲解实现原理和操作步骤,讲师也会带着大家演示一个实验。

    2315 人正在学习 去看看 腾讯云布道师团队

前言

本文是导航目录,以记录自己的FPGA学习之路。

本专题也仅仅是用于初步学习和了解数字图像处理基础。或许不能达到窥一斑而知全貌,但当涉猎即可!

每章节内容,后期空闲时,会逐步更新!

学习贵在坚持!生活,不能没有目标!

 

基础篇:

 

一、FPGA实现Sober边缘检测 二、FPGA实现灰度直方图均衡
三、基于FPGA的均值滤波器

四、高斯滤波原理

参考文献  :http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html

五、基于FPGA的canny算子设计 六、基于FPGA的局部自适应分割
   
   
   
基于FPGA实现OV5640摄像头的视频图像采集及VGA显示  
   

 

 

 

进阶篇:

 

 

推荐书籍:

《数字信号处理的FPGA实现》第四版

《基于FPGA的数字图像处理原理及应用》

《数字图像处理(第三版)冈萨雷斯》

 

博客学习:

angelbosj  视频拼接器  : https://blog.csdn.net/angelbosj?t=1

LakersNation                :  https://blog.csdn.net/lzy272942518?t=1

Pieces_thinking的博客   :   https://blog.csdn.net/pieces_thinking?t=1

灰巧克力爱松露              :   https://blog.csdn.net/shadow_guo
 

 

 

 

 

 

 

2015-06-27 12:18:17 LZY272942518 阅读数 6807
  • FPGA入门

    本课程向大家介绍FPGA的基本概念和功能,并结合实际操作讲解实现原理和操作步骤,讲师也会带着大家演示一个实验。

    2315 人正在学习 去看看 腾讯云布道师团队

        本博文参考了《FPGA嵌入式图像处理系统设计》一书。该书的英文版下载链接:http://download.csdn.net/detail/lzy272942518/6949349

窗处理是图像处理中常见的一种处理,它的思想是对于图像矩阵,通过一个固定大小(例如3*3)的小矩阵对图像进行运算操作。常用的窗处理包括Sobel边缘检测,形态学操作,模糊滤波,高斯滤波等。在基于PC的图像处理领域,可以方便的实现窗处理操作。比如,在opencv库中可以自己随意构建窗口大小,然后调用相关的函数实现窗处理。

FPGA是一种可定制的逻辑电路,它拥有并行的结构特征,在设计上能实现硬件并行和流水线技术,可以实现算法的加速,而且性价比较高。本文即根据Sobel算法的理论,结合FPGA的结构特征,在FPGA上设计并尝试实现了Sobel窗处理算法方案。

Sobel边缘检测的思想是:该算子包含两组3 x 3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度查分近似值。如果以A代表原始图像,Gx及Gy分别代表经纵向向及横向边缘检测的图像,其公式如下(来源于百度图片):


对于FPGA实现Sobel,首先,是检测窗的实现。这种窗扩展了点运算,以一个局部邻域或窗口内像素值的函数运算结果作为输出:

Q[x,y] = f(I[x,y],...,I[x+△x,y+△y]),  (△x,△y)∈W

其中,W是I[x,y]为中心的窗口。以3×3大小的窗口为例,如图所示:


Sobel算子所需的窗口大小为3×3。在设计过程中,窗口应当满足以下要求:

1.能同时对窗口中所有的元素进行并行操作。

2.窗口采用流水的形式遍历整个图像。

设计的思路是:因为窗口在遍历图像过程中,每一个像素都会被窗口多次使用,因此需要通过缓存来存储像素,使得它们能在后续的窗口位置被重复利用。在FPGA中,可以设计3个单口行缓存(linebuffer),借助状态机和列计数值实现这种窗口,采用流水处理的方法,实现加速计算。如图为窗口结构:


其中状态信号用环形计数器来实现(计数值0-2),其驱动时钟为每一行第一个像素的像素时钟。窗口的行0由3个移位寄存器组成;行1——行2由状态机决定和行缓存的对应关系。窗口的控制逻辑如表1所示:

表1 窗口的控制逻辑

输入行

状态

行缓存0

行缓存1

行缓存2

输出行

0

0

(行2)

(行1)

(空)

1

1

行1

(行2)

(空)

2

2

行2

行1

1

3

0

行2

行1

2

4

1

行1

行2

3

5

2

行2

行1

4

6

0

行2

行1

5

 

……

……

……

……

……

  (注:行x对应窗口结构中的行x)

  对于窗口操作,存在的一个问题是边界部分无法得到处理。不过,本系统的窗口比较小,那么边界像素的输出可以不计算。这样输出的图像比输入图像减小了1行和1列,并不会影响图像显示效果。

具体实现思路:

1.窗口模块:

 3个行缓存,每个大小为640×8 bit;

 状态机,状态信号(0-2),以每一行第一个像素时钟作为驱动状态信号的时钟;

 3个移位寄存器,每个大小为8 bit,作为检测窗口的第一行

窗口的实现,需要建立一个像素时钟驱使的always块,根据窗口结构和表1的控制逻辑,构造窗口;

2.边缘判断模块:

    通过窗口可在像素点P处得到以其为中心,周围8个点的像素值。根据Sobel算子结构,进行计算。设置一个阈值,当计算后的值大于此阈值时,判定此像素为边缘。


关键部分代码(verilog):

always@(posedge PCLK)begin//产生行时钟,作为状态机驱动时钟
begin
	 if(VtcHCnt==0)
	   Line_CLK <= 1;
	 else
	   Line_CLK <= 0;
end
end

reg[1:0] state;
initial state = 0;

always@(posedge Line_CLK)begin//产生状态计数器
 if(VtcVCnt==1)
 state <= 2'b00;
 else begin
   if(state == 2'b10)
	   state <= 2'b00;
	else 
	   state <= state + 1;
	end
end 
//定义窗口第0行的三个元素
reg[7:0]S_Window0;
reg[7:0]S_Window1;
reg[7:0]S_Window2;


//定义行缓存
reg[7:0]LineBuffer0[639:0];
reg[7:0]LineBuffer1[639:0];
reg[7:0]LineBuffer2[639:0];
always@(posedge PCLK)begin
   case(state)
	 2'b00: begin
	    <span style="white-space:pre">	</span>LineBuffer0[VtcHCnt] <= GRAY;
		 LineBuffer1[VtcHCnt] <= LineBuffer1[VtcHCnt];
		 LineBuffer2[VtcHCnt] <= LineBuffer2[VtcHCnt];	
		 S_Window0 <= GRAY;
		 S_Window1 <= S_Window0;
	         S_Window2 <= S_Window1;
		if(VtcHCnt>=2&&VtcVCnt>=3)begin
		 if((S_Window0 + S_Window1*2 + S_Window2)>(LineBuffer1[VtcHCnt-2]+LineBuffer1[VtcHCnt-1]*2 +LineBuffer1[VtcHCnt]))
	          DOUT_reg <= ((S_Window0 + S_Window1*2  + S_Window2 -LineBuffer1[VtcHCnt-2]-LineBuffer1[VtcHCnt-1]*2  -LineBuffer1[VtcHCnt]))/4;
		 else
		 DOUT_reg <= (LineBuffer1[VtcHCnt-2]+LineBuffer1[VtcHCnt-1]*2  +LineBuffer1[VtcHCnt]-(S_Window0 + S_Window1*2  + S_Window2))/4;
		end 
		end 
	 2'b01: begin
	         LineBuffer1[VtcHCnt] <= GRAY;
		 LineBuffer0[VtcHCnt] <= LineBuffer0[VtcHCnt];
		 LineBuffer2[VtcHCnt] <= LineBuffer2[VtcHCnt];		 
		 S_Window0 <= GRAY;
	         S_Window1 <= S_Window0;
	         S_Window2 <= S_Window1;
	   if(VtcHCnt>=2&&VtcVCnt>=3)begin
   	 if((S_Window0 + S_Window1 *2 + S_Window2)>(LineBuffer2[VtcHCnt-2]+LineBuffer2[VtcHCnt-1]*2  +LineBuffer2[VtcHCnt]))
		 DOUT_reg <= ((S_Window0 + S_Window1*2  + S_Window2 -LineBuffer2[VtcHCnt-2]-LineBuffer2[VtcHCnt-1] *2 -LineBuffer2[VtcHCnt]))/4;
		 else
		 DOUT_reg <= (LineBuffer2[VtcHCnt-2]+LineBuffer2[VtcHCnt-1] *2 +LineBuffer2[VtcHCnt]-(S_Window0 + S_Window1*2  + S_Window2))/4;	
		end		   
		end
	 2'b10: begin
	    <span style="white-space:pre">	</span> LineBuffer2[VtcHCnt] <= GRAY;	 
		 LineBuffer0[VtcHCnt] <= LineBuffer0[VtcHCnt];
		 LineBuffer1[VtcHCnt] <= LineBuffer1[VtcHCnt];	
		 S_Window0 <= GRAY;
	    S_Window1 <= S_Window0;
	    S_Window2 <= S_Window1;
		if(VtcHCnt>=2&&VtcVCnt>=3)begin
		 if((S_Window0 + S_Window1*2  + S_Window2)>(LineBuffer0[VtcHCnt-2]+LineBuffer0[VtcHCnt-1] *2 +LineBuffer0[VtcHCnt]))
		 DOUT_reg <= ((S_Window0 + S_Window1*2  + S_Window2 -LineBuffer0[VtcHCnt-2]-LineBuffer0[VtcHCnt-1]*2  -LineBuffer0[VtcHCnt]))/4;
		 else
		 DOUT_reg <= (LineBuffer0[VtcHCnt-2]+LineBuffer0[VtcHCnt-1]*2  +LineBuffer0[VtcHCnt]-(S_Window0 + S_Window1*2  + S_Window2))/4;
	    end
		end
	default:	begin
	       DOUT_reg <= DOUT_reg;
			 LineBuffer0[VtcHCnt] <= LineBuffer0[VtcHCnt];
		    LineBuffer1[VtcHCnt] <= LineBuffer1[VtcHCnt];	
		    LineBuffer2[VtcHCnt] <= LineBuffer2[VtcHCnt];	
			 end
	endcase

end 









FPGA实现图像处理画中画PIP

博文 来自: my_share
没有更多推荐了,返回首页