Image scaling example with DISCO_F746NG board and STM32F4DIS-CAM Camera module.
Dependencies: mbed LCD_DISCO_F746NG BSP_DISCO_F746NG
camera_app.cpp@0:ce3028d3b22a, 2020-02-01 (annotated)
- 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?
User | Revision | Line number | New 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 |