fpga4student.com FPGA digital design projects using Verilog/ VHDL: Image processing on FPGA using Verilog HDL

Tuesday, November 8, 2016

Image processing on FPGA using Verilog HDL

This project is aimed to show details how to process an image on FPGA using Verilog from reading a bitmap image (.bmp), processing and writing the processed result to an output bitmap image. The Verilog code for image processing is presented.



verilog image processing fpga




In this project, some simple processing operations are implemented such as inversion, contrast, brightness and threshold operations. An input .bmp image is processed by a selected operation and then, the processed image is written to a bitmap image output.bmp to see if it is processed correctly.

The operations for processing an input image are defined in the following definition file. To change the processing operation, just switch the comment line.

/***************************************/
 /****************** Definition file ********/ 
/************** **********************************************/ 
`define INPUTFILENAME "./img/your_image.hex" // Input file name 
`define OUTPUTFILENAME "output.bmp" // Output file name 
// Choose the operation of code by delete 
// in the beginning of the selected line 
//`define BRIGHTNESS_OPERATION 
//`define CONTRAST_OPERATION
 `define INVERT_OPERATION 
//`define THRESHOLD_OPERATION
// fpga4student.com FPGA projects, Verilog projects, VHDL projects

The definition file is also to define paths and names of the input and output file. 
First of all, to process the .bmp image on FPGA, the image is converted from bitmap to hexadecimal format. Below is a Matlab example code to convert a bitmap image to .hex file. Image size is 768x512 and the hex file includes R, G, B data of the bitmap image.

b=imread('kodim24.bmp'); % 24-bit BMP image RGB888

k=1;
for i=512:-1:1
for j=1:768
a(k)=b(i,j,1);
a(k+1)=b(i,j,2);
a(k+2)=b(i,j,3);
k=k+3;
end
end
fid = fopen('kodim24.hex', 'wt');
fprintf(fid, '%x\n', a);
disp('Text file write done');disp(' ');
fclose(fid);

% fpga4student.com FPGA projects, Verilog projects, VHDL projects

Afterer obtaining .hex file from bitmap image, the your_image.hex is copied to ./img folder to be processed. Then, the following Verilog module is used to read the .hex file:


/*****************************************************************/ 

