element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Summer of FPGA
  • Challenges & Projects
  • Design Challenges
  • Summer of FPGA
  • More
  • Cancel
Summer of FPGA
Blog Number Plate Recognition #4: Loading an Image to FPGA
  • Blog
  • Forum
  • Documents
  • Files
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: taifur
  • Date Created: 13 Jan 2022 1:21 PM Date Created
  • Views 3393 views
  • Likes 6 likes
  • Comments 1 comment
  • image processing
  • spartan 7
  • xilinx
  • summer of fpgas
  • verilog
  • summer of fpga
Related
Recommended

Number Plate Recognition #4: Loading an Image to FPGA

taifur
taifur
13 Jan 2022

Over the last few years, FPGAs have moved from glue logic to computing platforms. They effectively provide a reconfigurable hardware platform for implementing logic and algorithms. Being fine-grained hardware, FPGAs are able to exploit the parallelism inherent within a hardware design while at the same time maintaining the reconfigurability and programmability of software. This has led to FPGAs being used as a platform for accelerating computationally intensive tasks. This is particularly seen in the field of image processing, where the FPGA-based acceleration of imaging algorithms has become mainstream. 

Field programmable gate arrays (FPGAs) are increasingly being used for the implementation of image processing applications. This is especially the case for real-time embedded applications, where latency and power are important considerations. An FPGA embedded in a smart camera is able to perform much of the image processing directly as the image is streamed from the sensor, with the camera providing a processed output data stream, rather than a sequence of images. The parallelism of hardware is able to exploit the spatial (data level) and temporal (task level) parallelism implicit within many image processing tasks. Unfortunately, simply porting a software algorithm onto an FPGA often gives disappointing results, because many image processing algorithms have been optimized for a serial processor. It is usually necessary to transform the algorithm to efficiently exploit the parallelism and resources available on an FPGA.

Automatic Number plate recognition (ANPR) may be found useful in many applications ranging from applications such as monitoring parking lots to identifying speeding vehicles in expressways. The procedure of implementing such systems may be found tedious due to problems such as: maintaining a constant distance with the rear view of the vehicle, varying lighting conditions, or the number plate being obstructed by some other object or dirt. Although the above-mentioned factors make the task of isolating and recognizing a number plate tedious, the speed of processing is a great concern because character recognition in real-time is vital in such applications. This research is focused mainly on the prime requirement for an improved number plate recognition system - the speed of processing. Hence, this system is based on a Field Programmable Gate Array (FPGA). Also, the implemented ANPR system has the ability to recognize characters of the number plate even if it is slightly obscured. The proposed Methodology of this project involves extracting the number plate from a rearview image of a vehicle and processing it in a suitable manner to perform character recognition using a template matching technique. This system is implemented based on several assumptions such as; the number plate being exposed to constant lighting conditions and that the frame of the number plate is captured for processing at a constant distance from the camera. These assumptions were made so that more focus could be given to faster processing, character recognition, and other concerns when using image processing techniques in hardware descriptive languages.

image

image

Before processing an image we need to load the image to the FPGA but Verilog cannot read image directly. To read a .bmp image in Verilog, the image is required to be converted from bitmap format to the hexadecimal format. An image can be easily converted to hexadecimal/binary data using Matlab, C, Python, etc. Below is a Matlab example code to convert a bitmap image to a .hex file. The input image size is 768x512 and the .hex file includes R, G, B data of the bitmap image.  

For Verilog code, you can use $readmemh(for hexadecimal data) or $readmemb(for binary data) command to load a converted binary/hexadecimal text file directly. Example Verilog code for loading a text file or an image into FPGA using $readmemh.


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

k=1;
for i=512:-1:1 % image is written from the last row to the first row
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

To read the image hexadecimal data file, Verilog uses this command: $readmemh or $readmemb if the image data is in a binary text file. After reading the image .hex file, the RGB image data are saved into memory and read out for processing.

