Image scaling example with DISCO_F746NG board and STM32F4DIS-CAM Camera module.

Dependencies:   mbed LCD_DISCO_F746NG BSP_DISCO_F746NG

Committer:
kashgarim
Date:
Sat Feb 01 18:49:12 2020 +0000
Revision:
0:ce3028d3b22a
This implements the image scaling example on DISCO_F746NG board.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kashgarim 0:ce3028d3b22a 1
kashgarim 0:ce3028d3b22a 2 #include "mbed.h"
kashgarim 0:ce3028d3b22a 3 #include "stm32746g_discovery_camera.h"
kashgarim 0:ce3028d3b22a 4 #include "LCD_DISCO_F746NG.h"
kashgarim 0:ce3028d3b22a 5 #include "stm32f7xx_hal_dcmi.h"
kashgarim 0:ce3028d3b22a 6
kashgarim 0:ce3028d3b22a 7 extern "C" {
kashgarim 0:ce3028d3b22a 8 //defined in stm32746g_discovery_camera.c
kashgarim 0:ce3028d3b22a 9 extern DCMI_HandleTypeDef hDcmiHandler;
kashgarim 0:ce3028d3b22a 10 //void DCMI_IRQHandler(void) {
kashgarim 0:ce3028d3b22a 11 // HAL_DCMI_IRQHandler(&hDcmiHandler);
kashgarim 0:ce3028d3b22a 12 //}
kashgarim 0:ce3028d3b22a 13 //void DMA2_Stream1_IRQHandler(void) {
kashgarim 0:ce3028d3b22a 14 // HAL_DMA_IRQHandler(hDcmiHandler.DMA_Handle);
kashgarim 0:ce3028d3b22a 15 //}
kashgarim 0:ce3028d3b22a 16 }
kashgarim 0:ce3028d3b22a 17
kashgarim 0:ce3028d3b22a 18 // 2 input channels, as input is in RGB565 format
kashgarim 0:ce3028d3b22a 19 #define NUM_IN_CH 2
kashgarim 0:ce3028d3b22a 20 #define NUM_OUT_CH 3
kashgarim 0:ce3028d3b22a 21 #define IMG_WIDTH 160
kashgarim 0:ce3028d3b22a 22 #define IMG_HEIGHT 120
kashgarim 0:ce3028d3b22a 23 #define CNN_IMG_SIZE 32
kashgarim 0:ce3028d3b22a 24 #define resolution RESOLUTION_R160x120
kashgarim 0:ce3028d3b22a 25
kashgarim 0:ce3028d3b22a 26 uint8_t camera_buffer[NUM_IN_CH*IMG_WIDTH*IMG_HEIGHT];
kashgarim 0:ce3028d3b22a 27 uint8_t resized_buffer[NUM_OUT_CH*CNN_IMG_SIZE*CNN_IMG_SIZE];
kashgarim 0:ce3028d3b22a 28 char lcd_output_string[50];
kashgarim 0:ce3028d3b22a 29 LCD_DISCO_F746NG lcd;
kashgarim 0:ce3028d3b22a 30 Serial pc(USBTX, USBRX);
kashgarim 0:ce3028d3b22a 31
kashgarim 0:ce3028d3b22a 32 void resize_rgb565in_rgb888out(uint8_t* camera_image, uint8_t* resize_image)
kashgarim 0:ce3028d3b22a 33 {
kashgarim 0:ce3028d3b22a 34 // offset so that only the center part of rectangular image is selected for resizing
kashgarim 0:ce3028d3b22a 35 int width_offset = ((IMG_WIDTH-IMG_HEIGHT)/2)*NUM_IN_CH;
kashgarim 0:ce3028d3b22a 36
kashgarim 0:ce3028d3b22a 37 int yresize_ratio = (IMG_HEIGHT/CNN_IMG_SIZE)*NUM_IN_CH;
kashgarim 0:ce3028d3b22a 38 int xresize_ratio = (IMG_WIDTH/CNN_IMG_SIZE)*NUM_IN_CH;
kashgarim 0:ce3028d3b22a 39 int resize_ratio = (xresize_ratio<yresize_ratio)?xresize_ratio:yresize_ratio;
kashgarim 0:ce3028d3b22a 40
kashgarim 0:ce3028d3b22a 41 for(int y=0; y<CNN_IMG_SIZE; y++) {
kashgarim 0:ce3028d3b22a 42 for(int x=0; x<CNN_IMG_SIZE; x++) {
kashgarim 0:ce3028d3b22a 43 int orig_img_loc = (y*IMG_WIDTH*resize_ratio + x*resize_ratio + width_offset);
kashgarim 0:ce3028d3b22a 44 // correcting the image inversion here
kashgarim 0:ce3028d3b22a 45 int out_img_loc = ((CNN_IMG_SIZE-1-y)*CNN_IMG_SIZE + (CNN_IMG_SIZE-1-x))*NUM_OUT_CH;
kashgarim 0:ce3028d3b22a 46 uint8_t pix_lo = camera_image[orig_img_loc];
kashgarim 0:ce3028d3b22a 47 uint8_t pix_hi = camera_image[orig_img_loc+1];
kashgarim 0:ce3028d3b22a 48 // convert RGB565 to RGB888
kashgarim 0:ce3028d3b22a 49 resize_image[out_img_loc] = (0xF8 & pix_hi);
kashgarim 0:ce3028d3b22a 50 resize_image[out_img_loc+1] = ((0x07 & pix_hi)<<5) | ((0xE0 & pix_lo)>>3);
kashgarim 0:ce3028d3b22a 51 resize_image[out_img_loc+2] = (0x1F & pix_lo) << 3;
kashgarim 0:ce3028d3b22a 52 }
kashgarim 0:ce3028d3b22a 53 }
kashgarim 0:ce3028d3b22a 54 }
kashgarim 0:ce3028d3b22a 55
kashgarim 0:ce3028d3b22a 56 void display_image_rgb888(int x_dim, int y_dim, uint8_t* image_data)
kashgarim 0:ce3028d3b22a 57 {
kashgarim 0:ce3028d3b22a 58 for(int y=0; y<y_dim; y++) {
kashgarim 0:ce3028d3b22a 59 for(int x=0; x<x_dim; x++) {
kashgarim 0:ce3028d3b22a 60 int pix_loc = (y*x_dim + x)*3;
kashgarim 0:ce3028d3b22a 61 uint8_t a = 0xFF;
kashgarim 0:ce3028d3b22a 62 uint8_t r = image_data[pix_loc];
kashgarim 0:ce3028d3b22a 63 uint8_t g = image_data[pix_loc+1];
kashgarim 0:ce3028d3b22a 64 uint8_t b = image_data[pix_loc+2];
kashgarim 0:ce3028d3b22a 65 int pixel = a<<24 | r<<16 | g<<8 | b;
kashgarim 0:ce3028d3b22a 66 lcd.DrawPixel(300+x, 100+y, pixel);
kashgarim 0:ce3028d3b22a 67 }
kashgarim 0:ce3028d3b22a 68 }
kashgarim 0:ce3028d3b22a 69 }
kashgarim 0:ce3028d3b22a 70
kashgarim 0:ce3028d3b22a 71 void display_image_rgb565(int x_dim, int y_dim, uint8_t* image_data)
kashgarim 0:ce3028d3b22a 72 {
kashgarim 0:ce3028d3b22a 73 for(int y=0; y<y_dim; y++) {
kashgarim 0:ce3028d3b22a 74 for(int x=0; x<x_dim; x++) {
kashgarim 0:ce3028d3b22a 75 int pix_loc = (y*x_dim + x)*2;
kashgarim 0:ce3028d3b22a 76 uint8_t a = 0xFF;
kashgarim 0:ce3028d3b22a 77 uint8_t pix_lo = image_data[pix_loc];
kashgarim 0:ce3028d3b22a 78 uint8_t pix_hi = image_data[pix_loc+1];
kashgarim 0:ce3028d3b22a 79 uint8_t r = (0xF8 & pix_hi);
kashgarim 0:ce3028d3b22a 80 uint8_t g = ((0x07 & pix_hi)<<5) | ((0xE0 & pix_lo)>>3);
kashgarim 0:ce3028d3b22a 81 uint8_t b = (0x1F & pix_lo) << 3;
kashgarim 0:ce3028d3b22a 82 int pixel = a<<24 | r<<16 | g<<8 | b;
kashgarim 0:ce3028d3b22a 83 // inverted image, so draw from bottom-right to top-left
kashgarim 0:ce3028d3b22a 84 lcd.DrawPixel(200-x, 160-y, pixel);
kashgarim 0:ce3028d3b22a 85 }
kashgarim 0:ce3028d3b22a 86 }
kashgarim 0:ce3028d3b22a 87 }
kashgarim 0:ce3028d3b22a 88
kashgarim 0:ce3028d3b22a 89 int main()
kashgarim 0:ce3028d3b22a 90 {
kashgarim 0:ce3028d3b22a 91 int count=0;
kashgarim 0:ce3028d3b22a 92 HAL_Init();
kashgarim 0:ce3028d3b22a 93 wait_ms(100);
kashgarim 0:ce3028d3b22a 94
kashgarim 0:ce3028d3b22a 95 pc.baud(115200);
kashgarim 0:ce3028d3b22a 96 lcd.Clear(LCD_COLOR_WHITE);
kashgarim 0:ce3028d3b22a 97
kashgarim 0:ce3028d3b22a 98 //lcd.Clear(0xFF0F9D58);
kashgarim 0:ce3028d3b22a 99 //lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"I heard yes! I love yes. :)", CENTER_MODE);
kashgarim 0:ce3028d3b22a 100
kashgarim 0:ce3028d3b22a 101 if( BSP_CAMERA_Init(resolution) == CAMERA_OK ) {
kashgarim 0:ce3028d3b22a 102 pc.printf("Camera init - SUCCESS\r\n");
kashgarim 0:ce3028d3b22a 103 } else {
kashgarim 0:ce3028d3b22a 104 pc.printf("Camera init - FAILED\r\n");
kashgarim 0:ce3028d3b22a 105 lcd.Clear(LCD_COLOR_RED);
kashgarim 0:ce3028d3b22a 106 }
kashgarim 0:ce3028d3b22a 107
kashgarim 0:ce3028d3b22a 108
kashgarim 0:ce3028d3b22a 109 while(1) {
kashgarim 0:ce3028d3b22a 110 BSP_CAMERA_SnapshotStart(camera_buffer);
kashgarim 0:ce3028d3b22a 111 resize_rgb565in_rgb888out(camera_buffer, resized_buffer);
kashgarim 0:ce3028d3b22a 112 display_image_rgb888(CNN_IMG_SIZE, CNN_IMG_SIZE, resized_buffer);
kashgarim 0:ce3028d3b22a 113 display_image_rgb565(IMG_WIDTH, IMG_HEIGHT, camera_buffer);
kashgarim 0:ce3028d3b22a 114 // run neural network
kashgarim 0:ce3028d3b22a 115 sprintf(lcd_output_string,"Original vs. scaled images");
kashgarim 0:ce3028d3b22a 116 lcd.DisplayStringAt(0, LINE(8), (uint8_t *)lcd_output_string, CENTER_MODE);
kashgarim 0:ce3028d3b22a 117
kashgarim 0:ce3028d3b22a 118 /*sprintf(lcd_output_string,"Counter index:%d",count++);
kashgarim 0:ce3028d3b22a 119 lcd.Clear(0xFF0F9D58);
kashgarim 0:ce3028d3b22a 120 lcd.DisplayStringAt(0, LINE(8), (uint8_t *)lcd_output_string, CENTER_MODE);
kashgarim 0:ce3028d3b22a 121 pc.printf("%s\r\n",lcd_output_string);
kashgarim 0:ce3028d3b22a 122 wait_ms(1000);*/
kashgarim 0:ce3028d3b22a 123 }
kashgarim 0:ce3028d3b22a 124 }
kashgarim 0:ce3028d3b22a 125