[punctual atom FPGA serial] Chapter 52 binarization experiment based on OV5640 camera - extracted from the FPGA Development Guide _V2.1 of the new starting point of punctual atom

Posted by Fehnris on Tue, 04 Jan 2022 08:17:36 +0100

Chapter 52 binarization experiment based on OV5640 camera

In digital image processing, binary image plays a very important role. The binarization of image greatly reduces the amount of data in the image and highlights the contour of the target. Image binarization is widely used in computer vision, image segmentation and artificial intelligence. In this chapter, the binarization experiment based on OV5640 will be carried out.
This chapter includes the following parts:
51.1 introduction
51.2 experimental tasks
51.3 hardware design
51.4 programming
51.5 download verification

52.1 introduction
Image Binarization is the process of setting the gray value of pixels on the image to the maximum (white) or minimum (black), that is, the whole image presents an obvious black-and-white effect. Here, take the gray image represented by 8bit as an example (the range of gray value is 0 ~ 255). Binarization is to select an appropriate threshold and compare it with 256 brightness levels in the image. The pixels with brightness higher than the threshold are set as white (255), and the pixels lower than the threshold are set as black (0), so as to clearly reflect the overall and local characteristics of the image.
In digital image processing, binary image plays a very important role, especially in real-time image processing, there are many systems composed of binary image. To process and analyze the binary image, we must first binarize the gray image to obtain the binary image, which is conducive to the further processing of the image. The set property of the image is only related to the position of the point with the pixel value of 0 or 255, and does not involve the multi-level value of the pixel, making the processing simple. In order to obtain an ideal binary image, closed and connected boundaries are generally used to define non overlapping regions. All pixels with grayscale greater than or equal to the threshold are determined to belong to a specific object, and their grayscale value is represented by 255. Otherwise, these pixels are excluded from the object area, and the grayscale value is 0, indicating the background or exceptional object area.
There are two methods to realize binarization. One is to manually specify a threshold and binarize through the threshold; The other is an adaptive threshold binarization method (OTSU algorithm, Kittle algorithm, etc.). The first method has a small amount of calculation and high speed, but the color distribution varies greatly when processing different images; the second method has strong applicability and can directly observe the image contour, but the calculation is relatively more complex. The experiment in this chapter will use the first method to realize the binarization of images.
If a specific object has uniform gray values in the interior, and it is in a uniform background with other gray values, using the method of threshold can get more effective segmentation results. If the difference between the object and the background is not reflected in the gray value (such as different texture), the difference feature can be converted into the gray difference, and then the threshold selection technology can be used to segment the image.
52.2 experimental tasks
The experimental task of this section is to use OV5640 camera to collect RGB565 data on the new starting point development board, convert the data into YCbCr format, then conduct median filtering, and finally binarize the gray value and display it through HDMI.
52.3 hardware design
The hardware design in this chapter is exactly the same as "OV5640 camera HDMI display experiment", which will not be repeated here.
52.4 program design
According to the experimental task, the first design is shown in Figure 52.4 1. The system framework of the experiment in this chapter continues the overall architecture of "OV5640 camera HDMI gray display experiment". This experiment includes the following modules: clock module, SDRAM controller module, IIC driver module, IIC configuration module, camera acquisition module, image processing module and HDMI top-level module. The clock module, SDRAM controller module, IIC driver module, IIC configuration module, camera acquisition module and HDMI top-level module have not been modified in this experiment. These modules have been described in "OV5640 camera HDMI display experiment", which will not be detailed here. This experiment only modifies the image processing module.
The block diagram of OV5640 binarization experiment system is shown in the following figure:

Figure 52.4 1 top level system block diagram
As can be seen from the above figure, Clock module (PLL and pll_hdmi) provide drive clock for HDMI top-level module, SDRAM control module and IIC drive module. IIC drive module and IIC configuration module control the beginning and end of sensor initialization. After sensor initialization, the collected data is written into camera acquisition module. After processing by camera acquisition module, the data is written into image processing module and image processing module The block processes the camera data and stores it into the SDRAM control module. The top-level module reads the data from the SDRAM control module and drives the display. At this time, the whole system completes the data acquisition, cache and display. It should be noted that the image data acquisition module starts to output data after the initialization of SDRAM and sensor, so as to avoid writing data to it during the initialization of SDRAM.
The top-level module code is as follows:

