Opencv 3.1 project on GR-PEACH board

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

Committer:
thedo
Date:
Thu Jun 29 11:00:41 2017 +0000
Revision:
166:3a9487d57a5c
Child:
168:3efe7c3d1dd7
This is Opencv 3.1 project on GR-PEACH board

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