/********** Module for reading and processing image **************/ /******************************************************************/ // fpga4student.com FPGA projects, Verilog projects, VHDL projects
`include "parameter.v" // Include definition file 
module image_read #( parameter 
                 WIDTH = 768, // Image width 
                 HEIGHT = 512, // Image height 
                 INFILE = "./img/your_image.hex", // image file     
                 START_UP_DELAY = 100, //Delay during start up time 
                 HSYNC_DELAY = 160, // Delay between 
                 HSYNC pulses 
                 VALUE= 100, // value for Brightness operation 
                 THRESHOLD= 90, 
           // Threshold value for Threshold and contrast operation 
                ValueToMul=2, 
                ValueToAdd= 10, 
// Value to add in contrast addition 
                ValueToSubtract= 15 , 
// Value to add in contrast addition 
               SIGN=1 // Sign value using for brightness operation
              // SIGN = 0: Brightness subtraction 
// SIGN = 1: Brightness addition 
( input HCLK, // clock 
input HRESETn, // Reset (active low) 
output reg VSYNC, // Vertical synchronous pulse 
// This signal is often a way to indicate that one entire image is transmitted. 
// Just create and is not used, will be used once a video or many images are transmitted. 
output reg HSYNC, 
// Horizontal synchronous pulse 
// An HSYNC indicates that one line of the image is transmitted. 
//Used to be a horizontal synchronous signals for writing bmp file. 
output reg [7:0] DATA_R0, // 8 bit Red data (even) 
output reg [7:0] DATA_G0, // 8 bit Green data (even)
 output reg [7:0] DATA_B0, // 8 bit Blue data (even) 
output reg [7:0] DATA_R1, // 8 bit Red data (odd) 
output reg [7:0] DATA_G1, // 8 bit Green data (odd) 
output reg [7:0] DATA_B1, // 8 bit Blue data (odd) 
output ctrl_done // Done flag 
);
// fpga4student.com FPGA projects, Verilog projects, VHDL projects
//---------------------------// 
// -------- Reading data from input file ----------// 
//-------------------------------------------------// 
initial begin 
$readmemh(INFILE,total_memory,0,sizeOfLengthReal-1); 
// read file from INFILE 
end 
// use 3 intermediate signals RGB to save image data 
always@(start) begin 
if(start == 1'b1) begin 
for(i=0; i
temp_BMP[i] = total_memory[i+0][7:0]; 
end 
for(i=0; i
for(j=0; j
org_R[WIDTH*i+j] = temp_BMP[WIDTH*3*(HEIGHT-i-1)+3*j+0]; org_G[WIDTH*i+j] = temp_BMP[WIDTH*3*(HEIGHT-i-1)+3*j+1]; org_B[WIDTH*i+j] = temp_BMP[WIDTH*3*(HEIGHT-i-1)+3*j+2]; 
end 
end 
end 
end
// fpga4student.com FPGA projects, Verilog projects, VHDL projects
To read the hexadecimal file, $readmemh is used in Verilog. After reading the .hex file, RGB data is saved into memory and processed. Below is the Verilog code to perform inverting operation:


/**************************************/
 /* INVERT_OPERATION */ 
/**************************************/ 
`ifdef INVERT_OPERATION 
value2 =(org_B[WIDTH * row + col ] + org_R[WIDTH * row + col] +org_G[WIDTH * row + col])/2; 
value4 =(org_B[WIDTH * row + col ] + org_R[WIDTH * row + col] +org_G[WIDTH * row + col])/4; 
value = (value2+value4)/2; 
DATA_R0=255-value; 
DATA_G0=255-value; 
DATA_B0=255-value; 
value2 =(org_B[WIDTH * row + col+1] + org_R[WIDTH * row + col+1] +org_G[WIDTH * row + col+1])/2; 
value4 =(org_B[WIDTH * row + col+1] + org_R[WIDTH * row + col+1] +org_G[WIDTH * row + col+1])/4; 
value = (value2+value4)/2; DATA_R1=255-value; DATA_G1=255-value; DATA_B1=255-value; 
`endif
// fpga4student.com FPGA projects, Verilog projects, VHDL projects

After processed the image, it is needed to write the processed data to an output image. The following Verilog code is to write processed data to a bitmap image:

/****************** Module for writing .bmp image *************/ /***********************************************************/ 
module image_write #(parameter 
WIDTH = 768, // Image width 
HEIGHT = 512, // Image height 
INFILE = "output.bmp", // Output image 
BMP_HEADER_NUM = 54 // Header for bmp image 
// fpga4student.com FPGA projects, Verilog projects, VHDL projects
input HCLK, // Clock input 
HRESETn, // Reset active low 
input hsync, // Hsync pulse 
input [7:0] DATA_WRITE_R0, // Red 8-bit data (odd) 
input [7:0] DATA_WRITE_G0, // Green 8-bit data (odd) 
input [7:0] DATA_WRITE_B0, // Blue 8-bit data (odd) 
input [7:0] DATA_WRITE_R1, // Red 8-bit data (even) 
input [7:0] DATA_WRITE_G1, // Green 8-bit data (even) 
input [7:0] DATA_WRITE_B1, // Blue 8-bit data (even) 
output reg Write_Done 
);
// fpga4student.com FPGA projects, Verilog projects, VHDL projects
//-----------------------------------// 
//-------Header data for bmp image-----// 
//-------------------------------------// 
// Windows BMP files begin with a 54-byte header: 
// Check the website to see the value of this header:
// http://www.fastgraph.com/help/bmp_header_format.html 
initial  begin 
BMP_header[ 0] = 66;BMP_header[28] =24; 
BMP_header[ 1] = 77;BMP_header[29] = 0; 
BMP_header[ 2] = 54;BMP_header[30] = 0; 
BMP_header[ 3] = 0;BMP_header[31] = 0;
BMP_header[ 4] = 18;BMP_header[32] = 0;
BMP_header[ 5] = 0;BMP_header[33] = 0; 
BMP_header[ 6] = 0;BMP_header[34] = 0; 
BMP_header[ 7] = 0;BMP_header[35] = 0; 
BMP_header[ 8] = 0;BMP_header[36] = 0; 
BMP_header[ 9] = 0;BMP_header[37] = 0; 
BMP_header[10] = 54;BMP_header[38] = 0; 
BMP_header[11] = 0;BMP_header[39] = 0; 
BMP_header[12] = 0;BMP_header[40] = 0; 
BMP_header[13] = 0;BMP_header[41] = 0; 
BMP_header[14] = 40;BMP_header[42] = 0; 
BMP_header[15] = 0;BMP_header[43] = 0; 
BMP_header[16] = 0;BMP_header[44] = 0; 
BMP_header[17] = 0;BMP_header[45] = 0; 
BMP_header[18] = 0;BMP_header[46] = 0; 
BMP_header[19] = 3;BMP_header[47] = 0;
BMP_header[20] = 0;BMP_header[48] = 0;
BMP_header[21] = 0;BMP_header[49] = 0; 
BMP_header[22] = 0;BMP_header[50] = 0; 
BMP_header[23] = 2;BMP_header[51] = 0; 
BMP_header[24] = 0;BMP_header[52] = 0; 
BMP_header[25] = 0;BMP_header[53] = 0; 
BMP_header[26] = 1; BMP_header[27] = 0; 
end
//---------------------------------------------// 
//--------------Write .bmp file ------------// 
//-------------------------------------------// 
initial 
begin 
fd = $fopen(INFILE, "wb+"); 
end 
always@(Write_Done) begin 
// once the processing was done, bmp image will be created if(Write_Done == 1'b1) begin 
for(i=0; i
begin 
$fwrite(fd, "%c", BMP_header[i][7:0]); // write the header end for(i=0; i
begin 
// write R0B0G0 and R1B1G1 (6 bytes) in a loop 
$fwrite(fd, "%c", out_BMP[i ][7:0]); 
$fwrite(fd, "%c", out_BMP[i+1][7:0]); 
$fwrite(fd, "%c", out_BMP[i+2][7:0]); 
$fwrite(fd, "%c", out_BMP[i+3][7:0]); 
$fwrite(fd, "%c", out_BMP[i+4][7:0]); 
$fwrite(fd, "%c", out_BMP[i+5][7:0]); 
end
end 
end

The header data for bitmap image is very important and it is published here. If there is no header data, the written image could not be correctly displayed. In Verilog HDL, $fwrite command is used to write data to file.

Here we go, now writing testbench to verify the code:

`timescale 1ns/1ps /**************************************************/ 
/******* Testbench for simulation ****************/ /*********************************************/ 
`include "parameter.v" // include definition file module tb_simulation; 
//------------------ // Internal Signals 
//------------------------------------------------- 
reg HCLK, HRESETn; 
wire vsync; 
wire hsync;
 // fpga4student.com FPGA projects, Verilog projects, VHDL projects
wire [ 7 : 0] data_R0; 
wire [ 7 : 0] data_G0; 
wire [ 7 : 0] data_B0; 
wire [ 7 : 0] data_R1; 
wire [ 7 : 0] data_G1; 
wire [ 7 : 0] data_B1; 
wire enc_done; 
image_read #(.INFILE(`INPUTFILENAME)) 
u_image_read 
( .HCLK (HCLK ), 
.HRESETn (HRESETn ),
 .VSYNC (vsync ), 
.HSYNC (hsync ), 
.DATA_R0 (data_R0 ),
 .DATA_G0 (data_G0 ), 
.DATA_B0 (data_B0 ), 
.DATA_R1 (data_R1 ), 
.DATA_G1 (data_G1 ), 
.DATA_B1 (data_B1 ), 
.ctrl_done (enc_done) 
); 
image_write #(.INFILE(`OUTPUTFILENAME)) 
u_image_write ( 
.HCLK(HCLK), 
.HRESETn(HRESETn),
 .hsync(hsync), 
.DATA_WRITE_R0(data_R0),
 .DATA_WRITE_G0(data_G0),
 .DATA_WRITE_B0(data_B0), 
.DATA_WRITE_R1(data_R1), 
.DATA_WRITE_G1(data_G1), 
.DATA_WRITE_B1(data_B1),
 .Write_Done()
 ); 
//------------- // Test Vectors 
//------------------------------------- 
initial 
begin 
HCLK = 0; 
forever #10 HCLK = ~HCLK; 
end 
initial 
begin 
HRESETn = 0; 
#25 HRESETn = 1; 
end endmodule


Now, we have everything to run simulation to verify the code. Let me pick the following image as the input bitmap file:


image processing on FPGA verilog

Input bitmap image

And this is the output image being processed by the operations:

image processing on FPGA verilog

Output bitmap image after inverting


image processing on FPGA verilog

Output bitmap image after threshold operation



image processing on FPGA verilog

Output bitmap image after subtracting brightness

For full Verilog source code, please comment below or contact via email.

You might also like this:
VHDL code for D Flip Flop
Verilog code for D Flip Flop
Verilog code for a comparator
Verilog code for FIFO memory
VHDL code for FIFO memory

45 comments:

  1. Hi Van,

    My name is Jewel. I'm from India doing B.tech in Manipal University Your code on image processing using verilog HDL was really helpful. I'm doing a project called JPEG encoder using verilog HDL for grayscale image. Can u please help me with a code for this topic?

    Regards,
    JEWEL DOMINIC SAVIO ANTONY

    ReplyDelete
  2. Replies
    1. Thanks. Please keep update the blog: https://fpga4student.blogspot.com

      Delete
  3. Replies
    1. Thanks. Please keep update the blog: https://fpga4student.blogspot.com

      Delete
  4. baydarbasar@yahoo.com

    ReplyDelete
    Replies
    1. Emailed you. Kindly keep up to date with FPGA projects using Verilog/ VHDL fpga4student.com. Thanks

      Delete
  5. Replies
    1. You are welcome. Please help to like and share the site with your friends: https://www.facebook.com/fpga4student and keep updates with coming projects.Thanks.

      Delete
  6. Hello Van Loi Le, code is very useful. Thanks. Can you please send me full verilog source code

    ReplyDelete
    Replies
    1. Kindly keep up to date with FPGA projects using Verilog/ VHDL fpga4student.com. Thanks

      Delete
  7. Hello please share project my email: sylaslly@gmail.com

    ReplyDelete
    Replies
    1. Emailed you. Kindly keep up to date with FPGA projects using Verilog/ VHDL fpga4student.com. Thanks

      Delete
  8. Hi code is very useful please send me full code

    ReplyDelete
  9. my mail id is niranjanmehar445@gmail.com

    ReplyDelete
    Replies
    1. Emailed you. Kindly keep up to date with FPGA projects using Verilog/ VHDL fpga4student.com. Thanks

      Delete
  10. Can you please send me the full verilog source files? My mail id is gitalive@gmail.com. It'd be very useful for my project in image processing.

    ReplyDelete
  11. Can you please sned the full verilog source files. My email is cmonterrosad@gmail.com.

    ReplyDelete
  12. Hi,your code is very useful for me. please share project my email: adabi.1373@yahoo.com
    thank you.

    ReplyDelete
    Replies
    1. Emailed you. Kindly keep up to date with FPGA projects using Verilog/ VHDL fpga4student.com. Thanks

      Delete
    2. Hi,can you please share me the code freely since i can not pay for that. ill be so helpful if you are kind to do this.

      Delete
  13. hi...I find your code more useful in my project. . Can you please share me. . My email: annette307@gmail.com

    ReplyDelete
  14. Hello please share project my email:thinkalot812@gmail.com

    ReplyDelete
  15. Hi, my email id is : singhadiaashish@gmail.com , may you please email me the source code.

    ReplyDelete
  16. mail me code :heena09shaikh@gmail.com

    ReplyDelete
  17. vipul4336@gmail.com,thanks :)

    ReplyDelete
  18. could you please email me the code
    omersalim4901@gmail.com

    ReplyDelete
  19. Exquisite tutorial on image processing on FPGA using Verilog HDL. I thank you for sharing it. Color Correction Service plays a vital role in image manipulation.

    ReplyDelete
  20. can u please share this code ? my mail id is swarnah235@gmail.com .....
    thanks in advance.

    ReplyDelete
  21. cool!
    fasma@mailinator.com

    ReplyDelete
  22. Very helpful source. i need to load a video file in fpga. can you help me and procedure what i have to follow? thanks in advance.

    my mail id is: sivamanik.44@gmail.com

    ReplyDelete
  23. Sir,i have followed your blog since 2016 and currently i am doing a project on verilog to design a codec using wavelet transform algorithm,sir i require your help regarding this.Can you help me in completing my project?

    ReplyDelete
  24. nice post ! genwen.zhao@gmail.com

    ReplyDelete
  25. very good!! i would like to use your code. email anurung@gmail.com

    ReplyDelete
  26. Can you please send me the code @ sabarishprasanna@gmail.com

    ReplyDelete
  27. Can you mail the code to harshagopal1@gmail.com ?

    ReplyDelete
  28. Hello, I would greatly appreciate if you could share your code to darkinthewind@live.com
    Thank you!

    ReplyDelete
  29. please send us the full code and do we need zed-board for the processing the output? my email address is radha.rani9924@gmail.com. Thanks in advance...

    ReplyDelete
  30. Bravo sir. you have done a great job it will assist the new learners like me a lot. Sir can you plz share the code with me so i can practice it. sir please share the full code with me at my email address nasirkhanpak25@gmail.com
    Thanks in advance. Wish you best for luck.

    ReplyDelete