Below is the Verilog code to the image reading:

/******************************************************************************/
/******************  Module for reading image     **************/
/******************************************************************************/
`include "parameter.v"       // Include definition file

module image_read
#(
  parameter     WIDTH  = 768,   // Image width
         HEIGHT  = 512,   // Image height
  INFILE  = "./img/kodim01.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 operation
  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 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)
  // Process and transmit 2 pixels in parallel to make the process faster, you can modify to transmit 1 pixels or more if needed
  output     ctrl_done     // Done flag
);   
//-------------------------------------------------
// Internal Signals
//-------------------------------------------------
parameter sizeOfWidth = 8;   // data width
parameter sizeOfLengthReal = 1179648;   // image data : 1179648 bytes: 512 * 768 *3 
// local parameters for FSM
localparam  ST_IDLE  = 2'b00,// idle state
   ST_VSYNC = 2'b01,// state for creating vsync 
   ST_HSYNC = 2'b10,// state for creating hsync 
   ST_DATA  = 2'b11;// state for data processing 
reg [1:0] cstate,   // current state
nstate;    // next state   
reg start;         // start signal: trigger Finite state machine beginning to operate
reg HRESETn_d;   // delayed reset signal: use to create start signal
reg   ctrl_vsync_run; // control signal for vsync counter  
reg [8:0] ctrl_vsync_cnt; // counter for vsync
reg   ctrl_hsync_run; // control signal for hsync counter
reg [8:0] ctrl_hsync_cnt; // counter  for hsync
reg   ctrl_data_run; // control signal for data processing
reg [7 : 0]   total_memory [0 : sizeOfLengthReal-1];// memory to store  8-bit data image
// temporary memory to save image data : size will be WIDTH*HEIGHT*3
integer temp_BMP   [0 : WIDTH*HEIGHT*3 - 1];   
integer org_R  [0 : WIDTH*HEIGHT - 1];  // temporary storage for R component
integer org_G  [0 : WIDTH*HEIGHT - 1]; // temporary storage for G component
integer org_B  [0 : WIDTH*HEIGHT - 1]; // temporary storage for B component
// counting variables
integer i, j;
// temporary signals for calculation: details in the paper.
integer tempR0,tempR1,tempG0,tempG1,tempB0,tempB1; // temporary variables in contrast and brightness operation

integer value,value1,value2,value4;// temporary variables in invert and threshold operation
reg [ 9:0] row; // row index of the image
reg [10:0] col; // column index of the image
reg [18:0] data_count; // data counting for entire pixels of the image
//-------------------------------------------------//
// -------- 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<WIDTH*HEIGHT*3 ; i=i+1) begin
            temp_BMP[i] = total_memory[i+0][7:0]; 
        end
        
        for(i=0; i<HEIGHT; i=i+1) begin
            for(j=0; j<WIDTH; j=j+1) begin
     // Matlab code writes image from the last row to the first row
     // Verilog code does the same in reading to correctly save image pixels into 3 separate RGB mem
                org_R[WIDTH*i+j] = temp_BMP[WIDTH*3*(HEIGHT-i-1)+3*j+0]; // save Red component
                org_G[WIDTH*i+j] = temp_BMP[WIDTH*3*(HEIGHT-i-1)+3*j+1];// save Green component
                org_B[WIDTH*i+j] = temp_BMP[WIDTH*3*(HEIGHT-i-1)+3*j+2];// save Blue component
            end
        end
    end
end
//----------------------------------------------------//
// ---Begin to read image file once reset was high ---//
// ---by creating a starting pulse (start)------------//
//----------------------------------------------------//
always@(posedge HCLK, negedge HRESETn)
begin
    if(!HRESETn) begin
        start <= 0;
  HRESETn_d <= 0;
    end
    else begin           //          ______     
        HRESETn_d <= HRESETn;       //        |  |
  if(HRESETn == 1'b1 && HRESETn_d == 1'b0)  // __0___| 1 |___0____ : starting pulse
   start <= 1'b1;
  else
   start <= 1'b0;
    end
end
//-----------------------------------------------------------------------------------------------//
// Finite state machine for reading RGB888 data from memory and creating hsync and vsync pulses --//
//-----------------------------------------------------------------------------------------------//
always@(posedge HCLK, negedge HRESETn)
begin
    if(~HRESETn) begin
        cstate <= ST_IDLE;
    end
    else begin
        cstate <= nstate; // update next state 
    end
end
//-----------------------------------------//
//--------- State Transition --------------//
//-----------------------------------------//
// IDLE . VSYNC . HSYNC . DATA
always @(*) begin
 case(cstate)
  ST_IDLE: begin
   if(start)
    nstate = ST_VSYNC;
   else
    nstate = ST_IDLE;
  end   
  ST_VSYNC: begin
   if(ctrl_vsync_cnt == START_UP_DELAY) 
    nstate = ST_HSYNC;
   else
    nstate = ST_VSYNC;
  end
  ST_HSYNC: begin
   if(ctrl_hsync_cnt == HSYNC_DELAY) 
    nstate = ST_DATA;
   else
    nstate = ST_HSYNC;
  end  
  ST_DATA: begin
   if(ctrl_done)
    nstate = ST_IDLE;
   else begin
    if(col == WIDTH - 2)
     nstate = ST_HSYNC;
    else
     nstate = ST_DATA;
   end
  end
 endcase
end
// ------------------------------------------------------------------- //
// --- counting for time period of vsync, hsync, data processing ----  //
// ------------------------------------------------------------------- //
always @(*) begin
 ctrl_vsync_run = 0;
 ctrl_hsync_run = 0;
 ctrl_data_run  = 0;
 case(cstate)
  ST_VSYNC:  begin ctrl_vsync_run = 1; end  // trigger counting for vsync
  ST_HSYNC:  begin ctrl_hsync_run = 1; end // trigger counting for hsync
  ST_DATA:  begin ctrl_data_run  = 1; end // trigger counting for data processing
 endcase
end
// counters for vsync, hsync
always@(posedge HCLK, negedge HRESETn)
begin
    if(~HRESETn) begin
        ctrl_vsync_cnt <= 0;
  ctrl_hsync_cnt <= 0;
    end
    else begin
        if(ctrl_vsync_run)
   ctrl_vsync_cnt <= ctrl_vsync_cnt + 1; // counting for vsync
  else 
   ctrl_vsync_cnt <= 0;
   
        if(ctrl_hsync_run)
   ctrl_hsync_cnt <= ctrl_hsync_cnt + 1; // counting for hsync  
  else
   ctrl_hsync_cnt <= 0;
    end
end
// counting column and row index  for reading memory 
always@(posedge HCLK, negedge HRESETn)
begin
    if(~HRESETn) begin
        row <= 0;
  col <= 0;
    end
 else begin
  if(ctrl_data_run) begin
   if(col == WIDTH - 2) begin
    row <= row + 1;
   end
   if(col == WIDTH - 2) 
    col <= 0;
   else 
    col <= col + 2; // reading 2 pixels in parallel
  end
 end
end
//-------------------------------------------------//
//----------------Data counting---------- ---------//
//-------------------------------------------------//
always@(posedge HCLK, negedge HRESETn)
begin
    if(~HRESETn) begin
        data_count <= 0;
    end
    else begin
        if(ctrl_data_run)
   data_count <= data_count + 1;
    end
end
assign VSYNC = ctrl_vsync_run;
assign ctrl_done = (data_count == 196607)? 1'b1: 1'b0; // done flag

  • Sign in to reply
  • aditik
    aditik over 2 years ago

    Hi,

    Can you please share parameter.v file with us?

    it will be very helpful for me 

    thank you

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube