#include <vector>
+namespace cv
+{
class DetectionBasedTracker
{
public:
struct Parameters
{
- int minObjectSize;
- int maxObjectSize;
- double scaleFactor;
int maxTrackLifetime;
- int minNeighbors;
int minDetectionPeriod; //the minimal time between run of the big object detector (on the whole frame) in ms (1000 mean 1 sec), default=0
Parameters();
};
- DetectionBasedTracker(const std::string& cascadeFilename, const Parameters& params);
+ class IDetector
+ {
+ public:
+ IDetector():
+ minObjSize(96, 96),
+ maxObjSize(INT_MAX, INT_MAX),
+ minNeighbours(2),
+ scaleFactor(1.1f)
+ {}
+
+ virtual void detect(const cv::Mat& Image, std::vector<cv::Rect>& objects) = 0;
+
+ void setMinObjectSize(const cv::Size& min)
+ {
+ minObjSize = min;
+ }
+ void setMaxObjectSize(const cv::Size& max)
+ {
+ maxObjSize = max;
+ }
+ cv::Size getMinObjectSize() const
+ {
+ return minObjSize;
+ }
+ cv::Size getMaxObjectSize() const
+ {
+ return maxObjSize;
+ }
+ float getScaleFactor()
+ {
+ return scaleFactor;
+ }
+ void setScaleFactor(float value)
+ {
+ scaleFactor = value;
+ }
+ int getMinNeighbours()
+ {
+ return minNeighbours;
+ }
+ void setMinNeighbours(int value)
+ {
+ minNeighbours = value;
+ }
+ virtual ~IDetector() {}
+
+ protected:
+ cv::Size minObjSize;
+ cv::Size maxObjSize;
+ int minNeighbours;
+ float scaleFactor;
+ };
+
+ DetectionBasedTracker(cv::Ptr<IDetector> MainDetector, cv::Ptr<IDetector> TrackingDetector, const Parameters& params);
virtual ~DetectionBasedTracker();
virtual bool run();
cv::Ptr<SeparateDetectionWork> separateDetectionWork;
friend void* workcycleObjectDetectorFunction(void* p);
-
struct InnerParameters
{
int numLastPositionsToTrack;
std::vector<float> weightsPositionsSmoothing;
std::vector<float> weightsSizesSmoothing;
- cv::CascadeClassifier cascadeForTracking;
-
+ cv::Ptr<IDetector> cascadeForTracking;
void updateTrackedObjects(const std::vector<cv::Rect>& detectedObjects);
cv::Rect calcTrackedObjectPositionToShow(int i) const;
void detectInRegion(const cv::Mat& img, const cv::Rect& r, std::vector<cv::Rect>& detectedObjectsInRegions);
};
-
+} //end of cv namespace
#endif
-
{
return cv::Point2f(r.x+((float)r.width)/2, r.y+((float)r.height)/2);
};
+
static inline cv::Rect scale_rect(const cv::Rect& r, float scale)
{
cv::Point2f m=centerRect(r);
return cv::Rect(x, y, cvRound(width), cvRound(height));
};
-void* workcycleObjectDetectorFunction(void* p);
-class DetectionBasedTracker::SeparateDetectionWork
+namespace cv
+{
+ void* workcycleObjectDetectorFunction(void* p);
+}
+
+class cv::DetectionBasedTracker::SeparateDetectionWork
{
public:
- SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, const std::string& cascadeFilename);
+ SeparateDetectionWork(cv::DetectionBasedTracker& _detectionBasedTracker, cv::Ptr<DetectionBasedTracker::IDetector> _detector);
virtual ~SeparateDetectionWork();
bool communicateWithDetectingThread(const Mat& imageGray, vector<Rect>& rectsWhereRegions);
bool run();
protected:
DetectionBasedTracker& detectionBasedTracker;
- cv::CascadeClassifier cascadeInThread;
+ cv::Ptr<DetectionBasedTracker::IDetector> cascadeInThread;
pthread_t second_workthread;
pthread_mutex_t mutex;
long long timeWhenDetectingThreadStartedWork;
};
-DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, const std::string& cascadeFilename)
+cv::DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, cv::Ptr<DetectionBasedTracker::IDetector> _detector)
:detectionBasedTracker(_detectionBasedTracker),
cascadeInThread(),
isObjectDetectingReady(false),
stateThread(STATE_THREAD_STOPPED),
timeWhenDetectingThreadStartedWork(-1)
{
- if(!cascadeInThread.load(cascadeFilename)) {
- CV_Error(CV_StsBadArg, "DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork: Cannot load a cascade from the file '"+cascadeFilename+"'");
- }
+ CV_Assert(!_detector.empty());
+
+ cascadeInThread = _detector;
+
int res=0;
res=pthread_mutex_init(&mutex, NULL);//TODO: should be attributes?
if (res) {
}
}
-DetectionBasedTracker::SeparateDetectionWork::~SeparateDetectionWork()
+cv::DetectionBasedTracker::SeparateDetectionWork::~SeparateDetectionWork()
{
if(stateThread!=STATE_THREAD_STOPPED) {
LOGE("\n\n\nATTENTION!!! dangerous algorithm error: destructor DetectionBasedTracker::DetectionBasedTracker::~SeparateDetectionWork is called before stopping the workthread");
pthread_cond_destroy(&objectDetectorRun);
pthread_mutex_destroy(&mutex);
}
-bool DetectionBasedTracker::SeparateDetectionWork::run()
+bool cv::DetectionBasedTracker::SeparateDetectionWork::run()
{
LOGD("DetectionBasedTracker::SeparateDetectionWork::run() --- start");
pthread_mutex_lock(&mutex);
} while(0)
#endif
-void* workcycleObjectDetectorFunction(void* p)
+void* cv::workcycleObjectDetectorFunction(void* p)
{
- CATCH_ALL_AND_LOG({ ((DetectionBasedTracker::SeparateDetectionWork*)p)->workcycleObjectDetector(); });
+ CATCH_ALL_AND_LOG({ ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->workcycleObjectDetector(); });
try{
- ((DetectionBasedTracker::SeparateDetectionWork*)p)->stateThread=DetectionBasedTracker::SeparateDetectionWork::STATE_THREAD_STOPPED;
+ ((cv::DetectionBasedTracker::SeparateDetectionWork*)p)->stateThread = cv::DetectionBasedTracker::SeparateDetectionWork::STATE_THREAD_STOPPED;
} catch(...) {
LOGE0("DetectionBasedTracker: workcycleObjectDetectorFunction: ERROR concerning pointer, received as the function parameter");
}
return NULL;
}
-void DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
+void cv::DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
{
static double freq = getTickFrequency();
LOGD0("DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- start");
int64 t1_detect=getTickCount();
- int minObjectSize=detectionBasedTracker.parameters.minObjectSize;
- Size min_objectSize=Size(minObjectSize, minObjectSize);
-
- int maxObjectSize=detectionBasedTracker.parameters.maxObjectSize;
- Size max_objectSize(maxObjectSize, maxObjectSize);
+ cascadeInThread->detect(imageSeparateDetecting, objects);
-
- cascadeInThread.detectMultiScale( imageSeparateDetecting, objects,
+ /*cascadeInThread.detectMultiScale( imageSeparateDetecting, objects,
detectionBasedTracker.parameters.scaleFactor, detectionBasedTracker.parameters.minNeighbors, 0
|CV_HAAR_SCALE_IMAGE
,
min_objectSize,
max_objectSize
);
+ */
+
LOGD("DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- end handling imageSeparateDetecting");
if (!isWorking()) {
LOGI("DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector: Returning");
}
-void DetectionBasedTracker::SeparateDetectionWork::stop()
+void cv::DetectionBasedTracker::SeparateDetectionWork::stop()
{
//FIXME: TODO: should add quickStop functionality
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
}
-void DetectionBasedTracker::SeparateDetectionWork::resetTracking()
+void cv::DetectionBasedTracker::SeparateDetectionWork::resetTracking()
{
LOGD("DetectionBasedTracker::SeparateDetectionWork::resetTracking");
pthread_mutex_lock(&mutex);
}
-bool DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingThread(const Mat& imageGray, vector<Rect>& rectsWhereRegions)
+bool cv::DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingThread(const Mat& imageGray, vector<Rect>& rectsWhereRegions)
{
static double freq = getTickFrequency();
return shouldHandleResult;
}
-DetectionBasedTracker::Parameters::Parameters()
+cv::DetectionBasedTracker::Parameters::Parameters()
{
- minObjectSize=96;
- maxObjectSize=INT_MAX;
- scaleFactor=1.1;
maxTrackLifetime=5;
- minNeighbors=2;
minDetectionPeriod=0;
}
-
-
-DetectionBasedTracker::InnerParameters::InnerParameters()
+cv::DetectionBasedTracker::InnerParameters::InnerParameters()
{
numLastPositionsToTrack=4;
numStepsToWaitBeforeFirstShow=6;
coeffObjectSpeedUsingInPrediction=0.8;
}
-DetectionBasedTracker::DetectionBasedTracker(const std::string& cascadeFilename, const Parameters& params)
+
+cv::DetectionBasedTracker::DetectionBasedTracker(cv::Ptr<IDetector> MainDetector, cv::Ptr<IDetector> TrackingDetector, const Parameters& params)
:separateDetectionWork(),
+ parameters(params),
innerParameters(),
- numTrackedSteps(0)
+ numTrackedSteps(0),
+ cascadeForTracking(TrackingDetector)
{
- CV_Assert( (params.minObjectSize > 0)
- && (params.maxObjectSize >= 0)
- && (params.scaleFactor > 1.0)
- && (params.maxTrackLifetime >= 0) );
-
- if (!cascadeForTracking.load(cascadeFilename)) {
- CV_Error(CV_StsBadArg, "DetectionBasedTracker::DetectionBasedTracker: Cannot load a cascade from the file '"+cascadeFilename+"'");
- }
+ CV_Assert( (params.maxTrackLifetime >= 0)
+ && (!MainDetector.empty())
+ && (!TrackingDetector.empty()) );
- parameters=params;
-
- separateDetectionWork=new SeparateDetectionWork(*this, cascadeFilename);
+ separateDetectionWork = new SeparateDetectionWork(*this, MainDetector);
weightsPositionsSmoothing.push_back(1);
weightsSizesSmoothing.push_back(0.5);
weightsSizesSmoothing.push_back(0.3);
weightsSizesSmoothing.push_back(0.2);
-
}
-DetectionBasedTracker::~DetectionBasedTracker()
+
+cv::DetectionBasedTracker::~DetectionBasedTracker()
{
}
-
-
void DetectionBasedTracker::process(const Mat& imageGray)
{
-
CV_Assert(imageGray.type()==CV_8UC1);
if (!separateDetectionWork->isWorking()) {
Mat imageDetect=imageGray;
- int D=parameters.minObjectSize;
- if (D < 1)
- D=1;
-
vector<Rect> rectsWhereRegions;
bool shouldHandleResult=separateDetectionWork->communicateWithDetectingThread(imageGray, rectsWhereRegions);
-
-
if (shouldHandleResult) {
LOGD("DetectionBasedTracker::process: get _rectsWhereRegions were got from resultDetect");
} else {
continue;
}
-
//correction by speed of rectangle
if (n > 1) {
Point2f center=centerRect(r);
updateTrackedObjects(detectedObjectsInRegions);
}
-void DetectionBasedTracker::getObjects(std::vector<cv::Rect>& result) const
+void cv::DetectionBasedTracker::getObjects(std::vector<cv::Rect>& result) const
{
result.clear();
LOGD("DetectionBasedTracker::process: found a object with SIZE %d x %d, rect={%d, %d, %d x %d}", r.width, r.height, r.x, r.y, r.width, r.height);
}
}
-void DetectionBasedTracker::getObjects(std::vector<Object>& result) const
+
+void cv::DetectionBasedTracker::getObjects(std::vector<Object>& result) const
{
result.clear();
}
}
-
-
-bool DetectionBasedTracker::run()
+bool cv::DetectionBasedTracker::run()
{
return separateDetectionWork->run();
}
-void DetectionBasedTracker::stop()
+void cv::DetectionBasedTracker::stop()
{
separateDetectionWork->stop();
}
-void DetectionBasedTracker::resetTracking()
+void cv::DetectionBasedTracker::resetTracking()
{
separateDetectionWork->resetTracking();
trackedObjects.clear();
}
-void DetectionBasedTracker::updateTrackedObjects(const vector<Rect>& detectedObjects)
+void cv::DetectionBasedTracker::updateTrackedObjects(const vector<Rect>& detectedObjects)
{
enum {
NEW_RECTANGLE=-1,
}
}
}
-Rect DetectionBasedTracker::calcTrackedObjectPositionToShow(int i) const
+
+Rect cv::DetectionBasedTracker::calcTrackedObjectPositionToShow(int i) const
{
if ( (i < 0) || (i >= (int)trackedObjects.size()) ) {
LOGE("DetectionBasedTracker::calcTrackedObjectPositionToShow: ERROR: wrong i=%d", i);
double sum=0;
for(int j=0; j < Nsize; j++) {
int k=N-j-1;
- w+= lastPositions[k].width * weightsSizesSmoothing[j];
- h+= lastPositions[k].height * weightsSizesSmoothing[j];
+ w += lastPositions[k].width * weightsSizesSmoothing[j];
+ h += lastPositions[k].height * weightsSizesSmoothing[j];
sum+=weightsSizesSmoothing[j];
}
w /= sum;
Point br(lastPositions[k].br());
Point2f c1;
c1=tl;
- c1=c1* 0.5f;
+ c1=c1* 0.5f;
Point2f c2;
c2=br;
c2=c2*0.5f;
return res;
}
-void DetectionBasedTracker::detectInRegion(const Mat& img, const Rect& r, vector<Rect>& detectedObjectsInRegions)
+void cv::DetectionBasedTracker::detectInRegion(const Mat& img, const Rect& r, vector<Rect>& detectedObjectsInRegions)
{
Rect r0(Point(), img.size());
Rect r1=scale_rect(r, innerParameters.coeffTrackingWindowSize);
return;
}
- int d=std::min(r.width, r.height);
- d=cvRound(d * innerParameters.coeffObjectSizeToTrack);
+ int d = cvRound(std::min(r.width, r.height) * innerParameters.coeffObjectSizeToTrack);
vector<Rect> tmpobjects;
LOGD("DetectionBasedTracker::detectInRegion: img1.size()=%d x %d, d=%d",
img1.size().width, img1.size().height, d);
- int maxObjectSize=parameters.maxObjectSize;
- Size max_objectSize(maxObjectSize, maxObjectSize);
-
- cascadeForTracking.detectMultiScale( img1, tmpobjects,
+ cascadeForTracking->setMinObjectSize(Size(d, d));
+ cascadeForTracking->detect(img1, tmpobjects);
+ /*
+ detectMultiScale( img1, tmpobjects,
parameters.scaleFactor, parameters.minNeighbors, 0
|CV_HAAR_FIND_BIGGEST_OBJECT
|CV_HAAR_SCALE_IMAGE
,
Size(d,d),
max_objectSize
- );
+ );*/
for(size_t i=0; i < tmpobjects.size(); i++) {
Rect curres(tmpobjects[i].tl() + r1.tl(), tmpobjects[i].size());
}
}
-bool DetectionBasedTracker::setParameters(const Parameters& params)
+bool cv::DetectionBasedTracker::setParameters(const Parameters& params)
{
- if ( (params.minObjectSize <= 0)
- || (params.maxObjectSize < 0)
- || (params.scaleFactor <= 1.0)
- || (params.maxTrackLifetime < 0) )
+ if ( params.maxTrackLifetime < 0 )
{
LOGE("DetectionBasedTracker::setParameters: ERROR: wrong parameters value");
return false;
return true;
}
-const DetectionBasedTracker::Parameters& DetectionBasedTracker::getParameters()
+const cv::DetectionBasedTracker::Parameters& DetectionBasedTracker::getParameters()
{
return parameters;
}
mat = Mat(v_rect, true);
}
+class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
+{
+public:
+ CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
+ IDetector(),
+ Detector(detector)
+ {
+ CV_Assert(!detector.empty());
+ }
+
+ void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects)
+ {
+ Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize);
+ }
+
+ virtual ~CascadeDetectorAdapter()
+ {}
+
+private:
+ CascadeDetectorAdapter();
+ cv::Ptr<cv::CascadeClassifier> Detector;
+};
+
JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject
(JNIEnv * jenv, jclass, jstring jFileName, jint faceSize)
{
try
{
- DetectionBasedTracker::Parameters DetectorParams;
- if (faceSize > 0)
- DetectorParams.minObjectSize = faceSize;
- result = (jlong)new DetectionBasedTracker(stdFileName, DetectorParams);
+ // TODO: Reimplement using adapter
+// DetectionBasedTracker::Parameters DetectorParams;
+// if (faceSize > 0)
+// DetectorParams.minObjectSize = faceSize;
+// result = (jlong)new DetectionBasedTracker(stdFileName, DetectorParams);
}
catch(cv::Exception e)
{
- LOGD("nativeCreateObject catched cv::Exception: %s", e.what());
- jclass je = jenv->FindClass("org/opencv/core/CvException");
- if(!je)
- je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, e.what());
+ LOGD("nativeCreateObject catched cv::Exception: %s", e.what());
+ jclass je = jenv->FindClass("org/opencv/core/CvException");
+ if(!je)
+ je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, e.what());
}
catch (...)
{
- LOGD("nativeCreateObject catched unknown exception");
- jclass je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
- return 0;
+ LOGD("nativeCreateObject catched unknown exception");
+ jclass je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
+ return 0;
}
return result;
{
try
{
- ((DetectionBasedTracker*)thiz)->stop();
- delete (DetectionBasedTracker*)thiz;
+ ((DetectionBasedTracker*)thiz)->stop();
+ delete (DetectionBasedTracker*)thiz;
}
catch(cv::Exception e)
{
- LOGD("nativeestroyObject catched cv::Exception: %s", e.what());
- jclass je = jenv->FindClass("org/opencv/core/CvException");
- if(!je)
- je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, e.what());
+ LOGD("nativeestroyObject catched cv::Exception: %s", e.what());
+ jclass je = jenv->FindClass("org/opencv/core/CvException");
+ if(!je)
+ je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, e.what());
}
catch (...)
{
- LOGD("nativeDestroyObject catched unknown exception");
- jclass je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
+ LOGD("nativeDestroyObject catched unknown exception");
+ jclass je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
}
}
{
try
{
- ((DetectionBasedTracker*)thiz)->run();
+ ((DetectionBasedTracker*)thiz)->run();
}
catch(cv::Exception e)
{
- LOGD("nativeStart catched cv::Exception: %s", e.what());
- jclass je = jenv->FindClass("org/opencv/core/CvException");
- if(!je)
- je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, e.what());
+ LOGD("nativeStart catched cv::Exception: %s", e.what());
+ jclass je = jenv->FindClass("org/opencv/core/CvException");
+ if(!je)
+ je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, e.what());
}
catch (...)
{
- LOGD("nativeStart catched unknown exception");
- jclass je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
+ LOGD("nativeStart catched unknown exception");
+ jclass je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
}
}
{
try
{
- ((DetectionBasedTracker*)thiz)->stop();
+ ((DetectionBasedTracker*)thiz)->stop();
}
catch(cv::Exception e)
{
- LOGD("nativeStop catched cv::Exception: %s", e.what());
- jclass je = jenv->FindClass("org/opencv/core/CvException");
- if(!je)
- je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, e.what());
+ LOGD("nativeStop catched cv::Exception: %s", e.what());
+ jclass je = jenv->FindClass("org/opencv/core/CvException");
+ if(!je)
+ je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, e.what());
}
catch (...)
{
- LOGD("nativeStop catched unknown exception");
- jclass je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
+ LOGD("nativeStop catched unknown exception");
+ jclass je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
}
}
{
try
{
- if (faceSize > 0)
- {
- DetectionBasedTracker::Parameters DetectorParams = \
- ((DetectionBasedTracker*)thiz)->getParameters();
- DetectorParams.minObjectSize = faceSize;
- ((DetectionBasedTracker*)thiz)->setParameters(DetectorParams);
- }
-
+ if (faceSize > 0)
+ {
+ // TODO: Reimplement using adapter
+// DetectionBasedTracker::Parameters DetectorParams = ((DetectionBasedTracker*)thiz)->getParameters();
+// DetectorParams.minObjectSize = faceSize;
+// ((DetectionBasedTracker*)thiz)->setParameters(DetectorParams);
+ }
}
catch(cv::Exception e)
{
- LOGD("nativeStop catched cv::Exception: %s", e.what());
- jclass je = jenv->FindClass("org/opencv/core/CvException");
- if(!je)
- je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, e.what());
+ LOGD("nativeStop catched cv::Exception: %s", e.what());
+ jclass je = jenv->FindClass("org/opencv/core/CvException");
+ if(!je)
+ je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, e.what());
}
catch (...)
{
- LOGD("nativeSetFaceSize catched unknown exception");
- jclass je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
+ LOGD("nativeSetFaceSize catched unknown exception");
+ jclass je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
}
}
{
try
{
- vector<Rect> RectFaces;
- ((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray));
- ((DetectionBasedTracker*)thiz)->getObjects(RectFaces);
- vector_Rect_to_Mat(RectFaces, *((Mat*)faces));
+ vector<Rect> RectFaces;
+ ((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray));
+ ((DetectionBasedTracker*)thiz)->getObjects(RectFaces);
+ *((Mat*)faces) = Mat(RectFaces, true);
}
catch(cv::Exception e)
{
- LOGD("nativeCreateObject catched cv::Exception: %s", e.what());
- jclass je = jenv->FindClass("org/opencv/core/CvException");
- if(!je)
- je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, e.what());
+ LOGD("nativeCreateObject catched cv::Exception: %s", e.what());
+ jclass je = jenv->FindClass("org/opencv/core/CvException");
+ if(!je)
+ je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, e.what());
}
catch (...)
{
- LOGD("nativeDetect catched unknown exception");
- jclass je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
+ LOGD("nativeDetect catched unknown exception");
+ jclass je = jenv->FindClass("java/lang/Exception");
+ jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}");
}
-}
\ No newline at end of file
+}
--- /dev/null
+#if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(ANDROID)
+
+#include <opencv2/imgproc/imgproc.hpp> // Gaussian Blur
+#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
+#include <opencv2/highgui/highgui.hpp> // OpenCV window I/O
+#include <opencv2/features2d/features2d.hpp>
+#include <opencv2/contrib/detection_based_tracker.hpp>
+
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+using namespace std;
+using namespace cv;
+
+const string WindowName = "Face Detection example";
+
+class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
+{
+ public:
+ CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
+ IDetector(),
+ Detector(detector)
+ {
+ CV_Assert(!detector.empty());
+ }
+
+ void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects)
+ {
+ Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize);
+ }
+
+ virtual ~CascadeDetectorAdapter()
+ {}
+
+ private:
+ CascadeDetectorAdapter();
+ cv::Ptr<cv::CascadeClassifier> Detector;
+ };
+
+int main(int argc, char* argv[])
+{
+ namedWindow(WindowName);
+
+ VideoCapture VideoStream(0);
+
+ if (!VideoStream.isOpened())
+ {
+ printf("Error: Cannot open video stream from camera\n");
+ return 1;
+ }
+
+ std::string cascadeFrontalfilename = "../../data/lbpcascades/lbpcascade_frontalface.xml";
+ cv::Ptr<cv::CascadeClassifier> cascade = new cv::CascadeClassifier(cascadeFrontalfilename);
+ cv::Ptr<DetectionBasedTracker::IDetector> MainDetector = new CascadeDetectorAdapter(cascade);
+
+ cascade = new cv::CascadeClassifier(cascadeFrontalfilename);
+ cv::Ptr<DetectionBasedTracker::IDetector> TrackingDetector = new CascadeDetectorAdapter(cascade);
+
+ DetectionBasedTracker::Parameters params;
+ DetectionBasedTracker Detector(MainDetector, TrackingDetector, params);
+
+ if (!Detector.run())
+ {
+ printf("Error: Detector initialization failed\n");
+ return 2;
+ }
+
+ Mat ReferenceFrame;
+ Mat GrayFrame;
+ vector<Rect> Faces;
+
+ while(true)
+ {
+ VideoStream >> ReferenceFrame;
+ cvtColor(ReferenceFrame, GrayFrame, COLOR_RGB2GRAY);
+ Detector.process(GrayFrame);
+ Detector.getObjects(Faces);
+
+ for (size_t i = 0; i < Faces.size(); i++)
+ {
+ rectangle(ReferenceFrame, Faces[i], CV_RGB(0,255,0));
+ }
+
+ imshow(WindowName, ReferenceFrame);
+
+ if (cvWaitKey(30) >= 0) break;
+ }
+
+ Detector.stop();
+
+ return 0;
+}
+
+#else
+
+#include <stdio.h>
+int main()
+{
+ printf("This sample works for UNIX or ANDROID only\n");
+ return 0;
+}
+
+#endif
#define LOGE(...) do{} while(0)
#endif
-
-
using namespace cv;
using namespace std;
LOGE0("\t (e.g.\"opencv/data/lbpcascades/lbpcascade_frontalface.xml\" ");
}
+class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
+{
+ public:
+ CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
+ Detector(detector)
+ {
+ CV_Assert(!detector.empty());
+ }
+
+ void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects)
+ {
+ Detector->detectMultiScale(Image, objects, 1.1, 3, 0, minObjSize, maxObjSize);
+ }
+ virtual ~CascadeDetectorAdapter()
+ {}
+
+ private:
+ CascadeDetectorAdapter();
+ cv::Ptr<cv::CascadeClassifier> Detector;
+ };
+
static int test_FaceDetector(int argc, char *argv[])
{
- if (argc < 4) {
+ if (argc < 4)
+ {
usage();
return -1;
}
vector<Mat> images;
{
char filename[256];
- for(int n=1; ; n++) {
+ for(int n=1; ; n++)
+ {
snprintf(filename, sizeof(filename), filepattern, n);
LOGD("filename='%s'", filename);
Mat m0;
m0=imread(filename);
- if (m0.empty()) {
+ if (m0.empty())
+ {
LOGI0("Cannot read the file --- break");
break;
}
LOGD("read %d images", (int)images.size());
}
- DetectionBasedTracker::Parameters params;
std::string cascadeFrontalfilename=cascadefile;
+ cv::Ptr<cv::CascadeClassifier> cascade = new cv::CascadeClassifier(cascadeFrontalfilename);
+ cv::Ptr<DetectionBasedTracker::IDetector> MainDetector = new CascadeDetectorAdapter(cascade);
+
+ cascade = new cv::CascadeClassifier(cascadeFrontalfilename);
+ cv::Ptr<DetectionBasedTracker::IDetector> TrackingDetector = new CascadeDetectorAdapter(cascade);
- DetectionBasedTracker fd(cascadeFrontalfilename, params);
+ DetectionBasedTracker::Parameters params;
+ DetectionBasedTracker fd(MainDetector, TrackingDetector, params);
fd.run();
double freq=getTickFrequency();
int num_images=images.size();
- for(int n=1; n <= num_images; n++) {
+ for(int n=1; n <= num_images; n++)
+ {
int64 tcur=getTickCount();
int64 dt=tcur-tprev;
tprev=tcur;
double t_ms=((double)dt)/freq * 1000.0;
- LOGD("\n\nSTEP n=%d from prev step %f ms\n\n", n, t_ms);
+ LOGD("\n\nSTEP n=%d from prev step %f ms\n", n, t_ms);
m=images[n-1];
CV_Assert(! m.empty());
cvtColor(m, gray, CV_BGR2GRAY);
vector<Rect> result;
fd.getObjects(result);
-
-
-
-
- for(size_t i=0; i < result.size(); i++) {
+ for(size_t i=0; i < result.size(); i++)
+ {
Rect r=result[i];
CV_Assert(r.area() > 0);
Point tl=r.tl();
rectangle(m, tl, br, color, 3);
}
}
+
+ char outfilename[256];
+ for(int n=1; n <= num_images; n++)
{
- char outfilename[256];
- for(int n=1; n <= num_images; n++) {
- snprintf(outfilename, sizeof(outfilename), outfilepattern, n);
- LOGD("outfilename='%s'", outfilename);
- m=images[n-1];
- imwrite(outfilename, m);
- }
+ snprintf(outfilename, sizeof(outfilename), outfilepattern, n);
+ LOGD("outfilename='%s'", outfilename);
+ m=images[n-1];
+ imwrite(outfilename, m);
}
fd.stop();
return 0;
}
-
-
int main(int argc, char *argv[])
{
return test_FaceDetector(argc, argv);