SDCard version
Fork of gr-peach-opencv-project-sd-card by
main.cpp@167:2ee3e82cb6f5, 2017-07-21 (annotated)
- Committer:
- thedo
- Date:
- Fri Jul 21 01:26:54 2017 +0000
- Revision:
- 167:2ee3e82cb6f5
- Parent:
- 166:240bc5a0f42a
gr-peach-opencv-project-sd-card
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
thedo | 166:240bc5a0f42a | 1 | #include "mbed.h" |
thedo | 166:240bc5a0f42a | 2 | #include "DisplayBace.h" |
thedo | 166:240bc5a0f42a | 3 | #include "rtos.h" |
thedo | 166:240bc5a0f42a | 4 | #include "AsciiFont.h" |
thedo | 166:240bc5a0f42a | 5 | #include "define.h" |
thedo | 166:240bc5a0f42a | 6 | #include "mStorage.hpp" |
thedo | 166:240bc5a0f42a | 7 | |
thedo | 166:240bc5a0f42a | 8 | // Include for graphic |
thedo | 166:240bc5a0f42a | 9 | #include "graphicFramework/myImage.h" |
thedo | 166:240bc5a0f42a | 10 | #include "graphicFramework/mGraphic.hpp" |
thedo | 166:240bc5a0f42a | 11 | |
thedo | 166:240bc5a0f42a | 12 | // Include for opencv |
thedo | 166:240bc5a0f42a | 13 | #include "cProcess/cProcess.hpp" |
thedo | 166:240bc5a0f42a | 14 | #include "opencv_3_1/opencv2/core.hpp" |
thedo | 166:240bc5a0f42a | 15 | #include "opencv_3_1/opencv2/imgproc.hpp" |
thedo | 166:240bc5a0f42a | 16 | #include "opencv_3_1/opencv2/objdetect.hpp" |
thedo | 166:240bc5a0f42a | 17 | #include "opencv_3_1/opencv2/face.hpp" |
thedo | 166:240bc5a0f42a | 18 | using namespace cv; |
thedo | 166:240bc5a0f42a | 19 | using namespace face; |
thedo | 166:240bc5a0f42a | 20 | |
thedo | 166:240bc5a0f42a | 21 | typedef struct { |
thedo | 166:240bc5a0f42a | 22 | int x; |
thedo | 166:240bc5a0f42a | 23 | int y; |
thedo | 166:240bc5a0f42a | 24 | int radius; |
thedo | 166:240bc5a0f42a | 25 | uint8_t color[2]; |
thedo | 166:240bc5a0f42a | 26 | }mCircle; |
thedo | 166:240bc5a0f42a | 27 | |
thedo | 166:240bc5a0f42a | 28 | typedef struct { |
thedo | 166:240bc5a0f42a | 29 | int x1; |
thedo | 166:240bc5a0f42a | 30 | int y1; |
thedo | 166:240bc5a0f42a | 31 | int x2; |
thedo | 166:240bc5a0f42a | 32 | int y2; |
thedo | 166:240bc5a0f42a | 33 | uint8_t color[2]; |
thedo | 166:240bc5a0f42a | 34 | }mLine; |
thedo | 166:240bc5a0f42a | 35 | |
thedo | 166:240bc5a0f42a | 36 | typedef struct { |
thedo | 166:240bc5a0f42a | 37 | vector<Mat> database_image; |
thedo | 166:240bc5a0f42a | 38 | vector<int> database_label; |
thedo | 166:240bc5a0f42a | 39 | }face_database_t; |
thedo | 166:240bc5a0f42a | 40 | |
thedo | 166:240bc5a0f42a | 41 | typedef struct { |
thedo | 166:240bc5a0f42a | 42 | Rect obj; |
thedo | 166:240bc5a0f42a | 43 | int label; |
thedo | 166:240bc5a0f42a | 44 | }obj_detect_result; |
thedo | 166:240bc5a0f42a | 45 | |
thedo | 166:240bc5a0f42a | 46 | typedef struct { |
thedo | 166:240bc5a0f42a | 47 | vector<mCircle> circles; |
thedo | 166:240bc5a0f42a | 48 | vector<mLine> lines; |
thedo | 166:240bc5a0f42a | 49 | vector<Point> contour;//only have max contour |
thedo | 166:240bc5a0f42a | 50 | }gesture_result; |
thedo | 166:240bc5a0f42a | 51 | |
thedo | 166:240bc5a0f42a | 52 | typedef struct { |
thedo | 166:240bc5a0f42a | 53 | vector<Point> Pointstart; |
thedo | 166:240bc5a0f42a | 54 | vector<Point> Pointdepth; |
thedo | 166:240bc5a0f42a | 55 | vector<int> Pointindex; |
thedo | 166:240bc5a0f42a | 56 | int detecthand; |
thedo | 166:240bc5a0f42a | 57 | }ConvexPoint; |
thedo | 166:240bc5a0f42a | 58 | |
thedo | 166:240bc5a0f42a | 59 | typedef struct |
thedo | 166:240bc5a0f42a | 60 | { |
thedo | 166:240bc5a0f42a | 61 | double hand_max; |
thedo | 166:240bc5a0f42a | 62 | double hand_min; |
thedo | 166:240bc5a0f42a | 63 | }Sampling; |
thedo | 166:240bc5a0f42a | 64 | |
thedo | 166:240bc5a0f42a | 65 | /* Hardware */ |
thedo | 166:240bc5a0f42a | 66 | static DisplayBase Display; |
thedo | 166:240bc5a0f42a | 67 | static DigitalOut lcd_pwon(P7_15); |
thedo | 166:240bc5a0f42a | 68 | static DigitalOut lcd_blon(P8_1); |
thedo | 166:240bc5a0f42a | 69 | static PwmOut lcd_cntrst(P8_15); |
thedo | 166:240bc5a0f42a | 70 | static Serial pc(USBTX, USBRX); |
thedo | 166:240bc5a0f42a | 71 | static TouckKey_LCD_shield touch(P4_0, P2_13, I2C_SDA, I2C_SCL); |
thedo | 166:240bc5a0f42a | 72 | |
thedo | 166:240bc5a0f42a | 73 | /* Semaphore and mutex */ |
thedo | 166:240bc5a0f42a | 74 | rtos::Mutex mMutexProcess; |
thedo | 166:240bc5a0f42a | 75 | rtos::Mutex mMutexObjects; |
thedo | 166:240bc5a0f42a | 76 | rtos::Mutex mMutexClicked; |
thedo | 166:240bc5a0f42a | 77 | |
thedo | 166:240bc5a0f42a | 78 | static Semaphore semProcessThread(0); |
thedo | 166:240bc5a0f42a | 79 | static Semaphore semTouch(0); |
thedo | 166:240bc5a0f42a | 80 | static Semaphore semDrawAction(0); |
thedo | 166:240bc5a0f42a | 81 | |
thedo | 166:240bc5a0f42a | 82 | /* Threads */ |
thedo | 166:240bc5a0f42a | 83 | static Thread * p_VideoLcdTask = NULL; |
thedo | 166:240bc5a0f42a | 84 | static Thread * p_DrawObjects = NULL; |
thedo | 166:240bc5a0f42a | 85 | static Thread * p_Touch = NULL; |
thedo | 166:240bc5a0f42a | 86 | |
thedo | 166:240bc5a0f42a | 87 | static cStorage *myStorage = NULL; |
thedo | 166:240bc5a0f42a | 88 | static vector<obj_detect_result> gObjectDetects; |
thedo | 166:240bc5a0f42a | 89 | static gesture_result gGestureResult; |
thedo | 166:240bc5a0f42a | 90 | static bool gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 91 | static bool gIsDrawing = false; |
thedo | 166:240bc5a0f42a | 92 | static int write_buff_num = 0; |
thedo | 166:240bc5a0f42a | 93 | static int read_buff_num = 0; |
thedo | 166:240bc5a0f42a | 94 | static bool graphics_init_end = false; |
thedo | 166:240bc5a0f42a | 95 | static APP_MODE appMode = GUESTURE_RECOGNITION; |
thedo | 166:240bc5a0f42a | 96 | static CLICKED_CODE clickedCode = CLICKED_UNKNOWN; |
thedo | 166:240bc5a0f42a | 97 | |
thedo | 166:240bc5a0f42a | 98 | /****** cache control ******/ |
thedo | 166:240bc5a0f42a | 99 | static void dcache_clean(void * p_buf, uint32_t size) { |
thedo | 166:240bc5a0f42a | 100 | uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0; |
thedo | 166:240bc5a0f42a | 101 | uint32_t end_addr = (uint32_t)p_buf + size; |
thedo | 166:240bc5a0f42a | 102 | uint32_t addr; |
thedo | 166:240bc5a0f42a | 103 | |
thedo | 166:240bc5a0f42a | 104 | /* Data cache clean */ |
thedo | 166:240bc5a0f42a | 105 | for (addr = start_addr; addr < end_addr; addr += 0x20) { |
thedo | 166:240bc5a0f42a | 106 | __v7_clean_dcache_mva((void *)addr); |
thedo | 166:240bc5a0f42a | 107 | } |
thedo | 166:240bc5a0f42a | 108 | } |
thedo | 166:240bc5a0f42a | 109 | |
thedo | 166:240bc5a0f42a | 110 | /****** LCD ******/ |
thedo | 166:240bc5a0f42a | 111 | #if(0) /* When needing LCD Vsync interrupt, please make it effective. */ |
thedo | 166:240bc5a0f42a | 112 | static void IntCallbackFunc_LoVsync(DisplayBase::int_type_t int_type) { |
thedo | 166:240bc5a0f42a | 113 | /* Interrupt callback function for Vsync interruption */ |
thedo | 166:240bc5a0f42a | 114 | } |
thedo | 166:240bc5a0f42a | 115 | #endif |
thedo | 166:240bc5a0f42a | 116 | |
thedo | 166:240bc5a0f42a | 117 | static void Init_LCD_Display(void) { |
thedo | 166:240bc5a0f42a | 118 | DisplayBase::graphics_error_t error; |
thedo | 166:240bc5a0f42a | 119 | DisplayBase::lcd_config_t lcd_config; |
thedo | 166:240bc5a0f42a | 120 | PinName lvds_pin[8] = { |
thedo | 166:240bc5a0f42a | 121 | /* data pin */ |
thedo | 166:240bc5a0f42a | 122 | P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0 |
thedo | 166:240bc5a0f42a | 123 | }; |
thedo | 166:240bc5a0f42a | 124 | |
thedo | 166:240bc5a0f42a | 125 | lcd_pwon = 0; |
thedo | 166:240bc5a0f42a | 126 | lcd_blon = 0; |
thedo | 166:240bc5a0f42a | 127 | Thread::wait(100); |
thedo | 166:240bc5a0f42a | 128 | lcd_pwon = 1; |
thedo | 166:240bc5a0f42a | 129 | lcd_blon = 1; |
thedo | 166:240bc5a0f42a | 130 | |
thedo | 166:240bc5a0f42a | 131 | Display.Graphics_Lvds_Port_Init(lvds_pin, 8); |
thedo | 166:240bc5a0f42a | 132 | |
thedo | 166:240bc5a0f42a | 133 | /* Graphics initialization process */ |
thedo | 166:240bc5a0f42a | 134 | lcd_config = LcdCfgTbl_LCD_shield; |
thedo | 166:240bc5a0f42a | 135 | error = Display.Graphics_init(&lcd_config); |
thedo | 166:240bc5a0f42a | 136 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 137 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 138 | mbed_die(); |
thedo | 166:240bc5a0f42a | 139 | } |
thedo | 166:240bc5a0f42a | 140 | graphics_init_end = true; |
thedo | 166:240bc5a0f42a | 141 | |
thedo | 166:240bc5a0f42a | 142 | #if(0) /* When needing LCD Vsync interrupt, please make it effective. */ |
thedo | 166:240bc5a0f42a | 143 | /* Interrupt callback function setting (Vsync signal output from scaler 0)*/ |
thedo | 166:240bc5a0f42a | 144 | error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC, |
thedo | 166:240bc5a0f42a | 145 | 0, IntCallbackFunc_LoVsync); |
thedo | 166:240bc5a0f42a | 146 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 147 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 148 | mbed_die(); |
thedo | 166:240bc5a0f42a | 149 | } |
thedo | 166:240bc5a0f42a | 150 | #endif |
thedo | 166:240bc5a0f42a | 151 | } |
thedo | 166:240bc5a0f42a | 152 | |
thedo | 166:240bc5a0f42a | 153 | static void Start_LCD_Display(uint8_t * p_buf) { |
thedo | 166:240bc5a0f42a | 154 | DisplayBase::rect_t rect; |
thedo | 166:240bc5a0f42a | 155 | |
thedo | 166:240bc5a0f42a | 156 | rect.vs = 0; |
thedo | 166:240bc5a0f42a | 157 | rect.vw = LCD_PIXEL_HEIGHT; |
thedo | 166:240bc5a0f42a | 158 | rect.hs = 0; |
thedo | 166:240bc5a0f42a | 159 | rect.hw = LCD_PIXEL_WIDTH; |
thedo | 166:240bc5a0f42a | 160 | Display.Graphics_Read_Setting( |
thedo | 166:240bc5a0f42a | 161 | DisplayBase::GRAPHICS_LAYER_0, |
thedo | 166:240bc5a0f42a | 162 | (void *)p_buf, |
thedo | 166:240bc5a0f42a | 163 | FRAME_BUFFER_STRIDE, |
thedo | 166:240bc5a0f42a | 164 | GRAPHICS_FORMAT, |
thedo | 166:240bc5a0f42a | 165 | WR_RD_WRSWA, |
thedo | 166:240bc5a0f42a | 166 | &rect |
thedo | 166:240bc5a0f42a | 167 | ); |
thedo | 166:240bc5a0f42a | 168 | Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); |
thedo | 166:240bc5a0f42a | 169 | } |
thedo | 166:240bc5a0f42a | 170 | |
thedo | 166:240bc5a0f42a | 171 | /****** Video ******/ |
thedo | 166:240bc5a0f42a | 172 | #if(0) /* When needing video Vsync interrupt, please make it effective. */ |
thedo | 166:240bc5a0f42a | 173 | static void IntCallbackFunc_ViVsync(DisplayBase::int_type_t int_type) { |
thedo | 166:240bc5a0f42a | 174 | /* Interrupt callback function for Vsync interruption */ |
thedo | 166:240bc5a0f42a | 175 | } |
thedo | 166:240bc5a0f42a | 176 | #endif |
thedo | 166:240bc5a0f42a | 177 | |
thedo | 166:240bc5a0f42a | 178 | static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) { |
thedo | 166:240bc5a0f42a | 179 | /* Interrupt callback function */ |
thedo | 166:240bc5a0f42a | 180 | #if VIDEO_INPUT_METHOD == VIDEO_CVBS |
thedo | 166:240bc5a0f42a | 181 | if (vfield_count == 0) { |
thedo | 166:240bc5a0f42a | 182 | vfield_count = 1; |
thedo | 166:240bc5a0f42a | 183 | } else { |
thedo | 166:240bc5a0f42a | 184 | vfield_count = 0; |
thedo | 166:240bc5a0f42a | 185 | #else |
thedo | 166:240bc5a0f42a | 186 | { |
thedo | 166:240bc5a0f42a | 187 | #endif |
thedo | 166:240bc5a0f42a | 188 | if (p_VideoLcdTask != NULL) { |
thedo | 166:240bc5a0f42a | 189 | p_VideoLcdTask->signal_set(1); |
thedo | 166:240bc5a0f42a | 190 | } |
thedo | 166:240bc5a0f42a | 191 | } |
thedo | 166:240bc5a0f42a | 192 | } |
thedo | 166:240bc5a0f42a | 193 | |
thedo | 166:240bc5a0f42a | 194 | static void Init_Video(void) { |
thedo | 166:240bc5a0f42a | 195 | DisplayBase::graphics_error_t error; |
thedo | 166:240bc5a0f42a | 196 | |
thedo | 166:240bc5a0f42a | 197 | /* Graphics initialization process */ |
thedo | 166:240bc5a0f42a | 198 | if (graphics_init_end == false) { |
thedo | 166:240bc5a0f42a | 199 | /* When not initializing LCD, this processing is needed. */ |
thedo | 166:240bc5a0f42a | 200 | error = Display.Graphics_init(NULL); |
thedo | 166:240bc5a0f42a | 201 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 202 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 203 | mbed_die(); |
thedo | 166:240bc5a0f42a | 204 | } |
thedo | 166:240bc5a0f42a | 205 | graphics_init_end = true; |
thedo | 166:240bc5a0f42a | 206 | } |
thedo | 166:240bc5a0f42a | 207 | |
thedo | 166:240bc5a0f42a | 208 | #if VIDEO_INPUT_METHOD == VIDEO_CVBS |
thedo | 166:240bc5a0f42a | 209 | error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL); |
thedo | 166:240bc5a0f42a | 210 | if( error != DisplayBase::GRAPHICS_OK ) { |
thedo | 166:240bc5a0f42a | 211 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 212 | mbed_die(); |
thedo | 166:240bc5a0f42a | 213 | } |
thedo | 166:240bc5a0f42a | 214 | #elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA |
thedo | 166:240bc5a0f42a | 215 | DisplayBase::video_ext_in_config_t ext_in_config; |
thedo | 166:240bc5a0f42a | 216 | PinName cmos_camera_pin[11] = { |
thedo | 166:240bc5a0f42a | 217 | /* data pin */ |
thedo | 166:240bc5a0f42a | 218 | P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0, |
thedo | 166:240bc5a0f42a | 219 | /* control pin */ |
thedo | 166:240bc5a0f42a | 220 | P10_0, /* DV0_CLK */ |
thedo | 166:240bc5a0f42a | 221 | P1_0, /* DV0_Vsync */ |
thedo | 166:240bc5a0f42a | 222 | P1_1 /* DV0_Hsync */ |
thedo | 166:240bc5a0f42a | 223 | }; |
thedo | 166:240bc5a0f42a | 224 | |
thedo | 166:240bc5a0f42a | 225 | /* MT9V111 camera input config */ |
thedo | 166:240bc5a0f42a | 226 | ext_in_config.inp_format = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */ |
thedo | 166:240bc5a0f42a | 227 | ext_in_config.inp_pxd_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing data */ |
thedo | 166:240bc5a0f42a | 228 | ext_in_config.inp_vs_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing Vsync signals */ |
thedo | 166:240bc5a0f42a | 229 | ext_in_config.inp_hs_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing Hsync signals */ |
thedo | 166:240bc5a0f42a | 230 | ext_in_config.inp_endian_on = DisplayBase::OFF; /* External input bit endian change on/off */ |
thedo | 166:240bc5a0f42a | 231 | ext_in_config.inp_swap_on = DisplayBase::OFF; /* External input B/R signal swap on/off */ |
thedo | 166:240bc5a0f42a | 232 | ext_in_config.inp_vs_inv = DisplayBase::SIG_POL_NOT_INVERTED; /* External input DV_VSYNC inversion control */ |
thedo | 166:240bc5a0f42a | 233 | ext_in_config.inp_hs_inv = DisplayBase::SIG_POL_INVERTED; /* External input DV_HSYNC inversion control */ |
thedo | 166:240bc5a0f42a | 234 | ext_in_config.inp_f525_625 = DisplayBase::EXTIN_LINE_525; /* Number of lines for BT.656 external input */ |
thedo | 166:240bc5a0f42a | 235 | ext_in_config.inp_h_pos = DisplayBase::EXTIN_H_POS_CRYCBY; /* Y/Cb/Y/Cr data string start timing to Hsync reference */ |
thedo | 166:240bc5a0f42a | 236 | ext_in_config.cap_vs_pos = 6; /* Capture start position from Vsync */ |
thedo | 166:240bc5a0f42a | 237 | ext_in_config.cap_hs_pos = 150; /* Capture start position form Hsync */ |
thedo | 166:240bc5a0f42a | 238 | #if (LCD_TYPE == 0) |
thedo | 166:240bc5a0f42a | 239 | /* The same screen ratio as the screen ratio of the LCD. */ |
thedo | 166:240bc5a0f42a | 240 | ext_in_config.cap_width = 640; /* Capture width */ |
thedo | 166:240bc5a0f42a | 241 | ext_in_config.cap_height = 363; /* Capture height Max 468[line] |
thedo | 166:240bc5a0f42a | 242 | Due to CMOS(MT9V111) output signal timing and VDC5 specification */ |
thedo | 166:240bc5a0f42a | 243 | #else |
thedo | 166:240bc5a0f42a | 244 | ext_in_config.cap_width = 640; /* Capture width */ |
thedo | 166:240bc5a0f42a | 245 | ext_in_config.cap_height = 468; /* Capture height Max 468[line] |
thedo | 166:240bc5a0f42a | 246 | Due to CMOS(MT9V111) output signal timing and VDC5 specification */ |
thedo | 166:240bc5a0f42a | 247 | #endif |
thedo | 166:240bc5a0f42a | 248 | error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config); |
thedo | 166:240bc5a0f42a | 249 | if( error != DisplayBase::GRAPHICS_OK ) { |
thedo | 166:240bc5a0f42a | 250 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 251 | mbed_die(); |
thedo | 166:240bc5a0f42a | 252 | } |
thedo | 166:240bc5a0f42a | 253 | |
thedo | 166:240bc5a0f42a | 254 | /* Camera input port setting */ |
thedo | 166:240bc5a0f42a | 255 | error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11); |
thedo | 166:240bc5a0f42a | 256 | if( error != DisplayBase::GRAPHICS_OK ) { |
thedo | 166:240bc5a0f42a | 257 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 258 | mbed_die(); |
thedo | 166:240bc5a0f42a | 259 | } |
thedo | 166:240bc5a0f42a | 260 | #endif |
thedo | 166:240bc5a0f42a | 261 | |
thedo | 166:240bc5a0f42a | 262 | #if(0) /* When needing video Vsync interrupt, please make it effective. */ |
thedo | 166:240bc5a0f42a | 263 | /* Interrupt callback function setting (Vsync signal input to scaler 0) */ |
thedo | 166:240bc5a0f42a | 264 | error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC, |
thedo | 166:240bc5a0f42a | 265 | 0, IntCallbackFunc_ViVsync); |
thedo | 166:240bc5a0f42a | 266 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 267 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 268 | mbed_die(); |
thedo | 166:240bc5a0f42a | 269 | } |
thedo | 166:240bc5a0f42a | 270 | #endif |
thedo | 166:240bc5a0f42a | 271 | |
thedo | 166:240bc5a0f42a | 272 | /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */ |
thedo | 166:240bc5a0f42a | 273 | error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, |
thedo | 166:240bc5a0f42a | 274 | IntCallbackFunc_Vfield); |
thedo | 166:240bc5a0f42a | 275 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 276 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 277 | mbed_die(); |
thedo | 166:240bc5a0f42a | 278 | } |
thedo | 166:240bc5a0f42a | 279 | } |
thedo | 166:240bc5a0f42a | 280 | |
thedo | 166:240bc5a0f42a | 281 | static void initDrawResultLayer(void) |
thedo | 166:240bc5a0f42a | 282 | { |
thedo | 166:240bc5a0f42a | 283 | DisplayBase::rect_t rect; |
thedo | 166:240bc5a0f42a | 284 | /* The layer by which the touch panel location is drawn */ |
thedo | 166:240bc5a0f42a | 285 | memset(user_frame_buffer_draw, 0, sizeof(user_frame_buffer_draw)); |
thedo | 166:240bc5a0f42a | 286 | dcache_clean(user_frame_buffer_draw, sizeof(user_frame_buffer_draw)); |
thedo | 166:240bc5a0f42a | 287 | rect.vs = 0; |
thedo | 166:240bc5a0f42a | 288 | rect.vw = LCD_PIXEL_HEIGHT; |
thedo | 166:240bc5a0f42a | 289 | rect.hs = 0; |
thedo | 166:240bc5a0f42a | 290 | rect.hw = LCD_PIXEL_WIDTH; |
thedo | 166:240bc5a0f42a | 291 | Display.Graphics_Read_Setting( |
thedo | 166:240bc5a0f42a | 292 | DisplayBase::GRAPHICS_LAYER_1, |
thedo | 166:240bc5a0f42a | 293 | (void *)user_frame_buffer_draw, |
thedo | 166:240bc5a0f42a | 294 | DRAW_BUFFER_STRIDE, |
thedo | 166:240bc5a0f42a | 295 | DisplayBase::GRAPHICS_FORMAT_ARGB4444, |
thedo | 166:240bc5a0f42a | 296 | DisplayBase::WR_RD_WRSWA_32_16BIT, |
thedo | 166:240bc5a0f42a | 297 | &rect |
thedo | 166:240bc5a0f42a | 298 | ); |
thedo | 166:240bc5a0f42a | 299 | Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1); |
thedo | 166:240bc5a0f42a | 300 | } |
thedo | 166:240bc5a0f42a | 301 | |
thedo | 166:240bc5a0f42a | 302 | static void initDrawAction(void) |
thedo | 166:240bc5a0f42a | 303 | { |
thedo | 166:240bc5a0f42a | 304 | // Init draw control |
thedo | 166:240bc5a0f42a | 305 | DisplayBase::rect_t rect; |
thedo | 166:240bc5a0f42a | 306 | rect.vs = 0; |
thedo | 166:240bc5a0f42a | 307 | rect.vw = LCD_PIXEL_HEIGHT; |
thedo | 166:240bc5a0f42a | 308 | rect.hs = 0; |
thedo | 166:240bc5a0f42a | 309 | rect.hw = LCD_PIXEL_WIDTH; |
thedo | 166:240bc5a0f42a | 310 | |
thedo | 166:240bc5a0f42a | 311 | memset(user_frame_buffer_draw_action, 0, |
thedo | 166:240bc5a0f42a | 312 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 313 | /* Clean cache */ |
thedo | 166:240bc5a0f42a | 314 | dcache_clean(user_frame_buffer_draw_action, |
thedo | 166:240bc5a0f42a | 315 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 316 | |
thedo | 166:240bc5a0f42a | 317 | Display.Graphics_Read_Setting( |
thedo | 166:240bc5a0f42a | 318 | DisplayBase::GRAPHICS_LAYER_3, |
thedo | 166:240bc5a0f42a | 319 | (void *)user_frame_buffer_draw_action, |
thedo | 166:240bc5a0f42a | 320 | DRAW_BUFFER_STRIDE, |
thedo | 166:240bc5a0f42a | 321 | DisplayBase::GRAPHICS_FORMAT_ARGB4444, |
thedo | 166:240bc5a0f42a | 322 | DisplayBase::WR_RD_WRSWA_32_16BIT, |
thedo | 166:240bc5a0f42a | 323 | &rect |
thedo | 166:240bc5a0f42a | 324 | ); |
thedo | 166:240bc5a0f42a | 325 | Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_3); |
thedo | 166:240bc5a0f42a | 326 | } |
thedo | 166:240bc5a0f42a | 327 | static void initDrawButtonLayer(void) |
thedo | 166:240bc5a0f42a | 328 | { |
thedo | 166:240bc5a0f42a | 329 | DisplayBase::rect_t rect; |
thedo | 166:240bc5a0f42a | 330 | /* The layer by which the touch panel location is drawn */ |
thedo | 166:240bc5a0f42a | 331 | memset(user_frame_buffer_draw_button, 0, |
thedo | 166:240bc5a0f42a | 332 | sizeof(user_frame_buffer_draw_button)); |
thedo | 166:240bc5a0f42a | 333 | dcache_clean(user_frame_buffer_draw_button, |
thedo | 166:240bc5a0f42a | 334 | sizeof(user_frame_buffer_draw_button)); |
thedo | 166:240bc5a0f42a | 335 | rect.vs = 0; |
thedo | 166:240bc5a0f42a | 336 | rect.vw = LCD_PIXEL_HEIGHT; |
thedo | 166:240bc5a0f42a | 337 | rect.hs = 0; |
thedo | 166:240bc5a0f42a | 338 | rect.hw = LCD_PIXEL_WIDTH; |
thedo | 166:240bc5a0f42a | 339 | Display.Graphics_Read_Setting( |
thedo | 166:240bc5a0f42a | 340 | DisplayBase::GRAPHICS_LAYER_2, |
thedo | 166:240bc5a0f42a | 341 | (void *)user_frame_buffer_draw_button, |
thedo | 166:240bc5a0f42a | 342 | DRAW_BUFFER_STRIDE, |
thedo | 166:240bc5a0f42a | 343 | DisplayBase::GRAPHICS_FORMAT_ARGB4444, |
thedo | 166:240bc5a0f42a | 344 | DisplayBase::WR_RD_WRSWA_32_16BIT, |
thedo | 166:240bc5a0f42a | 345 | &rect |
thedo | 166:240bc5a0f42a | 346 | ); |
thedo | 166:240bc5a0f42a | 347 | Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_2); |
thedo | 166:240bc5a0f42a | 348 | } |
thedo | 166:240bc5a0f42a | 349 | |
thedo | 166:240bc5a0f42a | 350 | static void Start_Video(uint8_t * p_buf) { |
thedo | 166:240bc5a0f42a | 351 | DisplayBase::graphics_error_t error; |
thedo | 166:240bc5a0f42a | 352 | |
thedo | 166:240bc5a0f42a | 353 | /* Video capture setting (progressive form fixed) */ |
thedo | 166:240bc5a0f42a | 354 | error = Display.Video_Write_Setting( |
thedo | 166:240bc5a0f42a | 355 | VIDEO_INPUT_CH, |
thedo | 166:240bc5a0f42a | 356 | COL_SYS, |
thedo | 166:240bc5a0f42a | 357 | p_buf, |
thedo | 166:240bc5a0f42a | 358 | FRAME_BUFFER_STRIDE, |
thedo | 166:240bc5a0f42a | 359 | VIDEO_FORMAT, |
thedo | 166:240bc5a0f42a | 360 | WR_RD_WRSWA, |
thedo | 166:240bc5a0f42a | 361 | VIDEO_PIXEL_VW, |
thedo | 166:240bc5a0f42a | 362 | VIDEO_PIXEL_HW |
thedo | 166:240bc5a0f42a | 363 | ); |
thedo | 166:240bc5a0f42a | 364 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 365 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 366 | mbed_die(); |
thedo | 166:240bc5a0f42a | 367 | } |
thedo | 166:240bc5a0f42a | 368 | |
thedo | 166:240bc5a0f42a | 369 | /* Video write process start */ |
thedo | 166:240bc5a0f42a | 370 | error = Display.Video_Start(VIDEO_INPUT_CH); |
thedo | 166:240bc5a0f42a | 371 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 372 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 373 | mbed_die(); |
thedo | 166:240bc5a0f42a | 374 | } |
thedo | 166:240bc5a0f42a | 375 | |
thedo | 166:240bc5a0f42a | 376 | /* Video write process stop */ |
thedo | 166:240bc5a0f42a | 377 | error = Display.Video_Stop(VIDEO_INPUT_CH); |
thedo | 166:240bc5a0f42a | 378 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 379 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 380 | mbed_die(); |
thedo | 166:240bc5a0f42a | 381 | } |
thedo | 166:240bc5a0f42a | 382 | |
thedo | 166:240bc5a0f42a | 383 | /* Video write process start */ |
thedo | 166:240bc5a0f42a | 384 | error = Display.Video_Start(VIDEO_INPUT_CH); |
thedo | 166:240bc5a0f42a | 385 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 386 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 387 | mbed_die(); |
thedo | 166:240bc5a0f42a | 388 | } |
thedo | 166:240bc5a0f42a | 389 | } |
thedo | 166:240bc5a0f42a | 390 | |
thedo | 166:240bc5a0f42a | 391 | /* Select function from button */ |
thedo | 166:240bc5a0f42a | 392 | APP_MODE getFunctionSelected(int x, int y) |
thedo | 166:240bc5a0f42a | 393 | { |
thedo | 166:240bc5a0f42a | 394 | int w = 100; //width of image button |
thedo | 166:240bc5a0f42a | 395 | if ( MODE_BTN_Y > y ) |
thedo | 166:240bc5a0f42a | 396 | { |
thedo | 166:240bc5a0f42a | 397 | return MODE_UNKNOWN; |
thedo | 166:240bc5a0f42a | 398 | } |
thedo | 166:240bc5a0f42a | 399 | |
thedo | 166:240bc5a0f42a | 400 | if ( MODE_BTN_X <= x && x <= (MODE_BTN_X + w)) |
thedo | 166:240bc5a0f42a | 401 | { |
thedo | 166:240bc5a0f42a | 402 | return FACE_DETECTION; |
thedo | 166:240bc5a0f42a | 403 | } |
thedo | 166:240bc5a0f42a | 404 | else if ( (2*MODE_BTN_X + w) <= x && x <= (2*MODE_BTN_X + 2*w)) |
thedo | 166:240bc5a0f42a | 405 | { |
thedo | 166:240bc5a0f42a | 406 | return FACE_RECOGNITION; |
thedo | 166:240bc5a0f42a | 407 | } |
thedo | 166:240bc5a0f42a | 408 | else if ( (3*MODE_BTN_X + 2*w) <= x && x <= (3*MODE_BTN_X + 3*w) ) |
thedo | 166:240bc5a0f42a | 409 | { |
thedo | 166:240bc5a0f42a | 410 | return MOTION_DETECTION; |
thedo | 166:240bc5a0f42a | 411 | } |
thedo | 166:240bc5a0f42a | 412 | else if ((4*MODE_BTN_X + 3*w) <= x && x <= (4*MODE_BTN_X + 4*w)) |
thedo | 166:240bc5a0f42a | 413 | { |
thedo | 166:240bc5a0f42a | 414 | return GUESTURE_RECOGNITION; |
thedo | 166:240bc5a0f42a | 415 | } |
thedo | 166:240bc5a0f42a | 416 | else |
thedo | 166:240bc5a0f42a | 417 | return MODE_UNKNOWN; |
thedo | 166:240bc5a0f42a | 418 | } |
thedo | 166:240bc5a0f42a | 419 | |
thedo | 166:240bc5a0f42a | 420 | /* Click action in face recognition */ |
thedo | 166:240bc5a0f42a | 421 | void clickActionFaceReg(int x, int y) |
thedo | 166:240bc5a0f42a | 422 | { |
thedo | 166:240bc5a0f42a | 423 | mMutexClicked.lock(); |
thedo | 166:240bc5a0f42a | 424 | if(REGIS_FACE_BTN_X <= x && x <= (REGIS_FACE_BTN_X + 30) && |
thedo | 166:240bc5a0f42a | 425 | REGIS_FACE_BTN_Y <= y && y <= (REGIS_FACE_BTN_Y + 30)) |
thedo | 166:240bc5a0f42a | 426 | { |
thedo | 166:240bc5a0f42a | 427 | clickedCode = CLICKED_REGIS_FACE; |
thedo | 166:240bc5a0f42a | 428 | } |
thedo | 166:240bc5a0f42a | 429 | else if (FACE_REG_ACT_MENU_X <= x && x <= (FACE_REG_ACT_MENU_X + 60) && |
thedo | 166:240bc5a0f42a | 430 | FACE_REG_ACT_MENU_Y <= y && y <= (FACE_REG_ACT_MENU_Y + 20)) |
thedo | 166:240bc5a0f42a | 431 | { |
thedo | 166:240bc5a0f42a | 432 | clickedCode = CLICKED_CHANGE_ID; |
thedo | 166:240bc5a0f42a | 433 | } |
thedo | 166:240bc5a0f42a | 434 | else if (FACE_REG_ACT_MENU_X <= x && x <= (FACE_REG_ACT_MENU_X + 60) && |
thedo | 166:240bc5a0f42a | 435 | (FACE_REG_ACT_MENU_Y + 20 + 12)<= y && |
thedo | 166:240bc5a0f42a | 436 | y <= (FACE_REG_ACT_MENU_Y + 2*20 + 12))//space:12 |
thedo | 166:240bc5a0f42a | 437 | { |
thedo | 166:240bc5a0f42a | 438 | clickedCode = CLICKED_ADD; |
thedo | 166:240bc5a0f42a | 439 | } |
thedo | 166:240bc5a0f42a | 440 | else if (FACE_REG_ACT_MENU_X <= x && x <= (FACE_REG_ACT_MENU_X + 60) && |
thedo | 166:240bc5a0f42a | 441 | (FACE_REG_ACT_MENU_Y + 2*20 + 2*12)<= y && |
thedo | 166:240bc5a0f42a | 442 | y <= (FACE_REG_ACT_MENU_Y + 3*20 + 2*12)) |
thedo | 166:240bc5a0f42a | 443 | { |
thedo | 166:240bc5a0f42a | 444 | clickedCode = CLICKED_IGNORE; |
thedo | 166:240bc5a0f42a | 445 | } |
thedo | 166:240bc5a0f42a | 446 | else |
thedo | 166:240bc5a0f42a | 447 | { |
thedo | 166:240bc5a0f42a | 448 | clickedCode = CLICKED_UNKNOWN; |
thedo | 166:240bc5a0f42a | 449 | } |
thedo | 166:240bc5a0f42a | 450 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 451 | } |
thedo | 166:240bc5a0f42a | 452 | |
thedo | 166:240bc5a0f42a | 453 | /* Click on screen gesture recognition */ |
thedo | 166:240bc5a0f42a | 454 | void clickActionGestureReg(int x, int y) |
thedo | 166:240bc5a0f42a | 455 | { |
thedo | 166:240bc5a0f42a | 456 | mMutexClicked.lock(); |
thedo | 166:240bc5a0f42a | 457 | if(GESTURE_SAMPLING_BTN_X <= x && x <= (GESTURE_SAMPLING_BTN_X + 60) && |
thedo | 166:240bc5a0f42a | 458 | GESTURE_SAMPLING_BTN_Y <= y && y <= (GESTURE_SAMPLING_BTN_Y + 20)) |
thedo | 166:240bc5a0f42a | 459 | { |
thedo | 166:240bc5a0f42a | 460 | clickedCode = CLICKED_HAND_SAMPLING; |
thedo | 166:240bc5a0f42a | 461 | } |
thedo | 166:240bc5a0f42a | 462 | else |
thedo | 166:240bc5a0f42a | 463 | { |
thedo | 166:240bc5a0f42a | 464 | clickedCode = CLICKED_UNKNOWN; |
thedo | 166:240bc5a0f42a | 465 | } |
thedo | 166:240bc5a0f42a | 466 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 467 | } |
thedo | 166:240bc5a0f42a | 468 | |
thedo | 166:240bc5a0f42a | 469 | /**** Draw button controls ****/ |
thedo | 166:240bc5a0f42a | 470 | void drawButtonControls(graphicFrameworkCanvas myCanvasButton) |
thedo | 166:240bc5a0f42a | 471 | { |
thedo | 166:240bc5a0f42a | 472 | int space = 16; |
thedo | 166:240bc5a0f42a | 473 | int x = 0; |
thedo | 166:240bc5a0f42a | 474 | int y = MODE_BTN_Y; |
thedo | 166:240bc5a0f42a | 475 | |
thedo | 166:240bc5a0f42a | 476 | x+=space; |
thedo | 166:240bc5a0f42a | 477 | myCanvasButton.drawImage(my_img_button_face_detect,x,y); // 100x40 |
thedo | 166:240bc5a0f42a | 478 | x+=100; |
thedo | 166:240bc5a0f42a | 479 | |
thedo | 166:240bc5a0f42a | 480 | x+=space; |
thedo | 166:240bc5a0f42a | 481 | myCanvasButton.drawImage(my_img_button_face_recognition,x,y); |
thedo | 166:240bc5a0f42a | 482 | x+=100; |
thedo | 166:240bc5a0f42a | 483 | |
thedo | 166:240bc5a0f42a | 484 | x+=space; |
thedo | 166:240bc5a0f42a | 485 | myCanvasButton.drawImage(my_img_button_obj_motion,x,y); |
thedo | 166:240bc5a0f42a | 486 | x+=100; |
thedo | 166:240bc5a0f42a | 487 | |
thedo | 166:240bc5a0f42a | 488 | x+=space; |
thedo | 166:240bc5a0f42a | 489 | myCanvasButton.drawImage(my_img_button_gesture_reg,x,y); |
thedo | 166:240bc5a0f42a | 490 | x+=100; |
thedo | 166:240bc5a0f42a | 491 | } |
thedo | 166:240bc5a0f42a | 492 | |
thedo | 166:240bc5a0f42a | 493 | void drawTextScreen(graphicFrameworkCanvas myCanvasButton) |
thedo | 166:240bc5a0f42a | 494 | { |
thedo | 166:240bc5a0f42a | 495 | int x = 160; |
thedo | 166:240bc5a0f42a | 496 | int y = 5; |
thedo | 166:240bc5a0f42a | 497 | |
thedo | 166:240bc5a0f42a | 498 | if( appMode == MOTION_DETECTION ) |
thedo | 166:240bc5a0f42a | 499 | { |
thedo | 166:240bc5a0f42a | 500 | myCanvasButton.drawImage(my_img_text_obj_motion,x, y); |
thedo | 166:240bc5a0f42a | 501 | } |
thedo | 166:240bc5a0f42a | 502 | else if ( appMode == FACE_DETECTION ) |
thedo | 166:240bc5a0f42a | 503 | { |
thedo | 166:240bc5a0f42a | 504 | myCanvasButton.drawImage(my_img_text_face_detection,x, y); |
thedo | 166:240bc5a0f42a | 505 | } |
thedo | 166:240bc5a0f42a | 506 | else if ( appMode == FACE_RECOGNITION ) |
thedo | 166:240bc5a0f42a | 507 | { |
thedo | 166:240bc5a0f42a | 508 | myCanvasButton.drawImage(my_img_text_face_recognition,x, y); |
thedo | 166:240bc5a0f42a | 509 | } |
thedo | 166:240bc5a0f42a | 510 | else if ( appMode == GUESTURE_RECOGNITION ) |
thedo | 166:240bc5a0f42a | 511 | { |
thedo | 166:240bc5a0f42a | 512 | myCanvasButton.drawImage(my_img_text_gesture_reg,x, y); |
thedo | 166:240bc5a0f42a | 513 | } |
thedo | 166:240bc5a0f42a | 514 | } |
thedo | 166:240bc5a0f42a | 515 | |
thedo | 166:240bc5a0f42a | 516 | void clearGestureResult(gesture_result res) |
thedo | 166:240bc5a0f42a | 517 | { |
thedo | 166:240bc5a0f42a | 518 | res.circles.clear(); |
thedo | 166:240bc5a0f42a | 519 | res.lines.clear(); |
thedo | 166:240bc5a0f42a | 520 | res.contour.clear(); |
thedo | 166:240bc5a0f42a | 521 | } |
thedo | 166:240bc5a0f42a | 522 | /****** Thread image process ******/ |
thedo | 166:240bc5a0f42a | 523 | static void img_draw_objects(void) |
thedo | 166:240bc5a0f42a | 524 | { |
thedo | 166:240bc5a0f42a | 525 | graphicFrameworkCanvas myCanvas(user_frame_buffer_draw, 0x01E0, |
thedo | 166:240bc5a0f42a | 526 | 0x0110, (uint8_t)DRAW_BUFFER_BYTE_PER_PIXEL, |
thedo | 166:240bc5a0f42a | 527 | (uint8_t)DRAW_POINT,0x06); |
thedo | 166:240bc5a0f42a | 528 | |
thedo | 166:240bc5a0f42a | 529 | initDrawResultLayer(); |
thedo | 166:240bc5a0f42a | 530 | |
thedo | 166:240bc5a0f42a | 531 | uint8_t color[2] = {0x0B,0xFF};// Color Pink |
thedo | 166:240bc5a0f42a | 532 | APP_MODE oldMode = appMode; |
thedo | 166:240bc5a0f42a | 533 | while(1) |
thedo | 166:240bc5a0f42a | 534 | { |
thedo | 166:240bc5a0f42a | 535 | Thread::signal_wait(1); |
thedo | 166:240bc5a0f42a | 536 | memset(user_frame_buffer_draw, 0, sizeof(user_frame_buffer_draw)); |
thedo | 166:240bc5a0f42a | 537 | |
thedo | 166:240bc5a0f42a | 538 | if ( oldMode != appMode) |
thedo | 166:240bc5a0f42a | 539 | { |
thedo | 166:240bc5a0f42a | 540 | oldMode = appMode; |
thedo | 166:240bc5a0f42a | 541 | |
thedo | 166:240bc5a0f42a | 542 | mMutexObjects.lock(); |
thedo | 166:240bc5a0f42a | 543 | gIsDrawing = false; |
thedo | 166:240bc5a0f42a | 544 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 545 | |
thedo | 166:240bc5a0f42a | 546 | // Data cache clean |
thedo | 166:240bc5a0f42a | 547 | dcache_clean(user_frame_buffer_draw, sizeof(user_frame_buffer_draw)); |
thedo | 166:240bc5a0f42a | 548 | continue; |
thedo | 166:240bc5a0f42a | 549 | } |
thedo | 166:240bc5a0f42a | 550 | |
thedo | 166:240bc5a0f42a | 551 | // Draw faces on screen |
thedo | 166:240bc5a0f42a | 552 | switch(appMode) |
thedo | 166:240bc5a0f42a | 553 | { |
thedo | 166:240bc5a0f42a | 554 | case FACE_DETECTION: |
thedo | 166:240bc5a0f42a | 555 | case MOTION_DETECTION: |
thedo | 166:240bc5a0f42a | 556 | { |
thedo | 166:240bc5a0f42a | 557 | if(gObjectDetects.size() > 0) |
thedo | 166:240bc5a0f42a | 558 | { |
thedo | 166:240bc5a0f42a | 559 | for(int i = 0;i < gObjectDetects.size();i++) |
thedo | 166:240bc5a0f42a | 560 | { |
thedo | 166:240bc5a0f42a | 561 | int _x = gObjectDetects[i].obj.x*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 562 | int _y = gObjectDetects[i].obj.y*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 563 | int _w = gObjectDetects[i].obj.width*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 564 | int _h = gObjectDetects[i].obj.height*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 565 | myCanvas.drawRect(_x,_y,_w,_h,color); |
thedo | 166:240bc5a0f42a | 566 | } |
thedo | 166:240bc5a0f42a | 567 | } |
thedo | 166:240bc5a0f42a | 568 | gObjectDetects.clear(); |
thedo | 166:240bc5a0f42a | 569 | break; |
thedo | 166:240bc5a0f42a | 570 | } |
thedo | 166:240bc5a0f42a | 571 | case FACE_RECOGNITION: |
thedo | 166:240bc5a0f42a | 572 | { |
thedo | 166:240bc5a0f42a | 573 | if(gObjectDetects.size() > 0) |
thedo | 166:240bc5a0f42a | 574 | { |
thedo | 166:240bc5a0f42a | 575 | for(int i = 0;i < gObjectDetects.size();i++) |
thedo | 166:240bc5a0f42a | 576 | { |
thedo | 166:240bc5a0f42a | 577 | int _x = gObjectDetects[i].obj.x*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 578 | int _y = gObjectDetects[i].obj.y*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 579 | int _w = gObjectDetects[i].obj.width*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 580 | int _h = gObjectDetects[i].obj.height*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 581 | if(gObjectDetects[i].label == 1) |
thedo | 166:240bc5a0f42a | 582 | { |
thedo | 166:240bc5a0f42a | 583 | // Yellow |
thedo | 166:240bc5a0f42a | 584 | color[0] = 0xF0; |
thedo | 166:240bc5a0f42a | 585 | color[1] = 0xFF; |
thedo | 166:240bc5a0f42a | 586 | } |
thedo | 166:240bc5a0f42a | 587 | else if (gObjectDetects[i].label == 2) |
thedo | 166:240bc5a0f42a | 588 | { |
thedo | 166:240bc5a0f42a | 589 | // Green |
thedo | 166:240bc5a0f42a | 590 | color[0] = 0xF0; |
thedo | 166:240bc5a0f42a | 591 | color[1] = 0xF0; |
thedo | 166:240bc5a0f42a | 592 | } |
thedo | 166:240bc5a0f42a | 593 | else |
thedo | 166:240bc5a0f42a | 594 | { |
thedo | 166:240bc5a0f42a | 595 | // Pink |
thedo | 166:240bc5a0f42a | 596 | color[0] = 0x0B; |
thedo | 166:240bc5a0f42a | 597 | color[1] = 0xFF; |
thedo | 166:240bc5a0f42a | 598 | } |
thedo | 166:240bc5a0f42a | 599 | myCanvas.drawRect(_x,_y,_w,_h,color); |
thedo | 166:240bc5a0f42a | 600 | } |
thedo | 166:240bc5a0f42a | 601 | } |
thedo | 166:240bc5a0f42a | 602 | gObjectDetects.clear(); |
thedo | 166:240bc5a0f42a | 603 | break; |
thedo | 166:240bc5a0f42a | 604 | } |
thedo | 166:240bc5a0f42a | 605 | case GUESTURE_RECOGNITION: |
thedo | 166:240bc5a0f42a | 606 | { |
thedo | 166:240bc5a0f42a | 607 | uint8_t contoursColor[2] = {0xF0,0xFF}; |
thedo | 166:240bc5a0f42a | 608 | |
thedo | 166:240bc5a0f42a | 609 | //Draw max contour |
thedo | 166:240bc5a0f42a | 610 | for(int i = 0; i < gGestureResult.contour.size();i++)//i=0 |
thedo | 166:240bc5a0f42a | 611 | { |
thedo | 166:240bc5a0f42a | 612 | myCanvas.draw_pixel(gGestureResult.contour[i].x, |
thedo | 166:240bc5a0f42a | 613 | gGestureResult.contour[i].y,contoursColor); |
thedo | 166:240bc5a0f42a | 614 | } |
thedo | 166:240bc5a0f42a | 615 | // Draw lines, circles |
thedo | 166:240bc5a0f42a | 616 | for(int i = 0;i < gGestureResult.lines.size();i++) |
thedo | 166:240bc5a0f42a | 617 | { |
thedo | 166:240bc5a0f42a | 618 | myCanvas.drawLine(gGestureResult.lines[i].x1, |
thedo | 166:240bc5a0f42a | 619 | gGestureResult.lines[i].y1, |
thedo | 166:240bc5a0f42a | 620 | gGestureResult.lines[i].x2, |
thedo | 166:240bc5a0f42a | 621 | gGestureResult.lines[i].y2, |
thedo | 166:240bc5a0f42a | 622 | gGestureResult.lines[i].color); |
thedo | 166:240bc5a0f42a | 623 | } |
thedo | 166:240bc5a0f42a | 624 | |
thedo | 166:240bc5a0f42a | 625 | for(int i = 0;i < gGestureResult.circles.size();i++) |
thedo | 166:240bc5a0f42a | 626 | { |
thedo | 166:240bc5a0f42a | 627 | myCanvas.drawCircle(gGestureResult.circles[i].x, |
thedo | 166:240bc5a0f42a | 628 | gGestureResult.circles[i].y, |
thedo | 166:240bc5a0f42a | 629 | gGestureResult.circles[i].radius, |
thedo | 166:240bc5a0f42a | 630 | gGestureResult.circles[i].color); |
thedo | 166:240bc5a0f42a | 631 | } |
thedo | 166:240bc5a0f42a | 632 | break; |
thedo | 166:240bc5a0f42a | 633 | } |
thedo | 166:240bc5a0f42a | 634 | default: |
thedo | 166:240bc5a0f42a | 635 | break; |
thedo | 166:240bc5a0f42a | 636 | } // switch |
thedo | 166:240bc5a0f42a | 637 | |
thedo | 166:240bc5a0f42a | 638 | mMutexObjects.lock(); |
thedo | 166:240bc5a0f42a | 639 | gIsDrawing = false; |
thedo | 166:240bc5a0f42a | 640 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 641 | |
thedo | 166:240bc5a0f42a | 642 | // Data cache clean |
thedo | 166:240bc5a0f42a | 643 | dcache_clean(user_frame_buffer_draw, sizeof(user_frame_buffer_draw)); |
thedo | 166:240bc5a0f42a | 644 | }//while |
thedo | 166:240bc5a0f42a | 645 | } |
thedo | 166:240bc5a0f42a | 646 | |
thedo | 166:240bc5a0f42a | 647 | /* Touch task*/ |
thedo | 166:240bc5a0f42a | 648 | static void touch_int_callback(void) |
thedo | 166:240bc5a0f42a | 649 | { |
thedo | 166:240bc5a0f42a | 650 | semTouch.release(); |
thedo | 166:240bc5a0f42a | 651 | } |
thedo | 166:240bc5a0f42a | 652 | static void touch_task(void) |
thedo | 166:240bc5a0f42a | 653 | { |
thedo | 166:240bc5a0f42a | 654 | graphicFrameworkCanvas myCanvasButton(user_frame_buffer_draw_button, 0x01E0, |
thedo | 166:240bc5a0f42a | 655 | 0x0110, (uint8_t)DRAW_BUFFER_BYTE_PER_PIXEL, |
thedo | 166:240bc5a0f42a | 656 | (uint8_t)DRAW_POINT,0x06); |
thedo | 166:240bc5a0f42a | 657 | TouchKey::touch_pos_t touch_pos[TOUCH_NUM]; |
thedo | 166:240bc5a0f42a | 658 | |
thedo | 166:240bc5a0f42a | 659 | /* Callback setting */ |
thedo | 166:240bc5a0f42a | 660 | touch.SetCallback(&touch_int_callback); |
thedo | 166:240bc5a0f42a | 661 | |
thedo | 166:240bc5a0f42a | 662 | /* Reset touch IC */ |
thedo | 166:240bc5a0f42a | 663 | touch.Reset(); |
thedo | 166:240bc5a0f42a | 664 | |
thedo | 166:240bc5a0f42a | 665 | initDrawButtonLayer(); |
thedo | 166:240bc5a0f42a | 666 | drawTextScreen(myCanvasButton); |
thedo | 166:240bc5a0f42a | 667 | drawButtonControls(myCanvasButton); |
thedo | 166:240bc5a0f42a | 668 | |
thedo | 166:240bc5a0f42a | 669 | int x_touch = -1, y_touch = -1; |
thedo | 166:240bc5a0f42a | 670 | |
thedo | 166:240bc5a0f42a | 671 | set_time(0);//set_time(1498450609);//11:15,Mon-26-June |
thedo | 166:240bc5a0f42a | 672 | double seconds = (double)time(NULL); |
thedo | 166:240bc5a0f42a | 673 | |
thedo | 166:240bc5a0f42a | 674 | while(1) |
thedo | 166:240bc5a0f42a | 675 | { |
thedo | 166:240bc5a0f42a | 676 | /* Wait touch event */ |
thedo | 166:240bc5a0f42a | 677 | semTouch.wait(); |
thedo | 166:240bc5a0f42a | 678 | |
thedo | 166:240bc5a0f42a | 679 | touch.GetCoordinates(TOUCH_NUM, touch_pos); |
thedo | 166:240bc5a0f42a | 680 | |
thedo | 166:240bc5a0f42a | 681 | for (int i = 0; i < TOUCH_NUM; i ++) { |
thedo | 166:240bc5a0f42a | 682 | if (touch_pos[i].valid) { |
thedo | 166:240bc5a0f42a | 683 | int new_touch_x = touch_pos[i].x; |
thedo | 166:240bc5a0f42a | 684 | int new_touch_y = touch_pos[i].y; |
thedo | 166:240bc5a0f42a | 685 | APP_MODE mode = getFunctionSelected(new_touch_x, new_touch_y); |
thedo | 166:240bc5a0f42a | 686 | |
thedo | 166:240bc5a0f42a | 687 | if(mode != appMode && mode != MODE_UNKNOWN) |
thedo | 166:240bc5a0f42a | 688 | { |
thedo | 166:240bc5a0f42a | 689 | appMode = mode; |
thedo | 166:240bc5a0f42a | 690 | memset(user_frame_buffer_draw_button, 0, sizeof(uint8_t)*LCD_PIXEL_WIDTH*(MODE_BTN_Y)*FRAME_BUFFER_BYTE_PER_PIXEL); |
thedo | 166:240bc5a0f42a | 691 | drawTextScreen(myCanvasButton); |
thedo | 166:240bc5a0f42a | 692 | dcache_clean(user_frame_buffer_draw_button, sizeof(user_frame_buffer_draw_button)); |
thedo | 166:240bc5a0f42a | 693 | } |
thedo | 166:240bc5a0f42a | 694 | else if (appMode == FACE_RECOGNITION) |
thedo | 166:240bc5a0f42a | 695 | { |
thedo | 166:240bc5a0f42a | 696 | double time_1 = (double)time(NULL) - seconds; |
thedo | 166:240bc5a0f42a | 697 | int posAbs = abs(new_touch_x - x_touch) + |
thedo | 166:240bc5a0f42a | 698 | abs(new_touch_y - y_touch); |
thedo | 166:240bc5a0f42a | 699 | |
thedo | 166:240bc5a0f42a | 700 | if(posAbs > 5 || time_1 > 0.5) //1s |
thedo | 166:240bc5a0f42a | 701 | { |
thedo | 166:240bc5a0f42a | 702 | x_touch = new_touch_x; |
thedo | 166:240bc5a0f42a | 703 | y_touch = new_touch_y; |
thedo | 166:240bc5a0f42a | 704 | |
thedo | 166:240bc5a0f42a | 705 | clickActionFaceReg(new_touch_x,new_touch_y); |
thedo | 166:240bc5a0f42a | 706 | |
thedo | 166:240bc5a0f42a | 707 | } |
thedo | 166:240bc5a0f42a | 708 | seconds = (double)time(NULL); |
thedo | 166:240bc5a0f42a | 709 | } |
thedo | 166:240bc5a0f42a | 710 | else if (appMode == GUESTURE_RECOGNITION) |
thedo | 166:240bc5a0f42a | 711 | { |
thedo | 166:240bc5a0f42a | 712 | double time_1 = (double)time(NULL) - seconds; |
thedo | 166:240bc5a0f42a | 713 | int posAbs = abs(new_touch_x - x_touch) + |
thedo | 166:240bc5a0f42a | 714 | abs(new_touch_y - y_touch); |
thedo | 166:240bc5a0f42a | 715 | |
thedo | 166:240bc5a0f42a | 716 | if(posAbs > 5 || time_1 > 0.5) //1s |
thedo | 166:240bc5a0f42a | 717 | { |
thedo | 166:240bc5a0f42a | 718 | x_touch = new_touch_x; |
thedo | 166:240bc5a0f42a | 719 | y_touch = new_touch_y; |
thedo | 166:240bc5a0f42a | 720 | clickActionGestureReg(new_touch_x,new_touch_y); |
thedo | 166:240bc5a0f42a | 721 | } |
thedo | 166:240bc5a0f42a | 722 | |
thedo | 166:240bc5a0f42a | 723 | seconds = (double)time(NULL); |
thedo | 166:240bc5a0f42a | 724 | } |
thedo | 166:240bc5a0f42a | 725 | } |
thedo | 166:240bc5a0f42a | 726 | } |
thedo | 166:240bc5a0f42a | 727 | } |
thedo | 166:240bc5a0f42a | 728 | } |
thedo | 166:240bc5a0f42a | 729 | |
thedo | 166:240bc5a0f42a | 730 | /****** Video input is output to LCD ******/ |
thedo | 166:240bc5a0f42a | 731 | static void video_lcd_task(void) { |
thedo | 166:240bc5a0f42a | 732 | DisplayBase::graphics_error_t error; |
thedo | 166:240bc5a0f42a | 733 | int wk_num; |
thedo | 166:240bc5a0f42a | 734 | |
thedo | 166:240bc5a0f42a | 735 | /* Initialization memory */ |
thedo | 166:240bc5a0f42a | 736 | for (int i = 0; i < FRAME_BUFFER_NUM; i++) { |
thedo | 166:240bc5a0f42a | 737 | memset(FrameBufferTbl[i], 0, (FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT)); |
thedo | 166:240bc5a0f42a | 738 | dcache_clean(FrameBufferTbl[i],(FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT)); |
thedo | 166:240bc5a0f42a | 739 | } |
thedo | 166:240bc5a0f42a | 740 | |
thedo | 166:240bc5a0f42a | 741 | /* Start of Video */ |
thedo | 166:240bc5a0f42a | 742 | Start_Video(FrameBufferTbl[write_buff_num]); |
thedo | 166:240bc5a0f42a | 743 | |
thedo | 166:240bc5a0f42a | 744 | /* Wait for first video drawing */ |
thedo | 166:240bc5a0f42a | 745 | Thread::signal_wait(1); |
thedo | 166:240bc5a0f42a | 746 | write_buff_num++; |
thedo | 166:240bc5a0f42a | 747 | if (write_buff_num >= FRAME_BUFFER_NUM) { |
thedo | 166:240bc5a0f42a | 748 | write_buff_num = 0; |
thedo | 166:240bc5a0f42a | 749 | } |
thedo | 166:240bc5a0f42a | 750 | error = Display.Video_Write_Change(VIDEO_INPUT_CH, |
thedo | 166:240bc5a0f42a | 751 | FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE); |
thedo | 166:240bc5a0f42a | 752 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 753 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 754 | mbed_die(); |
thedo | 166:240bc5a0f42a | 755 | } |
thedo | 166:240bc5a0f42a | 756 | |
thedo | 166:240bc5a0f42a | 757 | /* Start of LCD */ |
thedo | 166:240bc5a0f42a | 758 | Start_LCD_Display(FrameBufferTbl[read_buff_num]); |
thedo | 166:240bc5a0f42a | 759 | |
thedo | 166:240bc5a0f42a | 760 | /* Backlight on */ |
thedo | 166:240bc5a0f42a | 761 | Thread::wait(200); |
thedo | 166:240bc5a0f42a | 762 | lcd_cntrst.write(1.0); |
thedo | 166:240bc5a0f42a | 763 | |
thedo | 166:240bc5a0f42a | 764 | while (1) { |
thedo | 166:240bc5a0f42a | 765 | Thread::signal_wait(1); |
thedo | 166:240bc5a0f42a | 766 | wk_num = write_buff_num + 1; |
thedo | 166:240bc5a0f42a | 767 | if (wk_num >= FRAME_BUFFER_NUM) { |
thedo | 166:240bc5a0f42a | 768 | wk_num = 0; |
thedo | 166:240bc5a0f42a | 769 | } |
thedo | 166:240bc5a0f42a | 770 | /* If the next buffer is empty, it's changed. */ |
thedo | 166:240bc5a0f42a | 771 | if (wk_num != read_buff_num) { |
thedo | 166:240bc5a0f42a | 772 | read_buff_num = write_buff_num; |
thedo | 166:240bc5a0f42a | 773 | write_buff_num = wk_num; |
thedo | 166:240bc5a0f42a | 774 | |
thedo | 166:240bc5a0f42a | 775 | /* Change video buffer */ |
thedo | 166:240bc5a0f42a | 776 | error = Display.Video_Write_Change(VIDEO_INPUT_CH, |
thedo | 166:240bc5a0f42a | 777 | FrameBufferTbl[0/*write_buff_num*/], FRAME_BUFFER_STRIDE); |
thedo | 166:240bc5a0f42a | 778 | if (error != DisplayBase::GRAPHICS_OK) { |
thedo | 166:240bc5a0f42a | 779 | printf("Line %d, error %d\n", __LINE__, error); |
thedo | 166:240bc5a0f42a | 780 | mbed_die(); |
thedo | 166:240bc5a0f42a | 781 | } |
thedo | 166:240bc5a0f42a | 782 | |
thedo | 166:240bc5a0f42a | 783 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 784 | if ( gIsProcessing == false) |
thedo | 166:240bc5a0f42a | 785 | { |
thedo | 166:240bc5a0f42a | 786 | gIsProcessing = true; |
thedo | 166:240bc5a0f42a | 787 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 788 | |
thedo | 166:240bc5a0f42a | 789 | memcpy((void *)my_frame,(void*)FrameBufferTbl[0], |
thedo | 166:240bc5a0f42a | 790 | FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT); |
thedo | 166:240bc5a0f42a | 791 | semProcessThread.release(); |
thedo | 166:240bc5a0f42a | 792 | } |
thedo | 166:240bc5a0f42a | 793 | else |
thedo | 166:240bc5a0f42a | 794 | { |
thedo | 166:240bc5a0f42a | 795 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 796 | } |
thedo | 166:240bc5a0f42a | 797 | |
thedo | 166:240bc5a0f42a | 798 | /* Change LCD buffer */ |
thedo | 166:240bc5a0f42a | 799 | Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, |
thedo | 166:240bc5a0f42a | 800 | (void *)FrameBufferTbl[0/*read_buff_num*/]); |
thedo | 166:240bc5a0f42a | 801 | } |
thedo | 166:240bc5a0f42a | 802 | } |
thedo | 166:240bc5a0f42a | 803 | } |
thedo | 166:240bc5a0f42a | 804 | |
thedo | 166:240bc5a0f42a | 805 | bool initSdCard() |
thedo | 166:240bc5a0f42a | 806 | { |
thedo | 166:240bc5a0f42a | 807 | if(myStorage == NULL) |
thedo | 166:240bc5a0f42a | 808 | { |
thedo | 166:240bc5a0f42a | 809 | return false; |
thedo | 166:240bc5a0f42a | 810 | } |
thedo | 166:240bc5a0f42a | 811 | if (myStorage->isConnectSdCard() == STORG_PASS) |
thedo | 166:240bc5a0f42a | 812 | { |
thedo | 166:240bc5a0f42a | 813 | if(myStorage->mountSdCard() == STORG_PASS) |
thedo | 166:240bc5a0f42a | 814 | { |
thedo | 166:240bc5a0f42a | 815 | return true; |
thedo | 166:240bc5a0f42a | 816 | } |
thedo | 166:240bc5a0f42a | 817 | else |
thedo | 166:240bc5a0f42a | 818 | { |
thedo | 166:240bc5a0f42a | 819 | // mount sdcard failed! |
thedo | 166:240bc5a0f42a | 820 | return false; |
thedo | 166:240bc5a0f42a | 821 | } |
thedo | 166:240bc5a0f42a | 822 | } |
thedo | 166:240bc5a0f42a | 823 | else |
thedo | 166:240bc5a0f42a | 824 | { |
thedo | 166:240bc5a0f42a | 825 | // no sdcard! |
thedo | 166:240bc5a0f42a | 826 | togle_led(LED_RED); |
thedo | 166:240bc5a0f42a | 827 | return false; |
thedo | 166:240bc5a0f42a | 828 | } |
thedo | 166:240bc5a0f42a | 829 | } |
thedo | 166:240bc5a0f42a | 830 | void faceDectectionApp(void) |
thedo | 166:240bc5a0f42a | 831 | { |
thedo | 166:240bc5a0f42a | 832 | Size face_size(LCD_PIXEL_WIDTH/IMG_DOWN_SAMPLE, |
thedo | 166:240bc5a0f42a | 833 | LCD_PIXEL_HEIGHT/IMG_DOWN_SAMPLE); |
thedo | 166:240bc5a0f42a | 834 | Mat smallImage = Mat::zeros(face_size, CV_8UC1); |
thedo | 166:240bc5a0f42a | 835 | CascadeClassifier haar_cascade; |
thedo | 166:240bc5a0f42a | 836 | vector<Rect> faces; |
thedo | 166:240bc5a0f42a | 837 | if (!haar_cascade.load("/SD/lbpcascade_frontalface.xml")) |
thedo | 166:240bc5a0f42a | 838 | { |
thedo | 166:240bc5a0f42a | 839 | // load failed |
thedo | 166:240bc5a0f42a | 840 | togle_led(LED_RED); |
thedo | 166:240bc5a0f42a | 841 | while(1) |
thedo | 166:240bc5a0f42a | 842 | { |
thedo | 166:240bc5a0f42a | 843 | wait(0.5); |
thedo | 166:240bc5a0f42a | 844 | } |
thedo | 166:240bc5a0f42a | 845 | } |
thedo | 166:240bc5a0f42a | 846 | else{ |
thedo | 166:240bc5a0f42a | 847 | togle_led(LED_GREEN); |
thedo | 166:240bc5a0f42a | 848 | } |
thedo | 166:240bc5a0f42a | 849 | togle_reset(LED_RED,LED_BLUE); |
thedo | 166:240bc5a0f42a | 850 | faces.clear(); |
thedo | 166:240bc5a0f42a | 851 | |
thedo | 166:240bc5a0f42a | 852 | gObjectDetects.clear(); |
thedo | 166:240bc5a0f42a | 853 | while (1) { |
thedo | 166:240bc5a0f42a | 854 | semProcessThread.wait(); |
thedo | 166:240bc5a0f42a | 855 | |
thedo | 166:240bc5a0f42a | 856 | if ( appMode != FACE_DETECTION ) |
thedo | 166:240bc5a0f42a | 857 | { |
thedo | 166:240bc5a0f42a | 858 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 859 | gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 860 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 861 | break; |
thedo | 166:240bc5a0f42a | 862 | } |
thedo | 166:240bc5a0f42a | 863 | |
thedo | 166:240bc5a0f42a | 864 | Mat gray; |
thedo | 166:240bc5a0f42a | 865 | { |
thedo | 166:240bc5a0f42a | 866 | Mat res = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH, |
thedo | 166:240bc5a0f42a | 867 | (int)LCD_PIXEL_HEIGHT,2); |
thedo | 166:240bc5a0f42a | 868 | cvtColor(res,gray,COLOR_RGB2GRAY); |
thedo | 166:240bc5a0f42a | 869 | res.release(); |
thedo | 166:240bc5a0f42a | 870 | } |
thedo | 166:240bc5a0f42a | 871 | |
thedo | 166:240bc5a0f42a | 872 | equalizeHist(gray,gray); |
thedo | 166:240bc5a0f42a | 873 | resize(gray, smallImage, face_size); |
thedo | 166:240bc5a0f42a | 874 | |
thedo | 166:240bc5a0f42a | 875 | haar_cascade.detectMultiScale(smallImage,faces,1.1, |
thedo | 166:240bc5a0f42a | 876 | 2,0|CV_HAAR_SCALE_IMAGE,Size(10,10)); |
thedo | 166:240bc5a0f42a | 877 | mMutexObjects.lock(); |
thedo | 166:240bc5a0f42a | 878 | if(gIsDrawing == false) |
thedo | 166:240bc5a0f42a | 879 | { |
thedo | 166:240bc5a0f42a | 880 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 881 | for(int i = 0;i < faces.size();i++) |
thedo | 166:240bc5a0f42a | 882 | { |
thedo | 166:240bc5a0f42a | 883 | obj_detect_result tmp; |
thedo | 166:240bc5a0f42a | 884 | tmp.obj = faces[i]; |
thedo | 166:240bc5a0f42a | 885 | tmp.label = -1; |
thedo | 166:240bc5a0f42a | 886 | gObjectDetects.push_back(tmp); |
thedo | 166:240bc5a0f42a | 887 | } |
thedo | 166:240bc5a0f42a | 888 | //gObjectDetects = faces; |
thedo | 166:240bc5a0f42a | 889 | gIsDrawing = true; |
thedo | 166:240bc5a0f42a | 890 | p_DrawObjects->signal_set(1); |
thedo | 166:240bc5a0f42a | 891 | } |
thedo | 166:240bc5a0f42a | 892 | else |
thedo | 166:240bc5a0f42a | 893 | { |
thedo | 166:240bc5a0f42a | 894 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 895 | } |
thedo | 166:240bc5a0f42a | 896 | |
thedo | 166:240bc5a0f42a | 897 | /* Reset flag */ |
thedo | 166:240bc5a0f42a | 898 | faces.clear(); |
thedo | 166:240bc5a0f42a | 899 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 900 | gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 901 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 902 | }; |
thedo | 166:240bc5a0f42a | 903 | } |
thedo | 166:240bc5a0f42a | 904 | |
thedo | 166:240bc5a0f42a | 905 | void motionDetectionApp(void) |
thedo | 166:240bc5a0f42a | 906 | { |
thedo | 166:240bc5a0f42a | 907 | bool isNewStart = true; |
thedo | 166:240bc5a0f42a | 908 | int threshValue = 30; |
thedo | 166:240bc5a0f42a | 909 | int blurSize = 5; |
thedo | 166:240bc5a0f42a | 910 | float mArea = 0.0; |
thedo | 166:240bc5a0f42a | 911 | float mMaxArea = 0.0; |
thedo | 166:240bc5a0f42a | 912 | int mMaxIndex = 0; |
thedo | 166:240bc5a0f42a | 913 | bool _isDrawing; |
thedo | 166:240bc5a0f42a | 914 | int mCounter = 0; |
thedo | 166:240bc5a0f42a | 915 | Mat curFrameGray; |
thedo | 166:240bc5a0f42a | 916 | Mat prevFrameGray; |
thedo | 166:240bc5a0f42a | 917 | Mat diffImage; |
thedo | 166:240bc5a0f42a | 918 | Mat binImage; |
thedo | 166:240bc5a0f42a | 919 | vector<vector<Point> > contours; |
thedo | 166:240bc5a0f42a | 920 | vector<Rect> _objects; |
thedo | 166:240bc5a0f42a | 921 | |
thedo | 166:240bc5a0f42a | 922 | gObjectDetects.clear(); |
thedo | 166:240bc5a0f42a | 923 | while(1) |
thedo | 166:240bc5a0f42a | 924 | { |
thedo | 166:240bc5a0f42a | 925 | semProcessThread.wait(); |
thedo | 166:240bc5a0f42a | 926 | |
thedo | 166:240bc5a0f42a | 927 | if ( appMode != MOTION_DETECTION ) |
thedo | 166:240bc5a0f42a | 928 | { |
thedo | 166:240bc5a0f42a | 929 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 930 | gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 931 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 932 | |
thedo | 166:240bc5a0f42a | 933 | break; |
thedo | 166:240bc5a0f42a | 934 | } |
thedo | 166:240bc5a0f42a | 935 | |
thedo | 166:240bc5a0f42a | 936 | _objects.clear(); |
thedo | 166:240bc5a0f42a | 937 | mCounter++; |
thedo | 166:240bc5a0f42a | 938 | if( isNewStart == false) |
thedo | 166:240bc5a0f42a | 939 | { |
thedo | 166:240bc5a0f42a | 940 | { |
thedo | 166:240bc5a0f42a | 941 | Mat res = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH, |
thedo | 166:240bc5a0f42a | 942 | (int)LCD_PIXEL_HEIGHT,2); |
thedo | 166:240bc5a0f42a | 943 | cvtColor(res,curFrameGray,COLOR_RGB2GRAY); |
thedo | 166:240bc5a0f42a | 944 | res.release(); |
thedo | 166:240bc5a0f42a | 945 | } |
thedo | 166:240bc5a0f42a | 946 | /* differential between foreground and background */ |
thedo | 166:240bc5a0f42a | 947 | absdiff(curFrameGray, prevFrameGray, diffImage); |
thedo | 166:240bc5a0f42a | 948 | blur(diffImage, diffImage, Size(blurSize, blurSize)); |
thedo | 166:240bc5a0f42a | 949 | threshold(diffImage, binImage, threshValue, 255, CV_THRESH_BINARY); |
thedo | 166:240bc5a0f42a | 950 | findContours(binImage, contours, CV_RETR_EXTERNAL, |
thedo | 166:240bc5a0f42a | 951 | CV_CHAIN_APPROX_NONE); |
thedo | 166:240bc5a0f42a | 952 | |
thedo | 166:240bc5a0f42a | 953 | if(contours.size() > 0) |
thedo | 166:240bc5a0f42a | 954 | { |
thedo | 166:240bc5a0f42a | 955 | for (int i = 0; i < contours.size(); i++) |
thedo | 166:240bc5a0f42a | 956 | { |
thedo | 166:240bc5a0f42a | 957 | mArea = contourArea(contours[i]); |
thedo | 166:240bc5a0f42a | 958 | if (mArea > mMaxArea) |
thedo | 166:240bc5a0f42a | 959 | { |
thedo | 166:240bc5a0f42a | 960 | mMaxArea = mArea; |
thedo | 166:240bc5a0f42a | 961 | mMaxIndex = i; |
thedo | 166:240bc5a0f42a | 962 | } |
thedo | 166:240bc5a0f42a | 963 | } |
thedo | 166:240bc5a0f42a | 964 | |
thedo | 166:240bc5a0f42a | 965 | if (mMaxArea > MAX_COUNTOURS) |
thedo | 166:240bc5a0f42a | 966 | { |
thedo | 166:240bc5a0f42a | 967 | Rect objectBoundingRectangle = boundingRect( |
thedo | 166:240bc5a0f42a | 968 | contours.at(mMaxIndex)); |
thedo | 166:240bc5a0f42a | 969 | _objects.push_back(objectBoundingRectangle); |
thedo | 166:240bc5a0f42a | 970 | } |
thedo | 166:240bc5a0f42a | 971 | } |
thedo | 166:240bc5a0f42a | 972 | |
thedo | 166:240bc5a0f42a | 973 | /* Set display motion objects */ |
thedo | 166:240bc5a0f42a | 974 | mMutexObjects.lock(); |
thedo | 166:240bc5a0f42a | 975 | _isDrawing = gIsDrawing; |
thedo | 166:240bc5a0f42a | 976 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 977 | |
thedo | 166:240bc5a0f42a | 978 | if(_isDrawing == false) |
thedo | 166:240bc5a0f42a | 979 | { |
thedo | 166:240bc5a0f42a | 980 | for(int i = 0;i < _objects.size();i++) |
thedo | 166:240bc5a0f42a | 981 | { |
thedo | 166:240bc5a0f42a | 982 | obj_detect_result tmp; |
thedo | 166:240bc5a0f42a | 983 | tmp.obj = _objects[i]; |
thedo | 166:240bc5a0f42a | 984 | tmp.label = -1; |
thedo | 166:240bc5a0f42a | 985 | gObjectDetects.push_back(tmp); |
thedo | 166:240bc5a0f42a | 986 | } |
thedo | 166:240bc5a0f42a | 987 | //gObjectDetects = _objects; |
thedo | 166:240bc5a0f42a | 988 | gIsDrawing = true; |
thedo | 166:240bc5a0f42a | 989 | p_DrawObjects->signal_set(1); |
thedo | 166:240bc5a0f42a | 990 | } |
thedo | 166:240bc5a0f42a | 991 | |
thedo | 166:240bc5a0f42a | 992 | /* Reset values */ |
thedo | 166:240bc5a0f42a | 993 | mMaxArea = 0; |
thedo | 166:240bc5a0f42a | 994 | mArea = 0; |
thedo | 166:240bc5a0f42a | 995 | mMaxIndex = 0; |
thedo | 166:240bc5a0f42a | 996 | |
thedo | 166:240bc5a0f42a | 997 | /* Update background */ |
thedo | 166:240bc5a0f42a | 998 | if(mCounter == 50) |
thedo | 166:240bc5a0f42a | 999 | { |
thedo | 166:240bc5a0f42a | 1000 | mCounter = 0; |
thedo | 166:240bc5a0f42a | 1001 | isNewStart = true; |
thedo | 166:240bc5a0f42a | 1002 | } |
thedo | 166:240bc5a0f42a | 1003 | } |
thedo | 166:240bc5a0f42a | 1004 | else |
thedo | 166:240bc5a0f42a | 1005 | { |
thedo | 166:240bc5a0f42a | 1006 | isNewStart = false; |
thedo | 166:240bc5a0f42a | 1007 | prevFrameGray = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH, |
thedo | 166:240bc5a0f42a | 1008 | (int)LCD_PIXEL_HEIGHT,2); |
thedo | 166:240bc5a0f42a | 1009 | cvtColor(prevFrameGray,prevFrameGray,COLOR_RGB2GRAY); |
thedo | 166:240bc5a0f42a | 1010 | } |
thedo | 166:240bc5a0f42a | 1011 | |
thedo | 166:240bc5a0f42a | 1012 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 1013 | gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 1014 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 1015 | }; |
thedo | 166:240bc5a0f42a | 1016 | } |
thedo | 166:240bc5a0f42a | 1017 | |
thedo | 166:240bc5a0f42a | 1018 | void faceRecognitionApp(void) |
thedo | 166:240bc5a0f42a | 1019 | { |
thedo | 166:240bc5a0f42a | 1020 | // Init draw |
thedo | 166:240bc5a0f42a | 1021 | graphicFrameworkCanvas myCanvas(user_frame_buffer_draw_action, 0x01E0, |
thedo | 166:240bc5a0f42a | 1022 | 0x0110, (uint8_t)DRAW_BUFFER_BYTE_PER_PIXEL, |
thedo | 166:240bc5a0f42a | 1023 | (uint8_t)DRAW_POINT,0x06); |
thedo | 166:240bc5a0f42a | 1024 | |
thedo | 166:240bc5a0f42a | 1025 | uint8_t label_id = 1; |
thedo | 166:240bc5a0f42a | 1026 | bool oldStateFace = false;// no faces |
thedo | 166:240bc5a0f42a | 1027 | // End init draw |
thedo | 166:240bc5a0f42a | 1028 | |
thedo | 166:240bc5a0f42a | 1029 | Size face_size(LCD_PIXEL_WIDTH/IMG_DOWN_SAMPLE, |
thedo | 166:240bc5a0f42a | 1030 | LCD_PIXEL_HEIGHT/IMG_DOWN_SAMPLE); |
thedo | 166:240bc5a0f42a | 1031 | Mat smallImage = Mat::zeros(face_size, CV_8UC1); |
thedo | 166:240bc5a0f42a | 1032 | CascadeClassifier haar_cascade; |
thedo | 166:240bc5a0f42a | 1033 | vector<Rect> faces; |
thedo | 166:240bc5a0f42a | 1034 | |
thedo | 166:240bc5a0f42a | 1035 | //Init recognizer |
thedo | 166:240bc5a0f42a | 1036 | int radius = 2, neighbors = 4, gridx = 8, gridy = 8, thresmax = 50; |
thedo | 166:240bc5a0f42a | 1037 | Ptr<LBPHFaceRecognizer> modelReg = createLBPHFaceRecognizer(radius, neighbors, |
thedo | 166:240bc5a0f42a | 1038 | gridx, gridy, thresmax); |
thedo | 166:240bc5a0f42a | 1039 | face_database_t face_database; |
thedo | 166:240bc5a0f42a | 1040 | Size regSize(70,70); |
thedo | 166:240bc5a0f42a | 1041 | bool flag_class = false; |
thedo | 166:240bc5a0f42a | 1042 | bool flag_train = false; |
thedo | 166:240bc5a0f42a | 1043 | bool isFirstTrain = true; |
thedo | 166:240bc5a0f42a | 1044 | bool changeApp = false; |
thedo | 166:240bc5a0f42a | 1045 | |
thedo | 166:240bc5a0f42a | 1046 | if (!haar_cascade.load("/SD/lbpcascade_frontalface.xml")) |
thedo | 166:240bc5a0f42a | 1047 | { |
thedo | 166:240bc5a0f42a | 1048 | // load failed |
thedo | 166:240bc5a0f42a | 1049 | togle_led(LED_RED); |
thedo | 166:240bc5a0f42a | 1050 | while(1) |
thedo | 166:240bc5a0f42a | 1051 | { |
thedo | 166:240bc5a0f42a | 1052 | wait(0.5); |
thedo | 166:240bc5a0f42a | 1053 | } |
thedo | 166:240bc5a0f42a | 1054 | } |
thedo | 166:240bc5a0f42a | 1055 | else{ |
thedo | 166:240bc5a0f42a | 1056 | togle_led(LED_GREEN); |
thedo | 166:240bc5a0f42a | 1057 | } |
thedo | 166:240bc5a0f42a | 1058 | togle_reset(LED_RED,LED_BLUE); |
thedo | 166:240bc5a0f42a | 1059 | faces.clear(); |
thedo | 166:240bc5a0f42a | 1060 | |
thedo | 166:240bc5a0f42a | 1061 | gObjectDetects.clear(); |
thedo | 166:240bc5a0f42a | 1062 | while(1) |
thedo | 166:240bc5a0f42a | 1063 | { |
thedo | 166:240bc5a0f42a | 1064 | semProcessThread.wait(); |
thedo | 166:240bc5a0f42a | 1065 | |
thedo | 166:240bc5a0f42a | 1066 | if ( appMode != FACE_RECOGNITION ) |
thedo | 166:240bc5a0f42a | 1067 | { |
thedo | 166:240bc5a0f42a | 1068 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 1069 | gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 1070 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 1071 | memset(user_frame_buffer_draw_action, 0, |
thedo | 166:240bc5a0f42a | 1072 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 1073 | break; |
thedo | 166:240bc5a0f42a | 1074 | } |
thedo | 166:240bc5a0f42a | 1075 | |
thedo | 166:240bc5a0f42a | 1076 | Mat gray; |
thedo | 166:240bc5a0f42a | 1077 | Mat imgRgb = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH, |
thedo | 166:240bc5a0f42a | 1078 | (int)LCD_PIXEL_HEIGHT,2); |
thedo | 166:240bc5a0f42a | 1079 | cvtColor(imgRgb,gray,COLOR_RGB2GRAY); |
thedo | 166:240bc5a0f42a | 1080 | |
thedo | 166:240bc5a0f42a | 1081 | equalizeHist(gray,gray); |
thedo | 166:240bc5a0f42a | 1082 | resize(gray, smallImage, face_size); |
thedo | 166:240bc5a0f42a | 1083 | |
thedo | 166:240bc5a0f42a | 1084 | haar_cascade.detectMultiScale(smallImage,faces,1.1, |
thedo | 166:240bc5a0f42a | 1085 | 2,0|CV_HAAR_SCALE_IMAGE,Size(10,10)); |
thedo | 166:240bc5a0f42a | 1086 | |
thedo | 166:240bc5a0f42a | 1087 | mMutexObjects.lock(); |
thedo | 166:240bc5a0f42a | 1088 | if(gIsDrawing == false) |
thedo | 166:240bc5a0f42a | 1089 | { |
thedo | 166:240bc5a0f42a | 1090 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 1091 | |
thedo | 166:240bc5a0f42a | 1092 | if( faces.size() > 0) |
thedo | 166:240bc5a0f42a | 1093 | { |
thedo | 166:240bc5a0f42a | 1094 | // Show label |
thedo | 166:240bc5a0f42a | 1095 | if (oldStateFace == false) |
thedo | 166:240bc5a0f42a | 1096 | { |
thedo | 166:240bc5a0f42a | 1097 | oldStateFace = true; |
thedo | 166:240bc5a0f42a | 1098 | myCanvas.drawImage(my_img_register_face, |
thedo | 166:240bc5a0f42a | 1099 | REGIS_FACE_BTN_X ,REGIS_FACE_BTN_Y); |
thedo | 166:240bc5a0f42a | 1100 | } |
thedo | 166:240bc5a0f42a | 1101 | |
thedo | 166:240bc5a0f42a | 1102 | // Click update database |
thedo | 166:240bc5a0f42a | 1103 | mMutexClicked.lock(); |
thedo | 166:240bc5a0f42a | 1104 | if(clickedCode == CLICKED_REGIS_FACE) |
thedo | 166:240bc5a0f42a | 1105 | { |
thedo | 166:240bc5a0f42a | 1106 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 1107 | |
thedo | 166:240bc5a0f42a | 1108 | // Clean draw faces |
thedo | 166:240bc5a0f42a | 1109 | mMutexObjects.lock(); |
thedo | 166:240bc5a0f42a | 1110 | if(gIsDrawing == false) |
thedo | 166:240bc5a0f42a | 1111 | { |
thedo | 166:240bc5a0f42a | 1112 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 1113 | gObjectDetects.clear(); |
thedo | 166:240bc5a0f42a | 1114 | gIsDrawing = true; |
thedo | 166:240bc5a0f42a | 1115 | p_DrawObjects->signal_set(1); |
thedo | 166:240bc5a0f42a | 1116 | } |
thedo | 166:240bc5a0f42a | 1117 | else |
thedo | 166:240bc5a0f42a | 1118 | { |
thedo | 166:240bc5a0f42a | 1119 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 1120 | } |
thedo | 166:240bc5a0f42a | 1121 | |
thedo | 166:240bc5a0f42a | 1122 | // Update database/ train data |
thedo | 166:240bc5a0f42a | 1123 | face_database.database_image.clear(); |
thedo | 166:240bc5a0f42a | 1124 | face_database.database_label.clear(); |
thedo | 166:240bc5a0f42a | 1125 | flag_train = false; |
thedo | 166:240bc5a0f42a | 1126 | |
thedo | 166:240bc5a0f42a | 1127 | for (int i = 0; i < faces.size(); i++) |
thedo | 166:240bc5a0f42a | 1128 | { |
thedo | 166:240bc5a0f42a | 1129 | // Check exit app |
thedo | 166:240bc5a0f42a | 1130 | if(changeApp == true) |
thedo | 166:240bc5a0f42a | 1131 | { |
thedo | 166:240bc5a0f42a | 1132 | break; |
thedo | 166:240bc5a0f42a | 1133 | } |
thedo | 166:240bc5a0f42a | 1134 | mMutexClicked.lock(); |
thedo | 166:240bc5a0f42a | 1135 | clickedCode = CLICKED_REGIS_FACE; |
thedo | 166:240bc5a0f42a | 1136 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 1137 | |
thedo | 166:240bc5a0f42a | 1138 | int _x = faces[i].x*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 1139 | int _y = faces[i].y*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 1140 | int _w = faces[i].width*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 1141 | int _h = faces[i].height*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 1142 | |
thedo | 166:240bc5a0f42a | 1143 | Rect roi(_x,_y,_w,_h); |
thedo | 166:240bc5a0f42a | 1144 | |
thedo | 166:240bc5a0f42a | 1145 | Mat imgShow = imgRgb(roi); |
thedo | 166:240bc5a0f42a | 1146 | if(_w > 100) |
thedo | 166:240bc5a0f42a | 1147 | { |
thedo | 166:240bc5a0f42a | 1148 | resize(imgShow,imgShow,Size(100,100)); |
thedo | 166:240bc5a0f42a | 1149 | _w = 100; |
thedo | 166:240bc5a0f42a | 1150 | _h = 100; |
thedo | 166:240bc5a0f42a | 1151 | } |
thedo | 166:240bc5a0f42a | 1152 | |
thedo | 166:240bc5a0f42a | 1153 | uint8_t* src = cvtMat2RGBA444(_w,_h,imgShow); |
thedo | 166:240bc5a0f42a | 1154 | |
thedo | 166:240bc5a0f42a | 1155 | label_id = 1; |
thedo | 166:240bc5a0f42a | 1156 | |
thedo | 166:240bc5a0f42a | 1157 | memset(user_frame_buffer_draw_action, 0, |
thedo | 166:240bc5a0f42a | 1158 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 1159 | myCanvas.drawImage(src,100, 90); |
thedo | 166:240bc5a0f42a | 1160 | myCanvas.drawImage(my_img_id_01, |
thedo | 166:240bc5a0f42a | 1161 | FACE_REG_ID_MENU_X ,FACE_REG_ID_MENU_Y); |
thedo | 166:240bc5a0f42a | 1162 | myCanvas.drawImage(my_img_change_id, |
thedo | 166:240bc5a0f42a | 1163 | FACE_REG_ACT_MENU_X ,FACE_REG_ACT_MENU_Y); |
thedo | 166:240bc5a0f42a | 1164 | myCanvas.drawImage(my_img_add_this, |
thedo | 166:240bc5a0f42a | 1165 | FACE_REG_ACT_MENU_X ,FACE_REG_ACT_MENU_Y + 12 + 20); |
thedo | 166:240bc5a0f42a | 1166 | myCanvas.drawImage(my_img_ignore, |
thedo | 166:240bc5a0f42a | 1167 | FACE_REG_ACT_MENU_X ,FACE_REG_ACT_MENU_Y+ 24 + 40); |
thedo | 166:240bc5a0f42a | 1168 | |
thedo | 166:240bc5a0f42a | 1169 | /* Clean cache */ |
thedo | 166:240bc5a0f42a | 1170 | dcache_clean(user_frame_buffer_draw_action, |
thedo | 166:240bc5a0f42a | 1171 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 1172 | while(1) |
thedo | 166:240bc5a0f42a | 1173 | { |
thedo | 166:240bc5a0f42a | 1174 | bool isBreak = false; |
thedo | 166:240bc5a0f42a | 1175 | mMutexClicked.lock(); |
thedo | 166:240bc5a0f42a | 1176 | CLICKED_CODE codeTmp = clickedCode; |
thedo | 166:240bc5a0f42a | 1177 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 1178 | |
thedo | 166:240bc5a0f42a | 1179 | // Check exit app |
thedo | 166:240bc5a0f42a | 1180 | if ( appMode != FACE_RECOGNITION ) |
thedo | 166:240bc5a0f42a | 1181 | { |
thedo | 166:240bc5a0f42a | 1182 | changeApp = true; |
thedo | 166:240bc5a0f42a | 1183 | isBreak = true; |
thedo | 166:240bc5a0f42a | 1184 | break; |
thedo | 166:240bc5a0f42a | 1185 | } |
thedo | 166:240bc5a0f42a | 1186 | |
thedo | 166:240bc5a0f42a | 1187 | switch(codeTmp) |
thedo | 166:240bc5a0f42a | 1188 | { |
thedo | 166:240bc5a0f42a | 1189 | case CLICKED_CHANGE_ID: |
thedo | 166:240bc5a0f42a | 1190 | { |
thedo | 166:240bc5a0f42a | 1191 | memset(user_frame_buffer_draw_action + FACE_REG_ID_MENU_Y*2*LCD_PIXEL_WIDTH, 0, |
thedo | 166:240bc5a0f42a | 1192 | 21*2*LCD_PIXEL_WIDTH);// clear 21 lines |
thedo | 166:240bc5a0f42a | 1193 | // Change ID label |
thedo | 166:240bc5a0f42a | 1194 | if(label_id == 1) |
thedo | 166:240bc5a0f42a | 1195 | { |
thedo | 166:240bc5a0f42a | 1196 | label_id = 2; |
thedo | 166:240bc5a0f42a | 1197 | myCanvas.drawImage(my_img_id_02, |
thedo | 166:240bc5a0f42a | 1198 | FACE_REG_ID_MENU_X ,FACE_REG_ID_MENU_Y); |
thedo | 166:240bc5a0f42a | 1199 | } |
thedo | 166:240bc5a0f42a | 1200 | else |
thedo | 166:240bc5a0f42a | 1201 | { |
thedo | 166:240bc5a0f42a | 1202 | label_id = 1; |
thedo | 166:240bc5a0f42a | 1203 | myCanvas.drawImage(my_img_id_01, |
thedo | 166:240bc5a0f42a | 1204 | FACE_REG_ID_MENU_X ,FACE_REG_ID_MENU_Y); |
thedo | 166:240bc5a0f42a | 1205 | } |
thedo | 166:240bc5a0f42a | 1206 | |
thedo | 166:240bc5a0f42a | 1207 | /* Clean cache */ |
thedo | 166:240bc5a0f42a | 1208 | dcache_clean(user_frame_buffer_draw_action, |
thedo | 166:240bc5a0f42a | 1209 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 1210 | |
thedo | 166:240bc5a0f42a | 1211 | clickedCode = CLICKED_UNKNOWN; |
thedo | 166:240bc5a0f42a | 1212 | break; |
thedo | 166:240bc5a0f42a | 1213 | } |
thedo | 166:240bc5a0f42a | 1214 | case CLICKED_ADD: |
thedo | 166:240bc5a0f42a | 1215 | { |
thedo | 166:240bc5a0f42a | 1216 | |
thedo | 166:240bc5a0f42a | 1217 | Mat imgReg = gray(roi); |
thedo | 166:240bc5a0f42a | 1218 | resize(imgReg,imgReg,regSize); |
thedo | 166:240bc5a0f42a | 1219 | //train face |
thedo | 166:240bc5a0f42a | 1220 | face_database.database_image.push_back(imgReg); |
thedo | 166:240bc5a0f42a | 1221 | face_database.database_label.push_back(label_id); |
thedo | 166:240bc5a0f42a | 1222 | flag_train = true; |
thedo | 166:240bc5a0f42a | 1223 | isBreak = true; |
thedo | 166:240bc5a0f42a | 1224 | break; |
thedo | 166:240bc5a0f42a | 1225 | } |
thedo | 166:240bc5a0f42a | 1226 | case CLICKED_IGNORE: |
thedo | 166:240bc5a0f42a | 1227 | { |
thedo | 166:240bc5a0f42a | 1228 | //ignore |
thedo | 166:240bc5a0f42a | 1229 | isBreak = true; |
thedo | 166:240bc5a0f42a | 1230 | break; |
thedo | 166:240bc5a0f42a | 1231 | } |
thedo | 166:240bc5a0f42a | 1232 | default: |
thedo | 166:240bc5a0f42a | 1233 | break; |
thedo | 166:240bc5a0f42a | 1234 | } |
thedo | 166:240bc5a0f42a | 1235 | |
thedo | 166:240bc5a0f42a | 1236 | if(isBreak) |
thedo | 166:240bc5a0f42a | 1237 | break; |
thedo | 166:240bc5a0f42a | 1238 | wait(0.1); |
thedo | 166:240bc5a0f42a | 1239 | } |
thedo | 166:240bc5a0f42a | 1240 | }// for faces.size() |
thedo | 166:240bc5a0f42a | 1241 | |
thedo | 166:240bc5a0f42a | 1242 | if( flag_train == true) |
thedo | 166:240bc5a0f42a | 1243 | { |
thedo | 166:240bc5a0f42a | 1244 | if(isFirstTrain == true) |
thedo | 166:240bc5a0f42a | 1245 | { |
thedo | 166:240bc5a0f42a | 1246 | isFirstTrain = false; |
thedo | 166:240bc5a0f42a | 1247 | modelReg->train(face_database.database_image, face_database.database_label); |
thedo | 166:240bc5a0f42a | 1248 | } |
thedo | 166:240bc5a0f42a | 1249 | else |
thedo | 166:240bc5a0f42a | 1250 | { |
thedo | 166:240bc5a0f42a | 1251 | modelReg->update(face_database.database_image, face_database.database_label); |
thedo | 166:240bc5a0f42a | 1252 | } |
thedo | 166:240bc5a0f42a | 1253 | } |
thedo | 166:240bc5a0f42a | 1254 | |
thedo | 166:240bc5a0f42a | 1255 | // Clean screen |
thedo | 166:240bc5a0f42a | 1256 | memset(user_frame_buffer_draw_action, 0, |
thedo | 166:240bc5a0f42a | 1257 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 1258 | oldStateFace = false; |
thedo | 166:240bc5a0f42a | 1259 | |
thedo | 166:240bc5a0f42a | 1260 | mMutexClicked.lock(); |
thedo | 166:240bc5a0f42a | 1261 | clickedCode = CLICKED_UNKNOWN; |
thedo | 166:240bc5a0f42a | 1262 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 1263 | } //clickedCode == CLICKED_REGIS_FACE |
thedo | 166:240bc5a0f42a | 1264 | else |
thedo | 166:240bc5a0f42a | 1265 | { |
thedo | 166:240bc5a0f42a | 1266 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 1267 | if (isFirstTrain == false) |
thedo | 166:240bc5a0f42a | 1268 | { |
thedo | 166:240bc5a0f42a | 1269 | for(int i = 0; i < faces.size();i++) |
thedo | 166:240bc5a0f42a | 1270 | { |
thedo | 166:240bc5a0f42a | 1271 | int _x = faces[i].x*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 1272 | int _y = faces[i].y*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 1273 | int _w = faces[i].width*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 1274 | int _h = faces[i].height*IMG_DOWN_SAMPLE; |
thedo | 166:240bc5a0f42a | 1275 | |
thedo | 166:240bc5a0f42a | 1276 | Rect roi(_x,_y,_w,_h); |
thedo | 166:240bc5a0f42a | 1277 | Mat target_face = gray(roi); |
thedo | 166:240bc5a0f42a | 1278 | resize(target_face,target_face,regSize); |
thedo | 166:240bc5a0f42a | 1279 | int predicted = -1; |
thedo | 166:240bc5a0f42a | 1280 | double confidence_level = 0; |
thedo | 166:240bc5a0f42a | 1281 | modelReg->predict(target_face, predicted, confidence_level); |
thedo | 166:240bc5a0f42a | 1282 | |
thedo | 166:240bc5a0f42a | 1283 | obj_detect_result tmp; |
thedo | 166:240bc5a0f42a | 1284 | tmp.obj = faces[i]; |
thedo | 166:240bc5a0f42a | 1285 | |
thedo | 166:240bc5a0f42a | 1286 | if(predicted != -1) |
thedo | 166:240bc5a0f42a | 1287 | { |
thedo | 166:240bc5a0f42a | 1288 | if (confidence_level < thresmax) |
thedo | 166:240bc5a0f42a | 1289 | { |
thedo | 166:240bc5a0f42a | 1290 | tmp.label = predicted; |
thedo | 166:240bc5a0f42a | 1291 | } |
thedo | 166:240bc5a0f42a | 1292 | else |
thedo | 166:240bc5a0f42a | 1293 | { |
thedo | 166:240bc5a0f42a | 1294 | tmp.label = -1; |
thedo | 166:240bc5a0f42a | 1295 | } |
thedo | 166:240bc5a0f42a | 1296 | } |
thedo | 166:240bc5a0f42a | 1297 | else |
thedo | 166:240bc5a0f42a | 1298 | { |
thedo | 166:240bc5a0f42a | 1299 | tmp.label = -1; |
thedo | 166:240bc5a0f42a | 1300 | } |
thedo | 166:240bc5a0f42a | 1301 | gObjectDetects.push_back(tmp); |
thedo | 166:240bc5a0f42a | 1302 | } |
thedo | 166:240bc5a0f42a | 1303 | } |
thedo | 166:240bc5a0f42a | 1304 | else{ |
thedo | 166:240bc5a0f42a | 1305 | for(int i = 0;i < faces.size();i++) |
thedo | 166:240bc5a0f42a | 1306 | { |
thedo | 166:240bc5a0f42a | 1307 | obj_detect_result tmp; |
thedo | 166:240bc5a0f42a | 1308 | tmp.obj = faces[i]; |
thedo | 166:240bc5a0f42a | 1309 | tmp.label = -1; |
thedo | 166:240bc5a0f42a | 1310 | gObjectDetects.push_back(tmp); |
thedo | 166:240bc5a0f42a | 1311 | } |
thedo | 166:240bc5a0f42a | 1312 | } |
thedo | 166:240bc5a0f42a | 1313 | |
thedo | 166:240bc5a0f42a | 1314 | gIsDrawing = true; |
thedo | 166:240bc5a0f42a | 1315 | p_DrawObjects->signal_set(1); |
thedo | 166:240bc5a0f42a | 1316 | } |
thedo | 166:240bc5a0f42a | 1317 | } //faces.size() > 0 |
thedo | 166:240bc5a0f42a | 1318 | else |
thedo | 166:240bc5a0f42a | 1319 | { |
thedo | 166:240bc5a0f42a | 1320 | oldStateFace = false; |
thedo | 166:240bc5a0f42a | 1321 | memset(user_frame_buffer_draw_action, 0, |
thedo | 166:240bc5a0f42a | 1322 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 1323 | mMutexClicked.lock(); |
thedo | 166:240bc5a0f42a | 1324 | clickedCode = CLICKED_UNKNOWN; |
thedo | 166:240bc5a0f42a | 1325 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 1326 | |
thedo | 166:240bc5a0f42a | 1327 | // Clean draw faces |
thedo | 166:240bc5a0f42a | 1328 | mMutexObjects.lock(); |
thedo | 166:240bc5a0f42a | 1329 | if(gIsDrawing == false) |
thedo | 166:240bc5a0f42a | 1330 | { |
thedo | 166:240bc5a0f42a | 1331 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 1332 | gObjectDetects.clear(); |
thedo | 166:240bc5a0f42a | 1333 | gIsDrawing = true; |
thedo | 166:240bc5a0f42a | 1334 | p_DrawObjects->signal_set(1); |
thedo | 166:240bc5a0f42a | 1335 | } |
thedo | 166:240bc5a0f42a | 1336 | else |
thedo | 166:240bc5a0f42a | 1337 | { |
thedo | 166:240bc5a0f42a | 1338 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 1339 | } |
thedo | 166:240bc5a0f42a | 1340 | } |
thedo | 166:240bc5a0f42a | 1341 | } |
thedo | 166:240bc5a0f42a | 1342 | else |
thedo | 166:240bc5a0f42a | 1343 | { |
thedo | 166:240bc5a0f42a | 1344 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 1345 | } |
thedo | 166:240bc5a0f42a | 1346 | |
thedo | 166:240bc5a0f42a | 1347 | /* Reset flag */ |
thedo | 166:240bc5a0f42a | 1348 | faces.clear(); |
thedo | 166:240bc5a0f42a | 1349 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 1350 | gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 1351 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 1352 | |
thedo | 166:240bc5a0f42a | 1353 | /* Clean cache */ |
thedo | 166:240bc5a0f42a | 1354 | dcache_clean(user_frame_buffer_draw_action, |
thedo | 166:240bc5a0f42a | 1355 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 1356 | } |
thedo | 166:240bc5a0f42a | 1357 | } |
thedo | 166:240bc5a0f42a | 1358 | |
thedo | 166:240bc5a0f42a | 1359 | /* 2 functions for gesture recognition */ |
thedo | 166:240bc5a0f42a | 1360 | int distanceP2P(Point2f a, Point2f b) |
thedo | 166:240bc5a0f42a | 1361 | { |
thedo | 166:240bc5a0f42a | 1362 | int d = (int)sqrt(fabs(pow(a.x - b.x, 2) + pow(a.y - b.y, 2))); |
thedo | 166:240bc5a0f42a | 1363 | return d; |
thedo | 166:240bc5a0f42a | 1364 | } |
thedo | 166:240bc5a0f42a | 1365 | |
thedo | 166:240bc5a0f42a | 1366 | float getAngle(Point s, Point f, Point e){ |
thedo | 166:240bc5a0f42a | 1367 | float l1 = distanceP2P(f, s); |
thedo | 166:240bc5a0f42a | 1368 | float l2 = distanceP2P(f, e); |
thedo | 166:240bc5a0f42a | 1369 | float dot = (s.x - f.x)*(e.x - f.x) + (s.y - f.y)*(e.y - f.y); |
thedo | 166:240bc5a0f42a | 1370 | float angle = acos(dot / (l1*l2)); |
thedo | 166:240bc5a0f42a | 1371 | angle = angle * 180 / M_PI; |
thedo | 166:240bc5a0f42a | 1372 | return angle; |
thedo | 166:240bc5a0f42a | 1373 | } |
thedo | 166:240bc5a0f42a | 1374 | |
thedo | 166:240bc5a0f42a | 1375 | void drawButtonSampling(graphicFrameworkCanvas canvas,bool sampling) |
thedo | 166:240bc5a0f42a | 1376 | { |
thedo | 166:240bc5a0f42a | 1377 | // Clear 21 lines |
thedo | 166:240bc5a0f42a | 1378 | memset(user_frame_buffer_draw_action + (GESTURE_SAMPLING_BTN_Y - 1)* |
thedo | 166:240bc5a0f42a | 1379 | LCD_PIXEL_WIDTH*FRAME_BUFFER_BYTE_PER_PIXEL, 0, |
thedo | 166:240bc5a0f42a | 1380 | 21*LCD_PIXEL_WIDTH*FRAME_BUFFER_BYTE_PER_PIXEL); |
thedo | 166:240bc5a0f42a | 1381 | if(sampling == true) // Sampling, Clicking stop, draw sampling |
thedo | 166:240bc5a0f42a | 1382 | { |
thedo | 166:240bc5a0f42a | 1383 | canvas.drawImage(my_img_sampling, GESTURE_SAMPLING_BTN_X, |
thedo | 166:240bc5a0f42a | 1384 | GESTURE_SAMPLING_BTN_Y); |
thedo | 166:240bc5a0f42a | 1385 | } |
thedo | 166:240bc5a0f42a | 1386 | else |
thedo | 166:240bc5a0f42a | 1387 | { |
thedo | 166:240bc5a0f42a | 1388 | canvas.drawImage(my_img_stop, GESTURE_SAMPLING_BTN_X, |
thedo | 166:240bc5a0f42a | 1389 | GESTURE_SAMPLING_BTN_Y); |
thedo | 166:240bc5a0f42a | 1390 | } |
thedo | 166:240bc5a0f42a | 1391 | } |
thedo | 166:240bc5a0f42a | 1392 | |
thedo | 166:240bc5a0f42a | 1393 | void gestureRegconition(void) |
thedo | 166:240bc5a0f42a | 1394 | { |
thedo | 166:240bc5a0f42a | 1395 | // Init draw |
thedo | 166:240bc5a0f42a | 1396 | graphicFrameworkCanvas myCanvas(user_frame_buffer_draw_action, 0x01E0, |
thedo | 166:240bc5a0f42a | 1397 | 0x0110, (uint8_t)DRAW_BUFFER_BYTE_PER_PIXEL, |
thedo | 166:240bc5a0f42a | 1398 | (uint8_t)DRAW_POINT,0x06); |
thedo | 166:240bc5a0f42a | 1399 | |
thedo | 166:240bc5a0f42a | 1400 | bool sampling = true; |
thedo | 166:240bc5a0f42a | 1401 | int kernelSize = 7; |
thedo | 166:240bc5a0f42a | 1402 | int thresValue = 100; |
thedo | 166:240bc5a0f42a | 1403 | int maxIndex = 0; |
thedo | 166:240bc5a0f42a | 1404 | double area = 0.0; |
thedo | 166:240bc5a0f42a | 1405 | unsigned long lArea = 0, maxArea = 0; |
thedo | 166:240bc5a0f42a | 1406 | int hullSize = 0; |
thedo | 166:240bc5a0f42a | 1407 | bool handSamp = true; |
thedo | 166:240bc5a0f42a | 1408 | bool isFinger = false; |
thedo | 166:240bc5a0f42a | 1409 | int oneFinger = 0; |
thedo | 166:240bc5a0f42a | 1410 | int countFinger = 0; |
thedo | 166:240bc5a0f42a | 1411 | Sampling handdist; |
thedo | 166:240bc5a0f42a | 1412 | Point2f mPa; |
thedo | 166:240bc5a0f42a | 1413 | ConvexPoint checkPoint; |
thedo | 166:240bc5a0f42a | 1414 | |
thedo | 166:240bc5a0f42a | 1415 | Mat imgGray; |
thedo | 166:240bc5a0f42a | 1416 | Mat blurImg; |
thedo | 166:240bc5a0f42a | 1417 | Mat thresholdImg; |
thedo | 166:240bc5a0f42a | 1418 | vector<vector<Point> > contours; |
thedo | 166:240bc5a0f42a | 1419 | vector<mLine> lLines; |
thedo | 166:240bc5a0f42a | 1420 | vector<mCircle> lCircles; |
thedo | 166:240bc5a0f42a | 1421 | vector<Point> lMaxContour; |
thedo | 166:240bc5a0f42a | 1422 | |
thedo | 166:240bc5a0f42a | 1423 | myCanvas.drawImage(my_img_stop, GESTURE_SAMPLING_BTN_X, |
thedo | 166:240bc5a0f42a | 1424 | GESTURE_SAMPLING_BTN_Y); |
thedo | 166:240bc5a0f42a | 1425 | mMutexClicked.lock(); |
thedo | 166:240bc5a0f42a | 1426 | clickedCode = CLICKED_UNKNOWN; |
thedo | 166:240bc5a0f42a | 1427 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 1428 | clearGestureResult(gGestureResult); |
thedo | 166:240bc5a0f42a | 1429 | while(1) |
thedo | 166:240bc5a0f42a | 1430 | { |
thedo | 166:240bc5a0f42a | 1431 | semProcessThread.wait(); |
thedo | 166:240bc5a0f42a | 1432 | |
thedo | 166:240bc5a0f42a | 1433 | //Test |
thedo | 166:240bc5a0f42a | 1434 | /*char f_name[40]; |
thedo | 166:240bc5a0f42a | 1435 | sprintf(f_name,"/SD/img_test%d.txt",count++); |
thedo | 166:240bc5a0f42a | 1436 | Mat res_tmp = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH, |
thedo | 166:240bc5a0f42a | 1437 | (int)LCD_PIXEL_HEIGHT,2); |
thedo | 166:240bc5a0f42a | 1438 | writeMatToTxt(res_tmp,f_name); |
thedo | 166:240bc5a0f42a | 1439 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 1440 | gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 1441 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 1442 | continue; */ |
thedo | 166:240bc5a0f42a | 1443 | |
thedo | 166:240bc5a0f42a | 1444 | //end test |
thedo | 166:240bc5a0f42a | 1445 | |
thedo | 166:240bc5a0f42a | 1446 | if ( appMode != GUESTURE_RECOGNITION ) |
thedo | 166:240bc5a0f42a | 1447 | { |
thedo | 166:240bc5a0f42a | 1448 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 1449 | gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 1450 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 1451 | memset(user_frame_buffer_draw_action, 0, |
thedo | 166:240bc5a0f42a | 1452 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 1453 | clearGestureResult(gGestureResult); |
thedo | 166:240bc5a0f42a | 1454 | break; |
thedo | 166:240bc5a0f42a | 1455 | } |
thedo | 166:240bc5a0f42a | 1456 | |
thedo | 166:240bc5a0f42a | 1457 | //Draw button sampling |
thedo | 166:240bc5a0f42a | 1458 | mMutexClicked.lock(); |
thedo | 166:240bc5a0f42a | 1459 | if (clickedCode == CLICKED_HAND_SAMPLING) |
thedo | 166:240bc5a0f42a | 1460 | { |
thedo | 166:240bc5a0f42a | 1461 | clickedCode = CLICKED_UNKNOWN; |
thedo | 166:240bc5a0f42a | 1462 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 1463 | drawButtonSampling(myCanvas,sampling); |
thedo | 166:240bc5a0f42a | 1464 | sampling = !sampling; |
thedo | 166:240bc5a0f42a | 1465 | } |
thedo | 166:240bc5a0f42a | 1466 | else |
thedo | 166:240bc5a0f42a | 1467 | { |
thedo | 166:240bc5a0f42a | 1468 | mMutexClicked.unlock(); |
thedo | 166:240bc5a0f42a | 1469 | } |
thedo | 166:240bc5a0f42a | 1470 | |
thedo | 166:240bc5a0f42a | 1471 | // Get frame camera |
thedo | 166:240bc5a0f42a | 1472 | { |
thedo | 166:240bc5a0f42a | 1473 | Mat res = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH, |
thedo | 166:240bc5a0f42a | 1474 | (int)LCD_PIXEL_HEIGHT,2); |
thedo | 166:240bc5a0f42a | 1475 | cvtColor(res,imgGray,COLOR_RGB2GRAY); |
thedo | 166:240bc5a0f42a | 1476 | res.release(); |
thedo | 166:240bc5a0f42a | 1477 | } |
thedo | 166:240bc5a0f42a | 1478 | |
thedo | 166:240bc5a0f42a | 1479 | //Clear old data |
thedo | 166:240bc5a0f42a | 1480 | lLines.clear(); |
thedo | 166:240bc5a0f42a | 1481 | lCircles.clear(); |
thedo | 166:240bc5a0f42a | 1482 | lMaxContour.clear(); |
thedo | 166:240bc5a0f42a | 1483 | |
thedo | 166:240bc5a0f42a | 1484 | // Start processing |
thedo | 166:240bc5a0f42a | 1485 | blur(imgGray,blurImg,Size(kernelSize,kernelSize)); |
thedo | 166:240bc5a0f42a | 1486 | threshold(blurImg,thresholdImg,thresValue,255,CV_THRESH_BINARY); |
thedo | 166:240bc5a0f42a | 1487 | |
thedo | 166:240bc5a0f42a | 1488 | checkPoint.Pointstart.clear(); |
thedo | 166:240bc5a0f42a | 1489 | checkPoint.Pointdepth.clear(); |
thedo | 166:240bc5a0f42a | 1490 | checkPoint.Pointindex.clear(); |
thedo | 166:240bc5a0f42a | 1491 | checkPoint.detecthand = 0; |
thedo | 166:240bc5a0f42a | 1492 | |
thedo | 166:240bc5a0f42a | 1493 | findContours(thresholdImg,contours,CV_RETR_EXTERNAL, |
thedo | 166:240bc5a0f42a | 1494 | CV_CHAIN_APPROX_SIMPLE,Point(0,0)); |
thedo | 166:240bc5a0f42a | 1495 | |
thedo | 166:240bc5a0f42a | 1496 | if(contours.size() > 0) |
thedo | 166:240bc5a0f42a | 1497 | { |
thedo | 166:240bc5a0f42a | 1498 | //togle_led(LED_GREEN); |
thedo | 166:240bc5a0f42a | 1499 | maxIndex = 0; |
thedo | 166:240bc5a0f42a | 1500 | vector<vector<int> > hull(contours.size()); |
thedo | 166:240bc5a0f42a | 1501 | vector<vector<Vec4i> > convDef(contours.size()); |
thedo | 166:240bc5a0f42a | 1502 | vector<vector<Point> > hull_point(contours.size()); |
thedo | 166:240bc5a0f42a | 1503 | vector<vector<Point> > detectPoint(contours.size()); |
thedo | 166:240bc5a0f42a | 1504 | |
thedo | 166:240bc5a0f42a | 1505 | for(int i = 0;i < contours.size();i++) |
thedo | 166:240bc5a0f42a | 1506 | { |
thedo | 166:240bc5a0f42a | 1507 | area = contourArea(contours[i]); |
thedo | 166:240bc5a0f42a | 1508 | lArea = long(area); |
thedo | 166:240bc5a0f42a | 1509 | if(lArea > maxArea) |
thedo | 166:240bc5a0f42a | 1510 | { |
thedo | 166:240bc5a0f42a | 1511 | hullSize++; |
thedo | 166:240bc5a0f42a | 1512 | maxArea = lArea; |
thedo | 166:240bc5a0f42a | 1513 | maxIndex = i; |
thedo | 166:240bc5a0f42a | 1514 | } |
thedo | 166:240bc5a0f42a | 1515 | } |
thedo | 166:240bc5a0f42a | 1516 | |
thedo | 166:240bc5a0f42a | 1517 | if(maxArea > 50000) |
thedo | 166:240bc5a0f42a | 1518 | { |
thedo | 166:240bc5a0f42a | 1519 | //togle_reset(LED_RED,LED_BLUE); |
thedo | 166:240bc5a0f42a | 1520 | checkPoint.detecthand = 1; |
thedo | 166:240bc5a0f42a | 1521 | convexHull(Mat(contours[maxIndex]),hull[maxIndex],false); |
thedo | 166:240bc5a0f42a | 1522 | convexityDefects(contours[maxIndex],hull[maxIndex],convDef[maxIndex]); |
thedo | 166:240bc5a0f42a | 1523 | } |
thedo | 166:240bc5a0f42a | 1524 | |
thedo | 166:240bc5a0f42a | 1525 | for (int i = 0;i < convDef[maxIndex].size();i++) |
thedo | 166:240bc5a0f42a | 1526 | { |
thedo | 166:240bc5a0f42a | 1527 | if(convDef[maxIndex][i][3] > 20*256) |
thedo | 166:240bc5a0f42a | 1528 | { |
thedo | 166:240bc5a0f42a | 1529 | int ind_0 = convDef[maxIndex][i][0]; |
thedo | 166:240bc5a0f42a | 1530 | int ind_1 = convDef[maxIndex][i][2]; |
thedo | 166:240bc5a0f42a | 1531 | checkPoint.Pointstart.push_back(contours[maxIndex][ind_0]); |
thedo | 166:240bc5a0f42a | 1532 | checkPoint.Pointdepth.push_back(contours[maxIndex][ind_1]); |
thedo | 166:240bc5a0f42a | 1533 | checkPoint.Pointindex.push_back(ind_1); |
thedo | 166:240bc5a0f42a | 1534 | } |
thedo | 166:240bc5a0f42a | 1535 | } |
thedo | 166:240bc5a0f42a | 1536 | |
thedo | 166:240bc5a0f42a | 1537 | vector<Moments> mu(contours.size()); |
thedo | 166:240bc5a0f42a | 1538 | vector<Point2d> mc(contours.size()); |
thedo | 166:240bc5a0f42a | 1539 | mu[maxIndex] = moments(contours[maxIndex],false); |
thedo | 166:240bc5a0f42a | 1540 | mc[maxIndex] = Point2f(mu[maxIndex].m10 / mu[maxIndex].m00, |
thedo | 166:240bc5a0f42a | 1541 | mu[maxIndex].m01 / mu[maxIndex].m00); |
thedo | 166:240bc5a0f42a | 1542 | mPa = mc[maxIndex]; |
thedo | 166:240bc5a0f42a | 1543 | |
thedo | 166:240bc5a0f42a | 1544 | // Reset values |
thedo | 166:240bc5a0f42a | 1545 | lArea = 0; |
thedo | 166:240bc5a0f42a | 1546 | maxArea = 0; |
thedo | 166:240bc5a0f42a | 1547 | hullSize = 0; |
thedo | 166:240bc5a0f42a | 1548 | area = 0; |
thedo | 166:240bc5a0f42a | 1549 | |
thedo | 166:240bc5a0f42a | 1550 | |
thedo | 166:240bc5a0f42a | 1551 | // Draw contours |
thedo | 166:240bc5a0f42a | 1552 | Mat imgContour(LCD_PIXEL_HEIGHT,LCD_PIXEL_WIDTH,CV_8UC1,Scalar(0)); |
thedo | 166:240bc5a0f42a | 1553 | drawContours(imgContour,contours,maxIndex,Scalar(255)); |
thedo | 166:240bc5a0f42a | 1554 | for(int i=0;i<imgContour.rows;i++) |
thedo | 166:240bc5a0f42a | 1555 | { |
thedo | 166:240bc5a0f42a | 1556 | for(int j=0;j<imgContour.cols;j++) |
thedo | 166:240bc5a0f42a | 1557 | { |
thedo | 166:240bc5a0f42a | 1558 | if(imgContour.at<uchar>(i,j) == 255) |
thedo | 166:240bc5a0f42a | 1559 | { |
thedo | 166:240bc5a0f42a | 1560 | lMaxContour.push_back(Point(j,i)); |
thedo | 166:240bc5a0f42a | 1561 | } |
thedo | 166:240bc5a0f42a | 1562 | } |
thedo | 166:240bc5a0f42a | 1563 | } |
thedo | 166:240bc5a0f42a | 1564 | |
thedo | 166:240bc5a0f42a | 1565 | |
thedo | 166:240bc5a0f42a | 1566 | }// contours.size() > 0 |
thedo | 166:240bc5a0f42a | 1567 | else |
thedo | 166:240bc5a0f42a | 1568 | { |
thedo | 166:240bc5a0f42a | 1569 | checkPoint.detecthand = 0; |
thedo | 166:240bc5a0f42a | 1570 | } |
thedo | 166:240bc5a0f42a | 1571 | |
thedo | 166:240bc5a0f42a | 1572 | if(sampling == true) |
thedo | 166:240bc5a0f42a | 1573 | { |
thedo | 166:240bc5a0f42a | 1574 | if (checkPoint.Pointstart.size() > 1) |
thedo | 166:240bc5a0f42a | 1575 | { |
thedo | 166:240bc5a0f42a | 1576 | for(int i = 0;i < checkPoint.Pointstart.size() -1;i++) |
thedo | 166:240bc5a0f42a | 1577 | { |
thedo | 166:240bc5a0f42a | 1578 | float pAngle = getAngle(checkPoint.Pointstart[i],mPa, |
thedo | 166:240bc5a0f42a | 1579 | checkPoint.Pointstart[i+1]); |
thedo | 166:240bc5a0f42a | 1580 | float fAngle = getAngle(checkPoint.Pointstart[1],mPa, |
thedo | 166:240bc5a0f42a | 1581 | checkPoint.Pointstart[i+1]); |
thedo | 166:240bc5a0f42a | 1582 | |
thedo | 166:240bc5a0f42a | 1583 | if(pAngle < 90.00 && pAngle > 5.00 && fAngle < 180) |
thedo | 166:240bc5a0f42a | 1584 | { |
thedo | 166:240bc5a0f42a | 1585 | double pFdist = distanceP2P(mPa, |
thedo | 166:240bc5a0f42a | 1586 | checkPoint.Pointstart[i]); |
thedo | 166:240bc5a0f42a | 1587 | double pLdist = distanceP2P(mPa, |
thedo | 166:240bc5a0f42a | 1588 | checkPoint.Pointdepth[i]); |
thedo | 166:240bc5a0f42a | 1589 | double _Pmax = handdist.hand_max; |
thedo | 166:240bc5a0f42a | 1590 | double _Pmin = handdist.hand_min; |
thedo | 166:240bc5a0f42a | 1591 | if (pFdist > pLdist) |
thedo | 166:240bc5a0f42a | 1592 | { |
thedo | 166:240bc5a0f42a | 1593 | if (pFdist > _Pmax) |
thedo | 166:240bc5a0f42a | 1594 | { |
thedo | 166:240bc5a0f42a | 1595 | handdist.hand_max = pFdist; |
thedo | 166:240bc5a0f42a | 1596 | } |
thedo | 166:240bc5a0f42a | 1597 | if (pLdist < _Pmin) |
thedo | 166:240bc5a0f42a | 1598 | { |
thedo | 166:240bc5a0f42a | 1599 | handdist.hand_min = pLdist; |
thedo | 166:240bc5a0f42a | 1600 | } |
thedo | 166:240bc5a0f42a | 1601 | } |
thedo | 166:240bc5a0f42a | 1602 | else |
thedo | 166:240bc5a0f42a | 1603 | { |
thedo | 166:240bc5a0f42a | 1604 | if (pLdist > _Pmin) |
thedo | 166:240bc5a0f42a | 1605 | { |
thedo | 166:240bc5a0f42a | 1606 | handdist.hand_max = pLdist; |
thedo | 166:240bc5a0f42a | 1607 | } |
thedo | 166:240bc5a0f42a | 1608 | if (pFdist < _Pmin) |
thedo | 166:240bc5a0f42a | 1609 | { |
thedo | 166:240bc5a0f42a | 1610 | handdist.hand_min = pFdist; |
thedo | 166:240bc5a0f42a | 1611 | } |
thedo | 166:240bc5a0f42a | 1612 | } |
thedo | 166:240bc5a0f42a | 1613 | } |
thedo | 166:240bc5a0f42a | 1614 | } |
thedo | 166:240bc5a0f42a | 1615 | } |
thedo | 166:240bc5a0f42a | 1616 | }//sampling == true |
thedo | 166:240bc5a0f42a | 1617 | else |
thedo | 166:240bc5a0f42a | 1618 | { |
thedo | 166:240bc5a0f42a | 1619 | if(checkPoint.detecthand == 1) |
thedo | 166:240bc5a0f42a | 1620 | { |
thedo | 166:240bc5a0f42a | 1621 | if (checkPoint.Pointstart.size() > 1) |
thedo | 166:240bc5a0f42a | 1622 | { |
thedo | 166:240bc5a0f42a | 1623 | for(int i = 0;i < checkPoint.Pointstart.size() -1;i++) |
thedo | 166:240bc5a0f42a | 1624 | { |
thedo | 166:240bc5a0f42a | 1625 | float pAngle = getAngle(checkPoint.Pointstart[i],mPa, |
thedo | 166:240bc5a0f42a | 1626 | checkPoint.Pointstart[i+1]); |
thedo | 166:240bc5a0f42a | 1627 | float fAngle = getAngle(checkPoint.Pointstart[1],mPa, |
thedo | 166:240bc5a0f42a | 1628 | checkPoint.Pointstart[i+1]); |
thedo | 166:240bc5a0f42a | 1629 | |
thedo | 166:240bc5a0f42a | 1630 | // Draw line |
thedo | 166:240bc5a0f42a | 1631 | mLine aLine; |
thedo | 166:240bc5a0f42a | 1632 | aLine.x1 = (int)checkPoint.Pointstart[i].x; |
thedo | 166:240bc5a0f42a | 1633 | aLine.y1 = (int)checkPoint.Pointstart[i].y; |
thedo | 166:240bc5a0f42a | 1634 | aLine.x2 = (int)mPa.x; |
thedo | 166:240bc5a0f42a | 1635 | aLine.y2 = (int)mPa.y; |
thedo | 166:240bc5a0f42a | 1636 | aLine.color[0] = 0x00;//Color red |
thedo | 166:240bc5a0f42a | 1637 | aLine.color[1] = 0xFF; |
thedo | 166:240bc5a0f42a | 1638 | lLines.push_back(aLine); |
thedo | 166:240bc5a0f42a | 1639 | //line(showRes,checkPoint.Pointstart[i],mPa, |
thedo | 166:240bc5a0f42a | 1640 | // Scalar(255,255,0)); |
thedo | 166:240bc5a0f42a | 1641 | //Draw circle |
thedo | 166:240bc5a0f42a | 1642 | mCircle cir; |
thedo | 166:240bc5a0f42a | 1643 | cir.x = (int)checkPoint.Pointstart[i].x; |
thedo | 166:240bc5a0f42a | 1644 | cir.y = (int)checkPoint.Pointstart[i].y; |
thedo | 166:240bc5a0f42a | 1645 | cir.radius = 10; |
thedo | 166:240bc5a0f42a | 1646 | cir.color[0] = 0xF0; |
thedo | 166:240bc5a0f42a | 1647 | cir.color[1] = 0xF0;//Color green |
thedo | 166:240bc5a0f42a | 1648 | lCircles.push_back(cir); |
thedo | 166:240bc5a0f42a | 1649 | |
thedo | 166:240bc5a0f42a | 1650 | |
thedo | 166:240bc5a0f42a | 1651 | //circle(showRes,checkPoint.Pointstart[i],10, |
thedo | 166:240bc5a0f42a | 1652 | // Scalar(0,255,0)); |
thedo | 166:240bc5a0f42a | 1653 | |
thedo | 166:240bc5a0f42a | 1654 | if(pAngle < 90.00 && pAngle > 5.00 && fAngle < 180) |
thedo | 166:240bc5a0f42a | 1655 | { |
thedo | 166:240bc5a0f42a | 1656 | double pFdist = distanceP2P(mPa, |
thedo | 166:240bc5a0f42a | 1657 | checkPoint.Pointstart[i]); |
thedo | 166:240bc5a0f42a | 1658 | if(pFdist > (handdist.hand_min + 110) && |
thedo | 166:240bc5a0f42a | 1659 | pFdist < (handdist.hand_max + 40)) |
thedo | 166:240bc5a0f42a | 1660 | { |
thedo | 166:240bc5a0f42a | 1661 | isFinger = true; |
thedo | 166:240bc5a0f42a | 1662 | //line(showRes,checkPoint.Pointstart[i],mPa,Scalar(255,255,255)); |
thedo | 166:240bc5a0f42a | 1663 | aLine.x1 = (int)checkPoint.Pointstart[i].x; |
thedo | 166:240bc5a0f42a | 1664 | aLine.y1 = (int)checkPoint.Pointstart[i].y; |
thedo | 166:240bc5a0f42a | 1665 | aLine.x2 = (int)mPa.x; |
thedo | 166:240bc5a0f42a | 1666 | aLine.y2 = (int)mPa.y;// Keep color red |
thedo | 166:240bc5a0f42a | 1667 | lLines.push_back(aLine); |
thedo | 166:240bc5a0f42a | 1668 | |
thedo | 166:240bc5a0f42a | 1669 | oneFinger++; |
thedo | 166:240bc5a0f42a | 1670 | } |
thedo | 166:240bc5a0f42a | 1671 | else |
thedo | 166:240bc5a0f42a | 1672 | { |
thedo | 166:240bc5a0f42a | 1673 | isFinger = false; |
thedo | 166:240bc5a0f42a | 1674 | } |
thedo | 166:240bc5a0f42a | 1675 | |
thedo | 166:240bc5a0f42a | 1676 | if(isFinger == true) |
thedo | 166:240bc5a0f42a | 1677 | { |
thedo | 166:240bc5a0f42a | 1678 | //circle(showRes,mPa,handdist.hand_min,Scalar(255,0,0)); |
thedo | 166:240bc5a0f42a | 1679 | cir.x = (int)mPa.x; |
thedo | 166:240bc5a0f42a | 1680 | cir.y = (int)mPa.y; |
thedo | 166:240bc5a0f42a | 1681 | cir.radius = (int)handdist.hand_min; |
thedo | 166:240bc5a0f42a | 1682 | lCircles.push_back(cir);//color green |
thedo | 166:240bc5a0f42a | 1683 | |
thedo | 166:240bc5a0f42a | 1684 | //circle(showRes,mPa,handdist.hand_min + 110,Scalar(255,0,0)); |
thedo | 166:240bc5a0f42a | 1685 | cir.radius = (int)handdist.hand_min + 110; |
thedo | 166:240bc5a0f42a | 1686 | lCircles.push_back(cir);//color green |
thedo | 166:240bc5a0f42a | 1687 | |
thedo | 166:240bc5a0f42a | 1688 | double pLdist = distanceP2P(mPa,checkPoint.Pointdepth[i]); |
thedo | 166:240bc5a0f42a | 1689 | if(pLdist > handdist.hand_min - 5) |
thedo | 166:240bc5a0f42a | 1690 | { |
thedo | 166:240bc5a0f42a | 1691 | countFinger++; |
thedo | 166:240bc5a0f42a | 1692 | //circle(showRes,contours[maxIndex][checkPoint.Pointindex[i]],2,Scalar(0,255,255)); |
thedo | 166:240bc5a0f42a | 1693 | cir.x = (int)contours[maxIndex][checkPoint.Pointindex[i]].x; |
thedo | 166:240bc5a0f42a | 1694 | cir.y = (int)contours[maxIndex][checkPoint.Pointindex[i]].y; |
thedo | 166:240bc5a0f42a | 1695 | cir.radius = 2; |
thedo | 166:240bc5a0f42a | 1696 | lCircles.push_back(cir);//color green |
thedo | 166:240bc5a0f42a | 1697 | } |
thedo | 166:240bc5a0f42a | 1698 | } |
thedo | 166:240bc5a0f42a | 1699 | } |
thedo | 166:240bc5a0f42a | 1700 | }// for |
thedo | 166:240bc5a0f42a | 1701 | if(isFinger == false) |
thedo | 166:240bc5a0f42a | 1702 | { |
thedo | 166:240bc5a0f42a | 1703 | for(int i = 0; i < checkPoint.Pointstart.size() -1;i++) |
thedo | 166:240bc5a0f42a | 1704 | { |
thedo | 166:240bc5a0f42a | 1705 | double pLdist = distanceP2P(mPa, |
thedo | 166:240bc5a0f42a | 1706 | checkPoint.Pointdepth[i]); |
thedo | 166:240bc5a0f42a | 1707 | if (pLdist > (handdist.hand_min - 5)) |
thedo | 166:240bc5a0f42a | 1708 | { |
thedo | 166:240bc5a0f42a | 1709 | countFinger = 0; |
thedo | 166:240bc5a0f42a | 1710 | isFinger = true; |
thedo | 166:240bc5a0f42a | 1711 | } |
thedo | 166:240bc5a0f42a | 1712 | } |
thedo | 166:240bc5a0f42a | 1713 | } |
thedo | 166:240bc5a0f42a | 1714 | }//checkPoint.Pointstart.size() > 1 |
thedo | 166:240bc5a0f42a | 1715 | }//checkPoint.detecthand == 1 |
thedo | 166:240bc5a0f42a | 1716 | } |
thedo | 166:240bc5a0f42a | 1717 | |
thedo | 166:240bc5a0f42a | 1718 | // Draw |
thedo | 166:240bc5a0f42a | 1719 | mMutexObjects.lock(); |
thedo | 166:240bc5a0f42a | 1720 | if(gIsDrawing == false) |
thedo | 166:240bc5a0f42a | 1721 | { |
thedo | 166:240bc5a0f42a | 1722 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 1723 | |
thedo | 166:240bc5a0f42a | 1724 | // Assign data |
thedo | 166:240bc5a0f42a | 1725 | gGestureResult.circles = lCircles; |
thedo | 166:240bc5a0f42a | 1726 | gGestureResult.lines = lLines; |
thedo | 166:240bc5a0f42a | 1727 | gGestureResult.contour = lMaxContour; |
thedo | 166:240bc5a0f42a | 1728 | |
thedo | 166:240bc5a0f42a | 1729 | gIsDrawing = true; |
thedo | 166:240bc5a0f42a | 1730 | p_DrawObjects->signal_set(1); |
thedo | 166:240bc5a0f42a | 1731 | } |
thedo | 166:240bc5a0f42a | 1732 | else |
thedo | 166:240bc5a0f42a | 1733 | { |
thedo | 166:240bc5a0f42a | 1734 | mMutexObjects.unlock(); |
thedo | 166:240bc5a0f42a | 1735 | } |
thedo | 166:240bc5a0f42a | 1736 | |
thedo | 166:240bc5a0f42a | 1737 | mMutexProcess.lock(); |
thedo | 166:240bc5a0f42a | 1738 | gIsProcessing = false; |
thedo | 166:240bc5a0f42a | 1739 | mMutexProcess.unlock(); |
thedo | 166:240bc5a0f42a | 1740 | |
thedo | 166:240bc5a0f42a | 1741 | /* Clean cache */ |
thedo | 166:240bc5a0f42a | 1742 | dcache_clean(user_frame_buffer_draw_action, |
thedo | 166:240bc5a0f42a | 1743 | sizeof(user_frame_buffer_draw_action)); |
thedo | 166:240bc5a0f42a | 1744 | } |
thedo | 166:240bc5a0f42a | 1745 | |
thedo | 166:240bc5a0f42a | 1746 | } |
thedo | 166:240bc5a0f42a | 1747 | |
thedo | 166:240bc5a0f42a | 1748 | /****** main image process here******/ |
thedo | 166:240bc5a0f42a | 1749 | int main(void) { |
thedo | 166:240bc5a0f42a | 1750 | /* Init SD card*/ |
thedo | 166:240bc5a0f42a | 1751 | myStorage = new cStorage(SDCARD_NAME); |
thedo | 166:240bc5a0f42a | 1752 | if( initSdCard() == false) |
thedo | 166:240bc5a0f42a | 1753 | { |
thedo | 166:240bc5a0f42a | 1754 | while(1); |
thedo | 166:240bc5a0f42a | 1755 | } |
thedo | 166:240bc5a0f42a | 1756 | togle_reset(LED_RED,LED_BLUE); |
thedo | 166:240bc5a0f42a | 1757 | |
thedo | 166:240bc5a0f42a | 1758 | /* Initialization of LCD */ |
thedo | 166:240bc5a0f42a | 1759 | Init_LCD_Display(); /* When using LCD, please call before than Init_Video(). */ |
thedo | 166:240bc5a0f42a | 1760 | |
thedo | 166:240bc5a0f42a | 1761 | /* Initialization of Video */ |
thedo | 166:240bc5a0f42a | 1762 | Init_Video(); |
thedo | 166:240bc5a0f42a | 1763 | |
thedo | 166:240bc5a0f42a | 1764 | /* Start Video and Lcd processing */ |
thedo | 166:240bc5a0f42a | 1765 | p_VideoLcdTask = new Thread(); |
thedo | 166:240bc5a0f42a | 1766 | p_VideoLcdTask->start(video_lcd_task); |
thedo | 166:240bc5a0f42a | 1767 | |
thedo | 166:240bc5a0f42a | 1768 | p_Touch = new Thread(); |
thedo | 166:240bc5a0f42a | 1769 | p_Touch->start(touch_task); |
thedo | 166:240bc5a0f42a | 1770 | |
thedo | 166:240bc5a0f42a | 1771 | /* Start image processor*/ |
thedo | 166:240bc5a0f42a | 1772 | p_DrawObjects = new Thread(); |
thedo | 166:240bc5a0f42a | 1773 | p_DrawObjects->signal_set(0); |
thedo | 166:240bc5a0f42a | 1774 | p_DrawObjects->start(img_draw_objects); |
thedo | 166:240bc5a0f42a | 1775 | |
thedo | 166:240bc5a0f42a | 1776 | initDrawAction(); |
thedo | 166:240bc5a0f42a | 1777 | |
thedo | 166:240bc5a0f42a | 1778 | while(1) |
thedo | 166:240bc5a0f42a | 1779 | { |
thedo | 166:240bc5a0f42a | 1780 | switch(appMode) |
thedo | 166:240bc5a0f42a | 1781 | { |
thedo | 166:240bc5a0f42a | 1782 | case FACE_DETECTION: |
thedo | 166:240bc5a0f42a | 1783 | { |
thedo | 166:240bc5a0f42a | 1784 | faceDectectionApp(); |
thedo | 166:240bc5a0f42a | 1785 | break; |
thedo | 166:240bc5a0f42a | 1786 | } |
thedo | 166:240bc5a0f42a | 1787 | case MOTION_DETECTION: |
thedo | 166:240bc5a0f42a | 1788 | { |
thedo | 166:240bc5a0f42a | 1789 | motionDetectionApp(); |
thedo | 166:240bc5a0f42a | 1790 | break; |
thedo | 166:240bc5a0f42a | 1791 | } |
thedo | 166:240bc5a0f42a | 1792 | case FACE_RECOGNITION: |
thedo | 166:240bc5a0f42a | 1793 | { |
thedo | 166:240bc5a0f42a | 1794 | faceRecognitionApp(); |
thedo | 166:240bc5a0f42a | 1795 | break; |
thedo | 166:240bc5a0f42a | 1796 | } |
thedo | 166:240bc5a0f42a | 1797 | case GUESTURE_RECOGNITION: |
thedo | 166:240bc5a0f42a | 1798 | { |
thedo | 166:240bc5a0f42a | 1799 | gestureRegconition(); |
thedo | 166:240bc5a0f42a | 1800 | break; |
thedo | 166:240bc5a0f42a | 1801 | } |
thedo | 166:240bc5a0f42a | 1802 | default: |
thedo | 166:240bc5a0f42a | 1803 | { |
thedo | 166:240bc5a0f42a | 1804 | wait(0.5); |
thedo | 166:240bc5a0f42a | 1805 | break; |
thedo | 166:240bc5a0f42a | 1806 | } |
thedo | 166:240bc5a0f42a | 1807 | } |
thedo | 166:240bc5a0f42a | 1808 | } |
thedo | 166:240bc5a0f42a | 1809 | return 1; |
thedo | 166:240bc5a0f42a | 1810 | } |