1 #include <DetectionBasedTracker_jni.h>
2 #include <opencv2/core.hpp>
3 #include <opencv2/objdetect.hpp>
4 
5 #include <string>
6 #include <vector>
7 
8 #include <android/log.h>
9 
10 #define LOG_TAG "FaceDetection/DetectionBasedTracker"
11 #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
12 
13 using namespace std;
14 using namespace cv;
15 
vector_Rect_to_Mat(vector<Rect> & v_rect,Mat & mat)16 inline void vector_Rect_to_Mat(vector<Rect>& v_rect, Mat& mat)
17 {
18     mat = Mat(v_rect, true);
19 }
20 
21 class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
22 {
23 public:
CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector)24     CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
25             IDetector(),
26             Detector(detector)
27     {
28         LOGD("CascadeDetectorAdapter::Detect::Detect");
29         CV_Assert(detector);
30     }
31 
detect(const cv::Mat & Image,std::vector<cv::Rect> & objects)32     void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects)
33     {
34         LOGD("CascadeDetectorAdapter::Detect: begin");
35         LOGD("CascadeDetectorAdapter::Detect: scaleFactor=%.2f, minNeighbours=%d, minObjSize=(%dx%d), maxObjSize=(%dx%d)", scaleFactor, minNeighbours, minObjSize.width, minObjSize.height, maxObjSize.width, maxObjSize.height);
36         Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize);
37         LOGD("CascadeDetectorAdapter::Detect: end");
38     }
39 
~CascadeDetectorAdapter()40     virtual ~CascadeDetectorAdapter()
41     {
42         LOGD("CascadeDetectorAdapter::Detect::~Detect");
43     }
44 
45 private:
46     CascadeDetectorAdapter();
47     cv::Ptr<cv::CascadeClassifier> Detector;
48 };
49 
50 struct DetectorAgregator
51 {
52     cv::Ptr<CascadeDetectorAdapter> mainDetector;
53     cv::Ptr<CascadeDetectorAdapter> trackingDetector;
54 
55     cv::Ptr<DetectionBasedTracker> tracker;
DetectorAgregatorDetectorAgregator56     DetectorAgregator(cv::Ptr<CascadeDetectorAdapter>& _mainDetector, cv::Ptr<CascadeDetectorAdapter>& _trackingDetector):
57             mainDetector(_mainDetector),
58             trackingDetector(_trackingDetector)
59     {
60         CV_Assert(_mainDetector);
61         CV_Assert(_trackingDetector);
62 
63         DetectionBasedTracker::Parameters DetectorParams;
64         tracker = makePtr<DetectionBasedTracker>(mainDetector, trackingDetector, DetectorParams);
65     }
66 };
67 
Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject(JNIEnv * jenv,jclass,jstring jFileName,jint faceSize)68 JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject
69 (JNIEnv * jenv, jclass, jstring jFileName, jint faceSize)
70 {
71     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject enter");
72     const char* jnamestr = jenv->GetStringUTFChars(jFileName, NULL);
73     string stdFileName(jnamestr);
74     jlong result = 0;
75 
76     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject");
77 
78     try
79     {
80         cv::Ptr<CascadeDetectorAdapter> mainDetector = makePtr<CascadeDetectorAdapter>(
81             makePtr<CascadeClassifier>(stdFileName));
82         cv::Ptr<CascadeDetectorAdapter> trackingDetector = makePtr<CascadeDetectorAdapter>(
83             makePtr<CascadeClassifier>(stdFileName));
84         result = (jlong)new DetectorAgregator(mainDetector, trackingDetector);
85         if (faceSize > 0)
86         {
87             mainDetector->setMinObjectSize(Size(faceSize, faceSize));
88             //trackingDetector->setMinObjectSize(Size(faceSize, faceSize));
89         }
90     }
91     catch(const cv::Exception& e)
92     {
93         LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
94         jclass je = jenv->FindClass("org/opencv/core/CvException");
95         if(!je)
96             je = jenv->FindClass("java/lang/Exception");
97         jenv->ThrowNew(je, e.what());
98     }
99     catch (...)
100     {
101         LOGD("nativeCreateObject caught unknown exception");
102         jclass je = jenv->FindClass("java/lang/Exception");
103         jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeCreateObject()");
104         return 0;
105     }
106 
107     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject exit");
108     return result;
109 }
110 
Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject(JNIEnv * jenv,jclass,jlong thiz)111 JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject
112 (JNIEnv * jenv, jclass, jlong thiz)
113 {
114     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject");
115 
116     try
117     {
118         if(thiz != 0)
119         {
120             ((DetectorAgregator*)thiz)->tracker->stop();
121             delete (DetectorAgregator*)thiz;
122         }
123     }
124     catch(const cv::Exception& e)
125     {
126         LOGD("nativeestroyObject caught cv::Exception: %s", e.what());
127         jclass je = jenv->FindClass("org/opencv/core/CvException");
128         if(!je)
129             je = jenv->FindClass("java/lang/Exception");
130         jenv->ThrowNew(je, e.what());
131     }
132     catch (...)
133     {
134         LOGD("nativeDestroyObject caught unknown exception");
135         jclass je = jenv->FindClass("java/lang/Exception");
136         jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeDestroyObject()");
137     }
138     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject exit");
139 }
140 
Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart(JNIEnv * jenv,jclass,jlong thiz)141 JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart
142 (JNIEnv * jenv, jclass, jlong thiz)
143 {
144     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart");
145 
146     try
147     {
148         ((DetectorAgregator*)thiz)->tracker->run();
149     }
150     catch(const cv::Exception& e)
151     {
152         LOGD("nativeStart caught cv::Exception: %s", e.what());
153         jclass je = jenv->FindClass("org/opencv/core/CvException");
154         if(!je)
155             je = jenv->FindClass("java/lang/Exception");
156         jenv->ThrowNew(je, e.what());
157     }
158     catch (...)
159     {
160         LOGD("nativeStart caught unknown exception");
161         jclass je = jenv->FindClass("java/lang/Exception");
162         jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeStart()");
163     }
164     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart exit");
165 }
166 
Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop(JNIEnv * jenv,jclass,jlong thiz)167 JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop
168 (JNIEnv * jenv, jclass, jlong thiz)
169 {
170     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop");
171 
172     try
173     {
174         ((DetectorAgregator*)thiz)->tracker->stop();
175     }
176     catch(const cv::Exception& e)
177     {
178         LOGD("nativeStop caught cv::Exception: %s", e.what());
179         jclass je = jenv->FindClass("org/opencv/core/CvException");
180         if(!je)
181             je = jenv->FindClass("java/lang/Exception");
182         jenv->ThrowNew(je, e.what());
183     }
184     catch (...)
185     {
186         LOGD("nativeStop caught unknown exception");
187         jclass je = jenv->FindClass("java/lang/Exception");
188         jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeStop()");
189     }
190     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop exit");
191 }
192 
Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize(JNIEnv * jenv,jclass,jlong thiz,jint faceSize)193 JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize
194 (JNIEnv * jenv, jclass, jlong thiz, jint faceSize)
195 {
196     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize -- BEGIN");
197 
198     try
199     {
200         if (faceSize > 0)
201         {
202             ((DetectorAgregator*)thiz)->mainDetector->setMinObjectSize(Size(faceSize, faceSize));
203             //((DetectorAgregator*)thiz)->trackingDetector->setMinObjectSize(Size(faceSize, faceSize));
204         }
205     }
206     catch(const cv::Exception& e)
207     {
208         LOGD("nativeStop caught cv::Exception: %s", e.what());
209         jclass je = jenv->FindClass("org/opencv/core/CvException");
210         if(!je)
211             je = jenv->FindClass("java/lang/Exception");
212         jenv->ThrowNew(je, e.what());
213     }
214     catch (...)
215     {
216         LOGD("nativeSetFaceSize caught unknown exception");
217         jclass je = jenv->FindClass("java/lang/Exception");
218         jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeSetFaceSize()");
219     }
220     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize -- END");
221 }
222 
223 
Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect(JNIEnv * jenv,jclass,jlong thiz,jlong imageGray,jlong faces)224 JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect
225 (JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces)
226 {
227     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect");
228 
229     try
230     {
231         vector<Rect> RectFaces;
232         ((DetectorAgregator*)thiz)->tracker->process(*((Mat*)imageGray));
233         ((DetectorAgregator*)thiz)->tracker->getObjects(RectFaces);
234         *((Mat*)faces) = Mat(RectFaces, true);
235     }
236     catch(const cv::Exception& e)
237     {
238         LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
239         jclass je = jenv->FindClass("org/opencv/core/CvException");
240         if(!je)
241             je = jenv->FindClass("java/lang/Exception");
242         jenv->ThrowNew(je, e.what());
243     }
244     catch (...)
245     {
246         LOGD("nativeDetect caught unknown exception");
247         jclass je = jenv->FindClass("java/lang/Exception");
248         jenv->ThrowNew(je, "Unknown exception in JNI code DetectionBasedTracker.nativeDetect()");
249     }
250     LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect END");
251 }
252