From 7a8268668ff54a6872ff159d132613eca4137263 Mon Sep 17 00:00:00 2001 From: Tae-Young Chung Date: Wed, 16 Aug 2017 15:56:29 +0900 Subject: [PATCH] Update testsuite to track face or image with image files Change-Id: Iff210d088dbe299f10d32fb67011613c0427cd6c Signed-off-by: Tae-Young Chung --- test/testsuites/face/face_test_suite.c | 208 ++++++++++++++++++++++-- test/testsuites/image/image_test_suite.c | 268 ++++++++++++++++++++++++++++++- 2 files changed, 453 insertions(+), 23 deletions(-) diff --git a/test/testsuites/face/face_test_suite.c b/test/testsuites/face/face_test_suite.c index a9fc9d9..40832b2 100644 --- a/test/testsuites/face/face_test_suite.c +++ b/test/testsuites/face/face_test_suite.c @@ -36,6 +36,8 @@ #define MIN_ALLOWED_LABEL 0 #define MAX_ALLOWED_LABEL 100 +#define FILE_PATH_SIZE 1024 + static bool Perform_eye_condition_recognize = false; static bool Perform_facial_expression_recognize = false; @@ -1454,6 +1456,8 @@ typedef struct { mv_face_tracking_model_h target; mv_video_writer_h writer; int frame_number; + bool is_video; + char out_file_path[FILE_PATH_SIZE]; } tracking_cb_data; void track_cb( @@ -1464,6 +1468,8 @@ void track_cb( double confidence, void *user_data) { + int err = MEDIA_VISION_ERROR_NONE; + tracking_cb_data *cb_data = user_data; static bool track_catch_face = false; @@ -1533,13 +1539,29 @@ void track_cb( } } - const int err = mv_video_writer_write_frame(cb_data->writer, out_buffer); - if (MEDIA_VISION_ERROR_NONE != err) { - printf(TEXT_RED "ERROR: Errors were occurred during writing frame #%i" - "to the result video file; code %i" TEXT_RESET "\n", - cb_data->frame_number, - err); - return; + if (cb_data->is_video) { + err = mv_video_writer_write_frame(cb_data->writer, out_buffer); + if (MEDIA_VISION_ERROR_NONE != err) { + printf(TEXT_RED "ERROR: Errors were occurred during writing frame #%i" + "to the result video file; code %i" TEXT_RESET "\n", + cb_data->frame_number, + err); + return; + } + } else { + char out_file_name[FILE_PATH_SIZE]; + snprintf(out_file_name, FILE_PATH_SIZE, "%s_%03d.jpg", + cb_data->out_file_path, + cb_data->frame_number); + + err = save_image_from_buffer(out_file_name, out_buffer, &image_data, 100); + if (MEDIA_VISION_ERROR_NONE != err) { + printf(TEXT_RED "ERROR: Errors were occurred during writing frame #%i" + "to the result image file; code %i" TEXT_RESET "\n", + cb_data->frame_number, + err); + return; + } } } @@ -1692,6 +1714,8 @@ int process_video_file( cb_data.target = tracking_model; cb_data.writer = writer; cb_data.frame_number = 0; + cb_data.is_video = true; + err = mv_video_reader_set_new_sample_cb( reader, track_on_sample_cb, @@ -1753,6 +1777,118 @@ int process_video_file( return MEDIA_VISION_ERROR_NONE; } +static int cmpstring(const void *p1, const void *p2) +{ + return strcmp((char * const) p1, (char * const) p2); +} + +int process_image_file( + mv_face_tracking_model_h tracking_model, + const char *track_target_file_name, + const char *track_result_file_name) +{ + if (track_target_file_name == NULL) + return MEDIA_VISION_ERROR_INVALID_PARAMETER; + + image_data_s image_info; + + int frame_idx; + int err = MEDIA_VISION_ERROR_NONE; + int frames_counter = 0; + char (*frames)[FILE_PATH_SIZE] = (char **)malloc(0); + + struct dirent *ent; + DIR *dir = opendir(track_target_file_name); + + if (dir == NULL) { + free(frames); + return MEDIA_VISION_ERROR_INVALID_PATH; + } + + while ((ent = readdir(dir)) != NULL) { + if (ent->d_name[0] == '.' || strlen(ent->d_name) < 4) + continue; + + if (strcmp(".jpg", ent->d_name + strlen(ent->d_name) - 4) != 0) + continue; + + + frames_counter++; + frames = (char **) realloc(frames, frames_counter * FILE_PATH_SIZE); + + + snprintf(frames[frames_counter -1], FILE_PATH_SIZE, "%s/%s", + track_target_file_name, ent->d_name); + } + + closedir(dir); + + if (frames_counter <= 0) + return MEDIA_VISION_ERROR_INVALID_PATH; + + qsort(&frames[0], frames_counter, FILE_PATH_SIZE, cmpstring); + + mv_source_h source = NULL; + err = mv_create_source(&source); + if (err != MEDIA_VISION_ERROR_NONE) { + printf(TEXT_RED "\nERROR: Errors(code %i) were occurred during" + "mv_create_source\n", TEXT_RESET "\n", err); + free(frames); + if (source) + mv_destroy_source(source); + + return err; + } + + tracking_cb_data cb_data; + cb_data.target = tracking_model; + cb_data.writer = NULL; + cb_data.is_video = false; + snprintf(cb_data.out_file_path, FILE_PATH_SIZE, "%s", track_result_file_name); + + for (frame_idx = 0; frame_idx < frames_counter; ++frame_idx) { + cb_data.frame_number = frame_idx; + + mv_source_clear(source); + + unsigned char *data_buffer = NULL; + unsigned long buffer_size = 0; + image_data_s image_data; + + err = load_image_to_buffer(frames[frame_idx], &data_buffer, &buffer_size, &image_data); + if (err != MEDIA_VISION_ERROR_NONE) { + printf(TEXT_RED "\nWARN: WARN(code %i) were occurred during" + "load_image_to_media_source, but continue\n", TEXT_RESET "\n", err); + + if (data_buffer != NULL) + destroy_loaded_buffer(data_buffer); + + continue; + } + + err = mv_source_fill_by_buffer(source, data_buffer, + buffer_size, + image_data.image_width, + image_data.image_height, + image_data.image_colorspace); + if (data_buffer != NULL) + destroy_loaded_buffer(data_buffer); + + if (err != MEDIA_VISION_ERROR_NONE) { + printf(TEXT_RED "\nWARN: WARN(code %i) were occurred during" + "mv_source_fill_by_buffer, but continue\n", TEXT_RESET "\n", err); + continue; + } + + err = mv_face_track(source, tracking_model, NULL, track_cb, false, &cb_data); + } + + mv_destroy_source(source); + free(frames); + + return MEDIA_VISION_ERROR_NONE; +} + int perform_mv_face_track(mv_face_tracking_model_h tracking_model) { printf(TEXT_YELLOW "Before any tracking session the tracking model\n" @@ -1767,18 +1903,56 @@ int perform_mv_face_track(mv_face_tracking_model_h tracking_model) char *track_target_file_name = NULL; char *track_result_file_name = NULL; - while (input_string("Input video file name to track on:", - 1024, &(track_target_file_name)) == -1) - printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n"); + int res = MEDIA_VISION_ERROR_NONE; + int sel_opt = 0; + const int options[2] = {1, 2}; + const char *names[2] = {"Track with the video file", + "Track with the image files"}; - while (input_string("Input video file name to save tracking results:", - 1024, &(track_result_file_name)) == -1) - printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n"); + bool is_video = false; + while (!sel_opt) { + sel_opt = show_menu("Select action:", options, names, 2); + + switch (sel_opt) { + case 1: + is_video = true; + break; + case 2: + is_video = false; + break; + default: + sel_opt = 0; + break; + } + } + + if (is_video) { + while (input_string("Input video file name to track on:", + 1024, &(track_target_file_name)) == -1) + printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n"); + + while (input_string("Input video file name to save tracking results:", + 1024, &(track_result_file_name)) == -1) + printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n"); - const int res = process_video_file( - tracking_model, - track_target_file_name, - track_result_file_name); + res = process_video_file( + tracking_model, + track_target_file_name, + track_result_file_name); + } else { + while (input_string("Input image file path to track on:", + 1024, &(track_target_file_name)) == -1) + printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n"); + + while (input_string("Input image file name to save tracking results:", + 1024, &(track_result_file_name)) == -1) + printf(TEXT_RED "Incorrect input! Try again." TEXT_RESET "\n"); + + res = process_image_file( + tracking_model, + track_target_file_name, + track_result_file_name); + } free(track_target_file_name); free(track_result_file_name); diff --git a/test/testsuites/image/image_test_suite.c b/test/testsuites/image/image_test_suite.c index fa690e3..dc5503c 100644 --- a/test/testsuites/image/image_test_suite.c +++ b/test/testsuites/image/image_test_suite.c @@ -27,6 +27,8 @@ #include +#define FILE_PATH_SIZE 1024 + typedef enum { SOURCE_TYPE_GENERATION, SOURCE_TYPE_LOADING, @@ -751,7 +753,7 @@ int perform_clone_image_object(mv_image_object_h src, mv_image_object_h *result) return err; } -int handle_tracking_result( +int handle_tracking_video_result( mv_video_writer_h writer, mv_source_h frame, int frame_number, @@ -834,10 +836,102 @@ int handle_tracking_result( return err; } +int handle_tracking_image_result( + const char *out_file_path, + mv_source_h frame, + int frame_number, + mv_quadrangle_s *location) +{ + unsigned char *data_buffer = NULL; + unsigned int buffer_size = 0; + image_data_s image_data; + + int err = mv_source_get_buffer(frame, &data_buffer, &buffer_size); + if (MEDIA_VISION_ERROR_NONE != err) { + printf( + "ERROR: Errors were occurred during getting buffer from the " + "source; code %i\n", + err); + return err; + } + + err = mv_source_get_width(frame, &image_data.image_width); + if (MEDIA_VISION_ERROR_NONE != err) { + printf( + "ERROR: Errors were occurred during getting width from the " + "source; code %i\n", + err); + return err; + } + + err = mv_source_get_height(frame, &image_data.image_height); + if (MEDIA_VISION_ERROR_NONE != err) { + printf( + "ERROR: Errors were occurred during getting height from the " + "source; code %i\n", + err); + return err; + } + + err = mv_source_get_colorspace(frame, &image_data.image_colorspace); + + if (location) { + printf( + "Frame #%i: object is found." + "Location: {%i, %i}; {%i, %i}; {%i, %i}; {%i, %i}.\n", + frame_number, + location->points[0].x, + location->points[0].y, + location->points[1].x, + location->points[1].y, + location->points[2].x, + location->points[2].y, + location->points[3].x, + location->points[3].y); + const int thickness = 2; + const int color[] = {0, 255, 0}; + + err = draw_quadrangle_on_buffer( + *location, + thickness, + color, + &image_data, + data_buffer); + if (MEDIA_VISION_ERROR_NONE != err) { + printf( + "ERROR: Errors were occurred during drawing quadrangle on " + "the frame; code %i\n", + err); + return err; + } + } else { + usleep(330000); + printf("Frame #%i: object isn't found.\n", frame_number); + } + + char out_file_name[FILE_PATH_SIZE]; + snprintf(out_file_name, FILE_PATH_SIZE, "%s_%03d.jpg", + out_file_path, + frame_number); + + err = save_image_from_buffer(out_file_name, data_buffer, &image_data, 100); + if (MEDIA_VISION_ERROR_NONE != err) { + printf( + "ERROR: Errors were occurred during writing frame to the " + "result image file; code %i\n", + err); + return err; + } + + return err; +} + typedef struct { mv_image_tracking_model_h target; mv_video_writer_h writer; int frame_number; + bool is_video; + char out_file_path[FILE_PATH_SIZE]; } tracking_cb_data; void tracked_cb( @@ -854,7 +948,10 @@ void tracked_cb( tracking_cb_data *cb_data = (tracking_cb_data*)user_data; - handle_tracking_result(cb_data->writer, source, cb_data->frame_number, location); + if (cb_data->is_video) + handle_tracking_video_result(cb_data->writer, source, cb_data->frame_number, location); + else + handle_tracking_image_result(cb_data->out_file_path, source, cb_data->frame_number, location); MEDIA_VISION_FUNCTION_LEAVE(); } @@ -939,7 +1036,7 @@ void eos_frame_cb( pthread_mutex_unlock((pthread_mutex_t*)user_data); } -int perform_track(mv_image_tracking_model_h target) +int perform_track_video(mv_image_tracking_model_h target) { if (NULL == target) { printf("\nTarget is invalid. It is impossible to track of this target.\n"); @@ -1049,6 +1146,7 @@ int perform_track(mv_image_tracking_model_h target) cb_data.target = target; cb_data.writer = writer; cb_data.frame_number = 0; + cb_data.is_video = true; err = mv_video_reader_set_new_sample_cb(reader, new_frame_cb, &cb_data); if (MEDIA_VISION_ERROR_NONE != err) { printf( @@ -1103,6 +1201,141 @@ int perform_track(mv_image_tracking_model_h target) return err; } +static int cmpstring(const void *p1, const void *p2) +{ + return strcmp((char * const) p1, (char * const) p2); +} + +int perform_track_image(mv_image_tracking_model_h target) +{ + if (NULL == target) { + printf("\nTarget is invalid. It is impossible to track of this target.\n"); + return MEDIA_VISION_ERROR_INVALID_PARAMETER; + } + + MEDIA_VISION_FUNCTION_ENTER(); + + char *path_to_image = NULL; + char *path_to_generated_image = NULL; + image_data_s image_data = {0}; + + while (input_string("Input path for tracking:", + 1024, &path_to_image) == -1) { + printf("Incorrect input! Try again.\n"); + } + + while (input_string("Input file name for generated results:", + 1024, &path_to_generated_image) == -1) { + printf("Incorrect input! Try again.\n"); + } + + int frame_idx; + int err = MEDIA_VISION_ERROR_NONE; + int frames_counter = 0; + char (*frames)[FILE_PATH_SIZE] = (char **)malloc(0); + + struct dirent *ent; + DIR *dir = opendir(path_to_image); + + if (dir == NULL) { + free(frames); + return MEDIA_VISION_ERROR_INVALID_PATH; + } + + while ((ent = readdir(dir)) != NULL) { + if (ent->d_name[0] == '.' || strlen(ent->d_name) < 4) + continue; + + if (strcmp(".jpg", ent->d_name + strlen(ent->d_name) -4) != 0) + continue; + + frames_counter++; + frames = (char**)realloc(frames, frames_counter * FILE_PATH_SIZE); + + snprintf(frames[frames_counter -1], FILE_PATH_SIZE, "%s/%s", path_to_image, ent->d_name); + } + + closedir(dir); + + if (frames_counter <= 0) + return MEDIA_VISION_ERROR_INVALID_PATH; + + qsort(&frames[0], frames_counter, FILE_PATH_SIZE, cmpstring); + + mv_source_h source = NULL; + err = mv_create_source(&source); + if (err != MEDIA_VISION_ERROR_NONE) { + printf("\nERROR: Errors(code %i) were occurred during" + "mv_create_source\n", err); + free(frames); + if (source) + mv_destroy_source(source); + + return err; + } + + tracking_cb_data cb_data; + cb_data.target = target; + cb_data.writer = NULL; + cb_data.is_video = false; + snprintf(cb_data.out_file_path, FILE_PATH_SIZE, "%s", path_to_generated_image); + + for (frame_idx = 0; frame_idx < frames_counter; ++frame_idx) { + cb_data.frame_number = frame_idx; + + mv_source_clear(source); + + unsigned char *data_buffer = NULL; + unsigned long buffer_size = 0; + image_data_s image_data; + + err = load_image_to_buffer(frames[frame_idx], &data_buffer, &buffer_size, &image_data); + if (err != MEDIA_VISION_ERROR_NONE) { + printf("\nWARN: WARN(code %i) were occurred during" + "load_image_to_media_source, but continue\n", err); + + if (data_buffer != NULL) + destroy_loaded_buffer(data_buffer); + + continue; + } + + err = mv_source_fill_by_buffer(source, data_buffer, + buffer_size, + image_data.image_width, + image_data.image_height, + image_data.image_colorspace); + + if (data_buffer != NULL) + destroy_loaded_buffer(data_buffer); + + if (err != MEDIA_VISION_ERROR_NONE) { + printf("\nWARN: WARN(code %i) were occurred during" + "mv_source_fill_by_buffer, but continue\n", err); + continue; + } + + err = mv_image_track(source, + cb_data.target, + NULL, + tracked_cb, + &cb_data); + + } + + mv_destroy_source(source); + + free(frames); + free(path_to_image); + free(path_to_generated_image); + + printf("\nTracking process is finished\n"); + + MEDIA_VISION_FUNCTION_LEAVE(); + + return err; +} + int perform_save_image_tracking_model(mv_image_tracking_model_h model) { MEDIA_VISION_FUNCTION_ENTER(); @@ -1753,10 +1986,33 @@ void perform_tracking_cases(GArray *image_objects, GArray *image_tracking_models err = select_testing_object( image_tracking_models, &temporary_testing_object, - "Select the object which you want to track on video"); + "Select the object which you want to track"); + + if (MEDIA_VISION_ERROR_NONE != err) { + printf("\nERROR: Errors(code %i) were occurred during " + "select_testing_object\n", err); + break; + } + + int track_opt = 0; + const int track_options[2] = {1, 2}; + const char *track_opt_names[2] = {"Track with the video file", + "Track with the image files"}; + while (!track_opt) { + track_opt = show_menu("Select actions:", track_options, track_opt_names, 2); - if (MEDIA_VISION_ERROR_NONE == err) - perform_track(temporary_testing_object->entity); + switch (track_opt) { + case 1: + perform_track_video(temporary_testing_object->entity); + break; + case 2: + perform_track_image(temporary_testing_object->entity); + break; + default: + track_opt = 0; + break; + } + } break; } case 10: { -- 2.7.4