modality_vision : vison.c - add logic about classification from image 92/265192/1
authordyamy-lee <dyamy.lee@samsung.com>
Tue, 12 Oct 2021 04:51:30 +0000 (13:51 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Tue, 12 Oct 2021 14:34:51 +0000 (23:34 +0900)
Change-Id: If2d40f6f0a0c6f5d9908738e51bba56a8ed46638

src/modules/modality_vision/vision.c

index 53ea752..b75c3a3 100644 (file)
 
 #define TASK_IC 0
 
+#define NANO_PER_SEC ((__clock_t) 1000000000)
+#define NANO_PER_MILLI ((__clock_t) 1000000)
+#define MILLI_PER_SEC ((__clock_t) 1000)
+
+struct timespec diff(struct timespec start, struct timespec end)
+{
+       struct timespec temp;
+       if ((end.tv_nsec - start.tv_nsec) < 0) {
+               temp.tv_sec = end.tv_sec - start.tv_sec - 1;
+               temp.tv_nsec = NANO_PER_SEC + end.tv_nsec - start.tv_nsec;
+       } else {
+               temp.tv_sec = end.tv_sec - start.tv_sec;
+               temp.tv_nsec = end.tv_nsec - start.tv_nsec;
+       }
+       return temp;
+}
+
+unsigned long gettotalmillisec(const struct timespec time)
+{
+       return time.tv_sec * MILLI_PER_SEC + time.tv_nsec / NANO_PER_MILLI;
+}
+
 #define RET_IF_FAIL(exp)                                \
        do {                                                \
                int err = (exp);                                \
@@ -58,6 +80,93 @@ int max_confidence_idx = 0;
 mv_engine_config_h _engine_cfg = NULL;
 mv_inference_h _infer = NULL;
 
+void _send_vision_event_cb(void *data)
+{
+       mmi_provider_event_vision *ev = (mmi_provider_event_vision *)data;
+       if(!ev)
+       {
+               LOGE("mmi_provider_event_vision malloc fail\n");
+               return;
+       }
+       LOGD("Max Confidence idx = %.3f, type(state) = %d\n", ev->confidence, ev->type);
+       ecore_event_add(MMI_PROVIDER_EVENT_VISION, ev, NULL, NULL);
+}
+
+void _image_classified_cb(mv_source_h source, const int number_of_classes,
+                                                 const int *indices, const char **names,
+                                                 const float *confidences, void *user_data)
+{
+       LOGD("In callback: %d classes\n", number_of_classes);
+
+       for (int n = 0; n < number_of_classes; ++n) {
+               LOGD("%2d\n", indices[n]);
+               LOGD("%s\n", names[n]);
+               LOGD("%.3f\n", confidences[n]);
+               if(confidences[max_confidence_idx] < confidences[n])
+               {
+                       max_confidence_idx = n;
+               }
+       }
+       LOGI("Max Confidence idx = %d, It's result is %s, type(state) = %d\n", max_confidence_idx, names[max_confidence_idx], indices[max_confidence_idx]);
+
+       mmi_provider_event_vision *ev = calloc(1, sizeof(mmi_provider_event_vision));
+       if(!ev)
+       {
+               LOGE("mmi_provider_event_vision malloc fail\n");
+               return;
+       }
+
+       ev->type = indices[max_confidence_idx];
+       ev->confidence = confidences[max_confidence_idx];
+
+       if(user_data)
+       {
+               pthread_mutex_unlock((pthread_mutex_t*)user_data);
+               ecore_main_loop_thread_safe_call_async(_send_vision_event_cb, ev);
+               pthread_mutex_lock((pthread_mutex_t*)user_data);
+       }
+       else
+       {
+               ecore_main_loop_thread_safe_call_async(_send_vision_event_cb, ev);
+       }
+}
+
+int load_mv_source_from_file(
+               const char *path_to_image,
+               mv_source_h source)
+{
+       unsigned char *data_buffer = NULL;
+       unsigned long buffer_size = 0;
+       image_data_s image_data;
+
+       int err = load_image_to_buffer(path_to_image, &data_buffer,
+                                                                       &buffer_size, &image_data);
+       if (MEDIA_VISION_ERROR_NONE != err) {
+               LOGE("ERROR: Errors were occurred during opening file!!! code: %i\n",
+                       err);
+               if (NULL != data_buffer)
+                       destroy_loaded_buffer(data_buffer);
+
+               return err;
+       }
+
+       err = mv_source_fill_by_buffer(
+                       source, data_buffer,
+                       buffer_size,
+                       image_data.image_width,
+                       image_data.image_height,
+                       image_data.image_colorspace);
+
+       if (MEDIA_VISION_ERROR_NONE != err)
+               LOGE("ERROR: Errors were occurred during filling source!!! code %i\n",
+                       err);
+
+       if (NULL != data_buffer)
+               destroy_loaded_buffer(data_buffer);
+
+       return err;
+}
+
 int mv_inference_task_helper(mv_engine_config_h engine_cfg, int task_id)
 {
        mv_inference_h infer = NULL;
@@ -115,6 +224,67 @@ int engine_config_user_hosted_tflite_cpu(mv_engine_config_h handle,
        return MEDIA_VISION_ERROR_NONE;
 }
 
+int infer_task_with_image(const char *img_file_name, mv_inference_h infer, int task_id)
+{
+       mv_source_h mvSource = NULL;
+       struct timespec s_tspec;
+       struct timespec e_tspec;
+
+       int err = mv_create_source(&mvSource);
+       if (err != MEDIA_VISION_ERROR_NONE) {
+               LOGE("Fail to create mvSource.\n");
+               return err;
+       }
+       mv_source_clear(mvSource);
+       err = load_mv_source_from_file(img_file_name, mvSource);
+       if (err != MEDIA_VISION_ERROR_NONE) {
+               LOGE("Fail to load mvSource err: %d.\n", err);
+               return err;
+       }
+
+       clock_gettime(CLOCK_MONOTONIC, &s_tspec);
+
+       switch (task_id) {
+       case TASK_IC:
+               err = mv_inference_image_classify(mvSource, infer, NULL,
+                                                                                 _image_classified_cb, NULL);
+               break;
+       default:
+               err = MEDIA_VISION_ERROR_INVALID_PARAMETER;
+               break;
+       }
+       if (err != MEDIA_VISION_ERROR_NONE)
+               LOGE("Fail to infer task [err:%i]\n", err);
+
+       clock_gettime(CLOCK_MONOTONIC, &e_tspec);
+       struct timespec diffspec = diff(s_tspec, e_tspec);
+       unsigned long timeDiff = gettotalmillisec(diffspec);
+       LOGE("elapsed time : %lu(ms)\n", timeDiff);
+
+       err = mv_destroy_source(mvSource);
+       if (err != MEDIA_VISION_ERROR_NONE)
+               LOGE("Fail to destroy mvSource [err:%i]\n", err);
+
+       return err;
+}
+
+void classification_from_image(const char *path_to_image)
+{
+       int err = MEDIA_VISION_ERROR_NONE;
+
+       if(_infer)
+       {
+               err = infer_task_with_image(path_to_image, _infer, TASK_IC);
+               if (err != MEDIA_VISION_ERROR_NONE) {
+                       LOGE("Fail to infer task");
+               }
+       }
+       else
+       {
+               LOGE("Fail to find infer handler\n");
+       }
+}
+
 int image_classification_init(void)
 {
        int err = MEDIA_VISION_ERROR_NONE;