Opencv 3.1 project on GR-PEACH board

Fork of gr-peach-opencv-project by the do

Committer:
thedo
Date:
Tue Jul 04 06:23:13 2017 +0000
Revision:
170:54ff26da7eb6
Parent:
169:bdaa9537e072
project opencv 3.1 on GR PEACH board, no use SD card.

Who changed what in which revision?

UserRevisionLine numberNew 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 }