1   module ov5640_hdmi_img_binarization(    
2       input         sys_clk    ,  //System clock
3       input         sys_rst_n  ,  //System reset, low level active
4       //camera 
5       input         cam_pclk   ,  //cmos data pixel clock
6       input         cam_vsync  ,  //cmos field synchronization signal
7       input         cam_href   ,  //cmos line synchronization signal
8       input  [7:0]  cam_data   ,  //cmos data  
9       output        cam_rst_n  ,  //cmos reset signal, active at low level
10      output        cam_pwdn   ,  //cmos power sleep mode selection signal
11      output        cam_scl    ,  //cmos SCCB_SCL line
12      inout         cam_sda    ,  //cmos SCCB_SDA line
13      //SDRAM 
14      output        sdram_clk  ,  //SDRAM clock
15      output        sdram_cke  ,  //SDRAM clock valid
16      output        sdram_cs_n ,  //SDRAM chip selection
17      output        sdram_ras_n,  //SDRAM line valid
18      output        sdram_cas_n,  //SDRAM column valid
19      output        sdram_we_n ,  //SDRAM write valid
20      output [1:0]  sdram_ba   ,  //SDRAM Bank address
21      output [1:0]  sdram_dqm  ,  //SDRAM data mask
22      output [12:0] sdram_addr ,  //SDRAM address
23      inout  [15:0] sdram_data ,  //SDRAM data    
24      //HDMI interface
25      output        tmds_clk_p,   // TMDS clock channel
26      output        tmds_clk_n,
27      output [2:0]  tmds_data_p,  // TMDS data channel
28      output [2:0]  tmds_data_n
29      );
30  
31  //parameter define
32  parameter SLAVE_ADDR    = 7'h3c          ; //Device address 7'h3c of OV5640
33  parameter BIT_CTRL      = 1'b1           ; //The byte address of OV5640 is 16 bits 0:8 bits 1:16 bits
34  parameter CLK_FREQ      = 27'd50_000_000 ; //i2c_ Drive clock frequency of DRI module 
35  parameter I2C_FREQ      = 18'd250_000    ; //SCL clock frequency of I2C, not exceeding 400KHz
36  parameter V_CMOS_DISP   = 11'd800        ; //CMOS resolution - row
37  parameter H_CMOS_DISP   = 11'd1280       ; //CMOS resolution - columns 
38  parameter TOTAL_H_PIXEL = 13'd2570       ; //CMOS resolution - row
39  parameter TOTAL_V_PIXEL = 13'd980        ;
40  
41  //wire define
42  wire        clk_100m           ;  //100mhz clock, SDRAM operation clock
43  wire        clk_100m_shift     ;  //100mhz clock, SDRAM phase offset clock
44  wire        clk_50m            ;
45  wire        hdmi_clk           ;  
46  wire        hdmi_clk_5         ;  
47  wire        locked             ;
48  wire        locked_hdmi        ;
49  wire        rst_n              ;
50  wire        sys_init_done      ;  //System initialization completed (sdram initialization + camera initialization)
51  wire        i2c_exec           ;  //I2C trigger execution signal
52  wire [23:0] i2c_data           ;  //I2C address and data to be configured (high 8-bit address and low 8-bit data)          
53  wire        i2c_done           ;  //I2C register configuration completion signal
54  wire        i2c_dri_clk        ;  //I2C operation clock
55  wire [ 7:0] i2c_data_r         ;  //Data read out by I2C
56  wire        i2c_rh_wl          ;  //I2C read / write control signal
57  wire        cam_init_done      ;  //Camera initialization complete                         
58  wire        wr_en              ;  //sdram_ctrl module write enable
59  wire [15:0] wr_data            ;  //sdram_ctrl module writes data
60  wire        rd_en              ;  //sdram_ctrl module read enable
61  wire [15:0] rd_data            ;  //sdram_ctrl module reads data
62  wire        sdram_init_done    ;  //SDRAM initialization completed
63  wire [10:0] pixel_xpos_w       ;  //HDMI abscissa
64  wire [10:0] pixel_ypos_w       ;  //HDMI ordinate
65  wire        post_frame_vsync   ;  //Processed field signal
66  wire        post_frame_hsync   ;  //Processed line signal
67  wire        post_frame_de      ;  //Processed data enable  
68  wire [15:0] post_rgb           ;  //Processed data 
69  
70  //*****************************************************
71  //**                    main code
72  //*****************************************************
73  
74  assign  rst_n = sys_rst_n & locked & locked_hdmi;
75  //System initialization completed: SDRAM and camera are initialized
76  //It avoids writing data to SDRAM during SDRAM initialization
77  assign  sys_init_done = sdram_init_done & cam_init_done;
78  //Power sleep mode selection 0: normal mode 1: power sleep mode
79  assign  cam_pwdn  = 1'b0;
80  assign  cam_rst_n = 1'b1;
81  
82  //Phase locked loop
83  pll u_pll(
84      .areset             (~sys_rst_n),
85      .inclk0             (sys_clk),            
86      .c0                 (clk_100m),
87      .c1                 (clk_100m_shift),  
88      .c2                 (clk_50m),   
89      .locked             (locked)
90      );
91  
92  pll_hdmi    pll_hdmi_inst (
93      .areset             ( ~sys_rst_n  ),
94      .inclk0             ( sys_clk     ),
95      .c0                 ( hdmi_clk    ),//hdmi pixel clock 71Mhz
96      .c1                 ( hdmi_clk_5  ),//hdmi pixel clock*5 355Mhz
97      .locked             ( locked_hdmi )
98      );
99       
100 //I2C configuration module
101 i2c_ov5640_rgb565_cfg u_i2c_cfg(
102     .clk                (i2c_dri_clk),
103     .rst_n              (rst_n      ),
104             
105     .i2c_exec           (i2c_exec   ),
106     .i2c_data           (i2c_data   ),
107     .i2c_rh_wl          (i2c_rh_wl  ),      //I2C read / write control signal
108     .i2c_done           (i2c_done   ), 
109     .i2c_data_r         (i2c_data_r ),   
110                 
111     .cmos_h_pixel       (H_CMOS_DISP  ),    //Number of CMOS horizontal pixels
112     .cmos_v_pixel       (V_CMOS_DISP  ) ,   //Number of CMOS vertical pixels
113     .total_h_pixel      (TOTAL_H_PIXEL),    //Total horizontal pixel size
114     .total_v_pixel      (TOTAL_V_PIXEL),    //Total vertical pixel size
115         
116     .init_done          (cam_init_done) 
117     );    
118 
119 //I2C drive module
120 i2c_dri #(
121     .SLAVE_ADDR         (SLAVE_ADDR    ),    //Parameter transfer
122     .CLK_FREQ           (CLK_FREQ      ),              
123     .I2C_FREQ           (I2C_FREQ      ) 
124     )
125 u_i2c_dr(
126     .clk                (clk_50m       ),
127     .rst_n              (rst_n         ),
128 
129     .i2c_exec           (i2c_exec      ),   
130     .bit_ctrl           (BIT_CTRL      ),   
131     .i2c_rh_wl          (i2c_rh_wl     ),     //Fixed to 0, only IIC driven write operations are used   
132     .i2c_addr           (i2c_data[23:8]),   
133     .i2c_data_w         (i2c_data[7:0] ),   
134     .i2c_data_r         (i2c_data_r    ),   
135     .i2c_done           (i2c_done      ),    
136     .scl                (cam_scl       ),   
137     .sda                (cam_sda       ),
138     .dri_clk            (i2c_dri_clk   )       //I2C operation clock
139     );
140 
141 //CMOS image data acquisition module
142 cmos_capture_data u_cmos_capture_data(         //Data collection can be started after system initialization 
143     .rst_n              (rst_n & sys_init_done),
144     
145     .cam_pclk           (cam_pclk ),
146     .cam_vsync          (cam_vsync),
147     .cam_href           (cam_href ),
148     .cam_data           (cam_data ),         
149     
150     .cmos_frame_vsync   (cmos_frame_vsync),
151     .cmos_frame_href    (cmos_frame_href),
152     .cmos_frame_valid   (wr_en    ),      //Data valid enable signal
153     .cmos_frame_data    (wr_data  )       //Valid data 
154     );
155      
156  //Image processing module
157 vip u_vip(
158     //module clock
159     .clk              (cam_pclk),           // clock signal
160     .rst_n            (rst_n    ),          // Reset signal (low active)
161     //Data interface before image processing
162     .pre_frame_vsync  (cmos_frame_vsync   ),
163     .pre_frame_hsync  (cmos_frame_href   ),
164     .pre_frame_de     (wr_en   ),
165     .pre_rgb          (wr_data),
166     .xpos             (pixel_xpos_w   ),
167     .ypos             (pixel_ypos_w   ),
168     //Data interface after image processing
169     .post_frame_vsync (post_frame_vsync ),  // Field synchronization signal
170     .post_frame_hsync ( ),                  // Line synchronization signal
171     .post_frame_de    (post_frame_de ),     // Data input enable
172     .post_rgb         (post_rgb)            // RGB565 color data
173 
174 );   
175 
176 //The top-level module of SDRAM controller is encapsulated into FIFO interface
177 //SDRAM controller address composition: {bank_addr[1:0], row_addr[12:0], col_addr[8:0]}
178 sdram_top u_sdram_top(
179     .ref_clk            (clk_100m),         //sdram controller reference clock
180     .out_clk            (clk_100m_shift),   //Phase offset clock for output
181     .rst_n              (rst_n),            //System reset
182                                             
183     //User write port                              
184     .wr_clk             (cam_pclk),         //Write port FIFO: write clock
185     .wr_en              (post_frame_de),    //Write port FIFO: write enable
186     .wr_data            (post_rgb),         //Write port FIFO: write data   
187      
188     .wr_min_addr        (24'd0),            //Write the starting address of SDRAM
189     .wr_max_addr        (V_CMOS_DISP*H_CMOS_DISP-1),   //Write end address of SDRAM
190     .wr_len             (10'd512),          //Data burst length when writing SDRAM
191     .wr_load            (~rst_n),           //Write port reset: reset the write address and clear the write FIFO
192                                             
193     //User read port                              
194     .rd_clk             (hdmi_clk),         //Read port FIFO: read clock
195     .rd_en              (rd_en),            //Read port FIFO: read enable
196     .rd_data            (rd_data),          //Read port FIFO: read data
197     .rd_min_addr        (24'd0),            //Read the starting address of SDRAM
198     .rd_max_addr        (V_CMOS_DISP*H_CMOS_DISP-1),   //End address of reading SDRAM
199     .rd_len             (10'd512),          //Burst length when reading data from SDRAM
200     .rd_load            (~rst_n),           //Read port reset: reset the read address and clear the read FIFO
201                                                 
202     //User control port                                
203     .sdram_read_valid   (1'b1),             //SDRAM read enable
204     .sdram_pingpang_en  (1'b1),             //SDRAM ping pong operation enable
205     .sdram_init_done    (sdram_init_done),  //SDRAM initialization completion flag
206                                             
207     //SDRAM chip interface                                
208     .sdram_clk          (sdram_clk),        //SDRAM chip clock
209     .sdram_cke          (sdram_cke),        //SDRAM clock valid
210     .sdram_cs_n         (sdram_cs_n),       //SDRAM chip selection
211     .sdram_ras_n        (sdram_ras_n),      //SDRAM line valid
212     .sdram_cas_n        (sdram_cas_n),      //SDRAM column valid
213     .sdram_we_n         (sdram_we_n),       //SDRAM write valid
214     .sdram_ba           (sdram_ba),         //SDRAM Bank address
215     .sdram_addr         (sdram_addr),       //SDRAM row / column address
216     .sdram_data         (sdram_data),       //SDRAM data
217     .sdram_dqm          (sdram_dqm)         //SDRAM data mask
218     );
219 
220 //Instantiated HDMI top-level module
221 hdmi_top u_hdmi_top(
222     .hdmi_clk       (hdmi_clk   ),
223     .hdmi_clk_5     (hdmi_clk_5 ),
224     .rst_n          (rst_n      ),
225                 
226     .rd_data        (rd_data    ),
227     .rd_en          (rd_en      ), 
228     .h_disp         (),  
229     .v_disp         (),
230     .pixel_xpos     (pixel_xpos_w),
231     .pixel_ypos     (pixel_ypos_w),
232     .video_vs       (),  
233     .tmds_clk_p     (tmds_clk_p ),
234     .tmds_clk_n     (tmds_clk_n ),
235     .tmds_data_p    (tmds_data_p),
236     .tmds_data_n    (tmds_data_n)
237     );   
238 
239 endmodule 

The FPGA top-level module (ov5640_hdmi_img_binarization) instantiates the following eight modules: clock module 1 (PLL), clock module 2 (pll_hdmi), I2C driver module (i2c_dri), I2C configuration module (i2c_ov5640_rgb565_cfg), image capture_data, image processing module (vip), SDRAM control module (sdram_top) and HDMI top-level module (hdmi_top).
Clock module: the clock module is realized by calling PLL IP core, and outputs 5 clocks in total. The frequencies are 100M clock, 100M offset - 75 degree clock, 50M clock 71Mhz clock and 355M clock (5 times the frequency of HDMI pixel clock). pll generates 50M clock, 100M clock and 100M offset - 75 degree clock. pll_hdmi generates 71Mhz clock and 355M clock. Here, two PLLs are used because 71Mhz clock used by HDMI is not an integral multiple of 100M clock used by SDRAM control module. Using one pll does not meet the design requirements. 100Mhz clock is used as SDRAM control module Block drive clock, 100M offset - 75 degree clock is used to output to external SDRAM chip, 50Mhz clock is used as the drive clock of I2C drive module, and 71Mhz clock and 355M clock (5x of HDMI pixel clock) are responsible for driving HDMI top-level module.
I2C driver module (i2c_dri): I2C driver module is responsible for driving the OV5640 SCCB interface bus. Users can easily configure the registers of OV5640 according to the user interface provided by the module. This module is the same module as the I2C driver module used in the chapter "EEPROM read-write experiment". Please refer to "EEPROM read-write experiment" for details of this module Chapter.
I2C configuration module (i2c_ov5640_rgb565_cfg): the drive clock of the I2C configuration module is provided by the clock output by the I2C drive module, which facilitates the data interaction between the I2C drive module and the I2C configuration module. The module registers the register address and data to be configured and controls the beginning and end of initialization. At the same time, the module outputs the register address and data of OV5640 and controls the I2C drive The control signal started by the drive module is directly connected to the user interface of the I2C drive module to complete the initialization of the OV5640 sensor.
cmos_capture_data: driven by the pixel clock, the camera acquisition module converts the field synchronization signal, line synchronization signal and 8-bit data output by the sensor into write enable signal and 16 bit write data signal to complete the image acquisition of OV5640 sensor. The image output timing of OV5640 and OV7725 is very similar. Please refer to the detailed introduction of this module "OV7725 camera LCD display experiment" chapter.
Image processing module (vip): process the collected image data and store the processed data into SDRAM control module.
SDRAM control module (sdram_top): the SDRAM read / write controller module is responsible for driving the SDRAM off chip memory and caching the image data output by the image sensor. For a detailed introduction of this module, please refer to the chapter "SDRAM read / write test experiment".
hdmi_top module: the HDMI top module is responsible for driving the output of the driving signal of the HDMI display, and providing display parameters, field synchronization signal and data request signal for other modules. For the detailed introduction of the HDMI top module, please refer to the chapter "OV5640 camera HDMI display experiment".
vip module block diagram is shown in the figure below:

Figure 52.4 2 VIP module block diagram
The VIP module exemplifies the RGB to YCbCr module (rgb2ycbcr), the median filter module (vip_gray_median_jilter) and the binarization module (binarization). The RGB to YCbCr module is responsible for converting the RGB565 format data collected by the camera to the data converted to YUV format. The median filter module is responsible for outputting the video image in YUV format after median filtering. The binarization module is responsible for binarization and outputting the video image after median filtering. Please refer to the detailed introduction of RGB to YCbCr module "OV5640 camera HDMI grayscale display experiment" chapter. For the detailed introduction of the median filtering module, please refer to the chapter "median filtering experiment based on OV5640".
The schematic diagram of vip module is shown in the figure below:

Figure 52.4 3 Schematic diagram of VIP module
As shown in the figure above, the camera collects 16 bit rgb565 input VIP module and converts it into 8-bit yuv444 data through the "rgb2ycbcr" module, Then, take the converted gray data (img_y) as the input of "vip_gray_median_filter" module, carry out median filtering on the gray, then input the median filtered data into the binarization module, carry out binarization on the data, and finally output the binarization processed gray data "monoc".
The image processing module is responsible for the format conversion of image data, and the code is as follows:

1  module vip(
2      //module clock
3      input           clk            ,   // clock signal
4      input           rst_n          ,   // Reset signal (low active)
5  
6      //Data interface before image processing
7      input           pre_frame_vsync,   
8      input           pre_frame_hsync,
9      input           pre_frame_de   ,
10     input    [15:0] pre_rgb        ,
11     input    [10:0] xpos           ,
12     input    [10:0] ypos           ,
13 
14     //Data interface after image processing
15     output          post_frame_vsync,  // Field synchronization signal
16     output          post_frame_hsync,  // Line synchronization signal
17     output          post_frame_de   ,  // Data input enable
18     output   [15:0] post_rgb           // RGB565 color data
19 
20 );
21 
22 //wire define
23 wire   [ 7:0]         img_y;
24 wire   [ 7:0]         post_img_y;
25 wire                  pe_frame_vsync;
26 wire                  pe_frame_href;
27 wire                  pe_frame_clken;
28 wire                  ycbcr_vsync;
29 wire                  ycbcr_hsync;
30 wire                  ycbcr_de;
31 wire                  monoc;
32 
33 //*****************************************************
34 //**                    main code
35 //*****************************************************
36 
37 assign  post_rgb = {16{monoc}};
38 
39 //RGB to YCbCr module
40 rgb2ycbcr u_rgb2ycbcr(
41     //module clock
42     .clk             (clk    ),            // clock signal
43     .rst_n           (rst_n  ),            // Reset signal (low active)
44     //Data interface before image processing
45     .pre_frame_vsync (pre_frame_vsync),    // vsync signal
46     .pre_frame_hsync (pre_frame_hsync),    // href signal
47     .pre_frame_de    (pre_frame_de   ),    // data enable signal
48     .img_red         (pre_rgb[15:11] ),
49     .img_green       (pre_rgb[10:5 ] ),
50     .img_blue        (pre_rgb[ 4:0 ] ),
51     //Data interface after image processing
52     .post_frame_vsync(pe_frame_vsync),     // vsync signal
53     .post_frame_hsync(pe_frame_href),      // href signal
54     .post_frame_de   (pe_frame_clken),     // data enable signal
55     .img_y           (img_y),              //Gray data
56     .img_cb          (),
57     .img_cr          ()
58 );
59 
60 //Gray image median filtering
61 vip_gray_median_filter u_vip_gray_median_filter(
62     .clk    (clk),   
63     .rst_n  (rst_n), 
64     
65     //Preprocessing image data
66     .pe_frame_vsync (pe_frame_vsync),      // vsync signal
67     .pe_frame_href  (pe_frame_href),       // href signal
68     .pe_frame_clken (pe_frame_clken),      // data enable signal
69     .pe_img_y       (img_y),               
70                                            
71     //Processed image data                     
72     .pos_frame_vsync (ycbcr_vsync),        // vsync signal
73     .pos_frame_href  (ycbcr_hsync),        // href signal
74     .pos_frame_clken (ycbcr_de),           // data enable signal
75     .pos_img_y       (post_img_y)          //Gray data after median filtering
76 );
77 
78 //Binary module
79 binarization  u_binarization(
80     .clk         (clk),
81     .rst_n       (rst_n),
82     //Data interface before image processing     
83     .ycbcr_vsync (ycbcr_vsync),
84     .ycbcr_hsync (ycbcr_hsync),
85     .ycbcr_de    (ycbcr_de),
86     .luminance   (post_img_y),
87     //Data interface after image processing     
88     .post_vsync  (post_frame_vsync),
89     .post_hsync  (post_frame_hsync),
90     .post_de     (post_frame_de),
91     .monoc       (monoc)                   //Binary data
92 );
93 
94 endmodule

The 37th line of the code indicates bit splicing of the binarized 1-bit gray data to form a 16 bit RGB565 format data output.
Lines 40 to 58 of the code are examples of the gray-scale conversion module. In this module, the 16 bit RGB565 red, green and blue primary color data collected by the camera is used as the input data, the conversion from RGB to YCbCr is realized through the algorithm, the 8-bit gray-scale data is output, and the data output enable signal is output. For the detailed introduction of RGB to YCbCr module, please refer to the chapter "OV5640 camera HDMI gray display experiment".
Lines 61 to 76 of the code are examples of the median filter module, which is responsible for outputting the video image in YUV format after median filtering. For the detailed introduction of the median filtering module, please refer to the chapter "median filtering experiment based on OV5640".
Lines 83 to 96 of the code are examples of the binarization module, which divides the image into black and white according to the set threshold.
The median filter module and gray conversion module have been explained in the previous chapters, and this experiment will not be described. This experiment focuses on the binary module. The following is the code of the binary module.

1  module binarization(
2      //module clock
3      input               clk             ,   // clock signal
4      input               rst_n           ,   // Reset signal (low active)
5  
6      //Data interface before image processing
7      input               ycbcr_vsync     ,   // vsync signal
8      input               ycbcr_hsync     ,   // hsync signal
9      input               ycbcr_de        ,   // data enable signal
10     input   [7:0]       luminance       ,
11 
12     //Data interface after image processing
13     output              post_vsync      ,   // vsync signal
14     output              post_hsync      ,   // hsync signal
15     output              post_de         ,   // data enable signal
16     output   reg        monoc               // monochrome (1 = white, 0 = black)
17 );
18 
19 //reg define
20 reg    ycbcr_vsync_d;
21 reg    ycbcr_hsync_d;
22 reg    ycbcr_de_d   ;
23 
24 //*****************************************************
25 //**                    main code
26 //*****************************************************
27 
28 assign  post_vsync = ycbcr_vsync_d  ;
29 assign  post_hsync = ycbcr_hsync_d  ;
30 assign  post_de    = ycbcr_de_d     ;
31 
32 //Binarization
33 always @(posedge clk or negedge rst_n) begin
34     if(!rst_n)
35         monoc <= 1'b0;
36     else if(luminance > 8'd64)  //threshold
37         monoc <= 1'b1;
38     else
39         monoc <= 1'b0;
40 end
41 
42 //Delay 1 beat to synchronize clock signal
43 always@(posedge clk or negedge rst_n) begin
44     if(!rst_n) begin
45         ycbcr_vsync_d <= 1'd0;
46         ycbcr_hsync_d <= 1'd0;
47         ycbcr_de_d    <= 1'd0;
48     end
49     else begin
50         ycbcr_vsync_d <= ycbcr_vsync;
51         ycbcr_hsync_d <= ycbcr_hsync;
52         ycbcr_de_d    <= ycbcr_de   ;
53     end
54 end
55 
56 endmodule 

The main principle of binarization is to give a set threshold and compare the gray value with the threshold. If the gray value is greater than the threshold, monoc is 1. If it is less than the threshold, monoc is 0, as shown in lines 33 to 40 of the code. Theoretically, the threshold can be any value from 0 to 255, but if the threshold is too large, the excess part will be extracted; If the threshold is too small, the required part will be lost, so threshold selection is a very important step.
In lines 43 to 54 of the code, gray is checked by the register operation_ vsync,gray_clken and other signals are delayed by one clock cycle. This is because a clock is consumed during binary determination, so the corresponding synchronization signal also needs to be delayed by one clock cycle to realize synchronization with the data.
52.5 download verification
After compiling the project, you can start downloading the program. Plug the OV5640 camera module into the "OLED/CAMERA" socket on the new starting point development board, and connect one end of the HDMI cable to the HDMI socket on the development board and the other end to the display. Connect one end of the downloader to the computer and the other end to the JTAG port on the development board. Connect the power cord and turn on the power switch. Next, we download the program and observe the binarized pattern displayed on the HDMI display after downloading. As shown in the figure below:

Figure 52.5 1hdmi real-time display of binary image

Topics: Computer Vision image processing