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