00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <iostream>
00030
00031 #include <stdint.h>
00032 #include <stdlib.h>
00033 #include <pthread.h>
00034 #include <sys/time.h>
00035
00036 #include "opencv2/opencv.hpp"
00037 #include <opencv2/core/core.hpp>
00038 #include <opencv2/highgui/highgui.hpp>
00039 #include <opencv2/imgproc/imgproc_c.h>
00040
00041 #include "Classifier.h"
00042
00043 using namespace std;
00044 using namespace cv;
00045
00046 #include "opencv_consumer_interface.h"
00047
00048 struct opencv_sample_handler
00049 {
00050 Classifier *classifier;
00051
00052 volatile int detector_busy;
00053 volatile int result_update_flag;
00054 volatile int detector_quit_flag;
00055
00056 pthread_t detector_thread;
00057 cv::Mat detecting_mat;
00058 std::vector<Prediction> predictions;
00059 string *model_file;
00060 string *trained_file;
00061 string *mean_file;
00062 string *label_file;
00063
00064 int width;
00065 int height;
00066
00067 char first_result[4096];
00068 float first_prob;
00069 char second_result[4096];
00070 float second_prob;
00071 long milliseconds;
00072 };
00073
00074
00075 static void
00076 matPrint(Mat &img, int lineOffsY, Scalar fontColor, const string &ss)
00077 {
00078 int fontFace = FONT_HERSHEY_DUPLEX;
00079 double fontScale = 1.;
00080 int fontThickness = 1;
00081 Size fontSize = cv::getTextSize("T[]", fontFace, fontScale, fontThickness, 0);
00082
00083 Point org;
00084 org.x = 1;
00085 org.y = 3 * fontSize.height * (lineOffsY + 1) / 2;
00086 putText(img, ss, org, fontFace, fontScale, CV_RGB(0,0,0), 5*fontThickness/2, 16);
00087 putText(img, ss, org, fontFace, fontScale, fontColor, fontThickness, 16);
00088
00089 return;
00090 }
00091
00092 static void *
00093 detector_thread_entry(void *arg)
00094 {
00095 struct opencv_sample_handler *handler =
00096 (struct opencv_sample_handler *) arg;
00097
00098 cv::Mat zero_img_buf =
00099 cv::Mat::zeros(handler->height, handler->width, CV_8U);
00100
00101 handler->classifier = new Classifier(*handler->model_file
00102 , *handler->trained_file
00103 , *handler->mean_file
00104 , *handler->label_file);
00105
00106 while (handler->detector_quit_flag == 0)
00107 {
00108 if (handler->detector_busy == 1)
00109 {
00110 cout << "To classify " << std::endl;
00111 struct timeval tp;
00112 gettimeofday(&tp, NULL);
00113 long start = tp.tv_sec * 1000 + tp.tv_usec / 1000;
00114 std::vector<Prediction> predictions =
00115 handler->classifier->Classify(handler->detecting_mat);
00116 gettimeofday(&tp, NULL);
00117 long end = tp.tv_sec * 1000 + tp.tv_usec / 1000;
00118
00119 handler->result_update_flag = 0;
00120 for (size_t i = 0; i < predictions.size(); i++)
00121 {
00122 Prediction p = predictions[i];
00123 std::cout << std::fixed << std::setprecision(4) << p.second
00124 << " - \"" << p.first << "\"" << std::endl;
00125 if (i == 0)
00126 {
00127 handler->first_prob = p.second;
00128 sprintf(handler->first_result, "%s", p.first.c_str());
00129 }
00130 else if (i == 1)
00131 {
00132 handler->second_prob = p.second;
00133 sprintf(handler->second_result, "%s", p.first.c_str());
00134 }
00135 }
00136 handler->milliseconds = end - start;
00137 handler->detector_busy = 0;
00138 handler->result_update_flag = 1;
00139 }
00140 }
00141
00142 pthread_exit(NULL);
00143 }
00144
00145 extern "C" void
00146 opencv_set_config(void *opencv_handler, int config_id, void *arg)
00147 {
00148 struct opencv_sample_handler *handler =
00149 (struct opencv_sample_handler *) opencv_handler;
00150
00151 cout << "opencv_set_config " << config_id << endl;
00152
00153 switch (config_id)
00154 {
00155 case OPENCV_CONSUMER_CONFIG_IMGWIDTH:
00156 handler->width = * (int *) arg;
00157 cout << "Image width " << handler->width << endl;
00158 break;
00159 case OPENCV_CONSUMER_CONFIG_IMGHEIGHT:
00160 handler->height = * (int *) arg;
00161 cout << "Image height " << handler->height << endl;
00162 break;
00163 case OPENCV_CONSUMER_CONFIG_CAFFE_MODELFILE:
00164 handler->model_file = new std::string((char *) arg);
00165 cout << "CAFFE model file : " << handler->model_file << endl;
00166 break;
00167 case OPENCV_CONSUMER_CONFIG_CAFFE_TRAINEDFILE:
00168 handler->trained_file = new std::string((char *) arg);
00169 cout << "CAFFE trained file : " << handler->trained_file << endl;
00170 break;
00171 case OPENCV_CONSUMER_CONFIG_CAFFE_MEANFILE:
00172 handler->mean_file = new std::string((char *) arg);
00173 cout << "CAFFE mean file : " << handler->mean_file << endl;
00174 break;
00175 case OPENCV_CONSUMER_CONFIG_CAFFE_LABELFILE:
00176 handler->label_file = new std::string((char *) arg);
00177 cout << "CAFFE label file : " << handler->label_file << endl;
00178 break;
00179 case OPENCV_CONSUMER_CONFIG_START:
00180 pthread_create(&handler->detector_thread
00181 , NULL, detector_thread_entry, (void *)handler);
00182 break;
00183 default:
00184 cerr << "Unknown config id: " << config_id << endl;
00185 break;
00186 }
00187
00188 return;
00189 }
00190
00191 extern "C" void *
00192 opencv_handler_open(void)
00193 {
00194 cout << "opencv_handler_open is called" << endl;
00195
00196 struct opencv_sample_handler *handler = (struct opencv_sample_handler *)
00197 malloc(sizeof(struct opencv_sample_handler));
00198
00199 memset(handler, 0, sizeof(struct opencv_sample_handler));
00200 handler->detector_busy = 0;
00201 handler->result_update_flag = 0;
00202 handler->detector_quit_flag = 0;
00203
00204 return handler;
00205 }
00206
00207 extern "C" void
00208 opencv_handler_close(void *opencv_handler)
00209 {
00210 struct opencv_sample_handler *handler =
00211 (struct opencv_sample_handler *) opencv_handler;
00212
00213 cout << "opencv_handler_close with " << handler << " is called" << endl;
00214
00215 handler->detector_quit_flag = 1;
00216 pthread_join(handler->detector_thread, NULL);
00217 delete handler->model_file;
00218 delete handler->trained_file;
00219 delete handler->mean_file;
00220 delete handler->label_file;
00221 delete handler->classifier;
00222
00223 free(handler);
00224
00225 return;
00226 }
00227
00228 extern "C" void
00229 opencv_img_processing(void *opencv_handler, uint8_t *pdata, int32_t width, int32_t height)
00230 {
00231 struct opencv_sample_handler *handler =
00232 (struct opencv_sample_handler *) opencv_handler;
00233
00234 cv::Mat imgbuf = cv::Mat(height, width, CV_8UC4, pdata);
00235 cv::Mat display_img;
00236
00237 if (handler->detector_busy == 0) {
00238
00239 imgbuf.copyTo(handler->detecting_mat);
00240 handler->detector_busy = 1;
00241 }
00242 cvtColor(imgbuf, display_img, CV_RGBA2BGRA);
00243 if (handler->result_update_flag)
00244 {
00245 ostringstream ss;
00246 ss.str("");
00247 ss << "FPS = " << std::fixed << std::setprecision(0)
00248 << 1000. / handler->milliseconds;
00249 matPrint(display_img, 0, CV_RGB(255,0,0), ss.str());
00250 ss.str("");
00251 ss << std::fixed << std::setprecision(2) << handler->first_prob << " - " << handler->first_result;
00252 matPrint(display_img, 1, CV_RGB(255,0,0), ss.str());
00253 ss.str("");
00254 ss << std::fixed << std::setprecision(2) << handler->second_prob << " - " << handler->second_result;
00255 matPrint(display_img, 2, CV_RGB(255,0,0), ss.str());
00256 }
00257 cv::imshow("img", display_img);
00258 waitKey(1);
00259 return;
00260 }