(4)opencv在android平台上实现 物体跟踪
最近项目时间很紧,抓紧时间集中精力去研究android平台的opencv里的物体跟踪技术
其他几篇文章有时间再去完善吧
从网上找到了一些实例代码,我想采取的学习方法是研究实例代码和看教程相结合,教程是ndk编程方面的编程规则等、opencv人脸识别、物体跟踪这一块的教程
(1)人脸检测与跟踪库 asmlibrary 分析和研究
http://www.oschina.net/p/asmlibrary
http://yaohan.sinaapp.com/topic/3/asmlibrary#comments
我下载了6.0这个版本,往eclipse里导入的时候要注意一些问题,记得导入Opencv-Library,在C++的paths and symbols的include里把需要的库加进去,然后还可能遇到其他问
题,读者自行百度或者留言给我吧,一起讨论研究一下!
把这个项目导入eclipse之后,观察它的结构:
src文件夹下有两个java文件: ASMFit.java, ASMLibraryActivity.java
jni文件夹下有 so文件夹,Android.mk,Application.mk,asmfitting.h,asmlibrary.h,DemoFit.cpp,vjfacedetect.h
在res文件夹下发现了一个文件夹 raw,第一次见,然后百度了一下,
assets和res下面raw文件的使用不同点
assets下面的文件不会被编译,通过路径可以去访问其中的内容。raw中文件会自动编译,我们可以在R.java文件中找到对应的ID
, , );
C++部分(jni)
(1)Android.mk
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE := asmlibrary
- LOCAL_SRC_FILES := so/$(TARGET_ARCH_ABI)/libasmlibrary.so
- include $(PREBUILT_SHARED_LIBRARY)
- include $(CLEAR_VARS)
- #OPENCV_CAMERA_MODULES:=off
- #OPENCV_INSTALL_MODULES:=off
- #OPENCV_LIB_TYPE:=SHARED
- include E:\android-eclipse\OpenCV-2.4.8-android-sdk/sdk/native/jni/OpenCV.mk
- LOCAL_SRC_FILES := DemoFit.cpp
- LOCAL_C_INCLUDES += $(LOCAL_PATH)
- LOCAL_CFLAGS += -DOPENCV_OLDER_VISION
- LOCAL_LDLIBS += -llog -ldl
- LOCAL_MODULE := jni-asmlibrary
- LOCAL_SHARED_LIBRARIES := asmlibrary
- include $(BUILD_SHARED_LIBRARY)
(2)Application.mk
- APP_STL := gnustl_static
- APP_CPPFLAGS := -frtti -fexceptions
- APP_ABI := armeabi-v7a armeabi x86 mips
- APP_PLATFORM := android-8
(3)asmfitting.h
- #ifndef _ASM_FITTING_H_
- #define _ASM_FITTING_H_
- #include "asmlibrary.h"
- /** Wrapped Class for face alignment/tracking using active shape model */
- class ASMLIB asmfitting
- {
- public:
- /** Constructor */
- asmfitting();
- /** Destructor */
- ~asmfitting();
- /**
- Process face alignment on image. (Only for one face box)
- @param shape the point features that carries initial shape and also restores result after fitting
- @param image the image resource
- @param n_iteration the number of iteration during fitting
- */
- void Fitting(asm_shape& shape, const IplImage* image, int n_iteration = 30);
- /**
- Process face alignment on image. (For multi-face boxes)
- @param shapes all shape datas that carry the fitting result
- @param n_shapes the number of human face
- @param image the image resource
- @param n_iteration the number of iteration during fitting
- */
- void Fitting2(asm_shape* shapes, int n_shapes, const IplImage* image, int n_iteration = 30);
- /**
- Process face tracking on video/camera.
- @param shape the point features that carries initial shape and also restores result after fitting
- @param image the image resource
- @param frame_no one certain frame number of video/camera
- @param bopticalflow whether to use optical flow or not?
- @param n_iteration the number of iteration during fitting
- @return false on failure, true otherwise.
- */
- bool ASMSeqSearch(asm_shape& shape, const IplImage* image,
- int frame_no = 0, bool bopticalflow = false, int n_iteration = 30);
- /**<
- Get the Average Viola-Jone Box.
- */
- const asm_shape GetMappingDetShape()const { return m__VJdetavshape;}
- /**<
- Get the width of mean face.
- */
- const double GetMeanFaceWidth()const{ return m_model.GetMeanShape().GetWidth(); }
- /**<
- Get raw ptr of asm_model.
- */
- const asm_model* GetModel()const { return &m_model; }
- /**
- Read model data from file.
- @param filename the filename that stores the model
- @return false on failure, true otherwise
- */
- bool Read(const char* filename);
- private:
- /**
- Apply optical flow between two successive frames.
- @param shape it carries initial shape and also restores result after fitting
- @param grayimage the image resource.
- */
- void OpticalFlowAlign(asm_shape& shape, const IplImage* grayimage);
- private:
- asm_model m_model; /**<active shape model to be trained */
- int *m_edge_start; /**< Starting index of edges */
- int *m_edge_end; /**< Ending index of edges */
- int m_nEdge; /**< Number of edges */
- asm_shape m__VJdetavshape; /**< average mapping shape relative to VJ detect box*/
- scale_param m_param; /**< point index of left and right side in the face template*/
- bool m_flag; /**< Does the image contain face? */
- double m_dReferenceFaceWidth; /**< reference face width */
- private:
- IplImage* __lastframe; /**< Cached variables for optical flow */
- IplImage* __pyrimg1; /**< Cached variables for optical flow */
- IplImage* __pyrimg2; /**< Cached variables for optical flow */
- Point2D32f* __features1; /**< Cached variables for optical flow */
- Point2D32f* __features2; /**< Cached variables for optical flow */
- char* __found_feature; /**< Cached variables for optical flow */
- float* __feature_error; /**< Cached variables for optical flow */
- };
- #endif //_ASM_FITTING_H_
(4)asmlibrary.h
- #ifndef _ASM_LIBRARY_H_
- #define _ASM_LIBRARY_H_
- #include <stdio.h>
- class asm_shape;
- class asm_profile;
- class asm_model;
- struct profile_Nd_model;
- struct profile_lbp_model;
- struct CvMat;
- struct _IplImage;
- typedef unsigned char uchar;
- typedef struct _IplImage IplImage;
- #ifdef WIN32
- #ifdef ASMLIBRARY_EXPORTS
- #define ASMLIB __declspec(dllexport)
- #else
- #define ASMLIB __declspec(dllimport)
- #endif
- #else
- #define ASMLIB
- #endif
- /**
- * Predefined local texture (profile) types.
- * <ul>
- * <li>PROFILE_1D: use only the pixels along the normal vector in the contour.</li>
- * <li>PROFILE_2D: use the pixels located at the recentage.</li>
- * <li>PROFILE_LBP: use the pixels processed with LBP-operator.</li>
- * </ul>
- **/
- enum ASM_PROFILE_TYPE {PROFILE_1D, PROFILE_2D, PROFILE_LBP};
- #ifdef __cplusplus
- extern "C"{
- #endif
- /**
- Initialize shape from the detected box.
- @param shape the returned initial shape
- @param det_shape the detected box calling by \a asm_vjfacedetect::\a Detect()
- @param ref_shape the average mean shape
- @param refwidth the width of average mean shape
- */
- ASMLIB void InitShapeFromDetBox(asm_shape &shape, const asm_shape& det_shape,
- const asm_shape &ref_shape, double refwidth);
- #ifdef __cplusplus
- }
- #endif
- /** Class for 2d point. */
- typedef struct Point2D32f
- {
- float x;
- float y;
- }
- Point2D32f;
- /** Class for 2d shape data. */
- class ASMLIB asm_shape
- {
- public:
- /** Constructor */
- asm_shape();
- /** Copy Constructor */
- asm_shape(const asm_shape &v);
- /** Destructor */
- ~asm_shape();
- /**
- Access elements by \a CvPoint2D32f \a pt = \a shape[\a i] to get \a i-th point in the shape.
- @param i Index of points
- @return Point at the certain index
- */
- const Point2D32f operator [](int i)const{ return m_vPoints[i]; }
- /**
- Access elements by \a CvPoint2D32f \a pt = \a shape[\a i] to get \a i-th point in the shape.
- @param i Index of points
- @return Point at the certain index
- */
- Point2D32f& operator [](int i){ return m_vPoints[i]; }
- /**
- Get the number of points.
- @return Number of points
- */
- inline const int NPoints()const{ return m_nPoints; }
- /**
- Override of operator =
- */
- asm_shape& operator =(const asm_shape &s);
- /**
- Override of operator =.
- */
- asm_shape& operator =(double value);
- /**
- Override of operator +
- */
- const asm_shape operator +(const asm_shape &s)const;
- /**
- Override of operator +=
- */
- asm_shape& operator +=(const asm_shape &s);
- /**
- Override of operator -
- */
- const asm_shape operator -(const asm_shape &s)const;
- /**
- Override of operator -=
- */
- asm_shape& operator -=(const asm_shape &s);
- /**
- Override of operator *
- */
- const asm_shape operator *(double value)const;
- /**
- Override of operator *=
- */
- asm_shape& operator *=(double value);
- /**
- Override of operator *
- */
- double operator *(const asm_shape &s)const;
- /**
- Override of operator /
- */
- const asm_shape operator /(double value)const;
- /**
- Override of operator /=
- */
- asm_shape& operator /=(double value);
- /**
- Release memory.
- */
- void Clear();
- /**
- Allocate memory.
- @param length Number of of shape points
- */
- void Resize(int length);
- /**
- Read points from file.
- @param filename the filename the stored shape data
- @return true on pts format, false on asf format, exit otherwise
- */
- bool ReadAnnotations(const char* filename);
- /**
- Read points from asf format file.
- @param filename the filename the stored shape data
- */
- void ReadFromASF(const char*filename);
- /**
- Read points from pts format file.
- @param filename the filename the stored shape data
- */
- void ReadFromPTS(const char*filename);
- /**
- Write shape data into file stream.
- @param f stream to write to
- */
- void Write(FILE* f);
- /**
- Read shape data from file stream.
- @param f stream to read from
- */
- void Read(FILE* f);
- /**
- Calculate minimum \f$x\f$-direction value of shape.
- */
- const double MinX()const;
- /**
- Calculate minimum \f$y\f$-direction value of shape.
- */
- const double MinY()const;
- /**
- Calculate maximum \f$x\f$-direction value of shape.
- */
- const double MaxX()const;
- /**
- Calculate maximum \f$y\f$-direction value of shape.
- */
- const double MaxY()const;
- /**
- Calculate the left and right index for \f$x\f$-direction in the shape.
- @param ileft the index of points in \f$x\f$-direction which has the minimum x
- @param iright the index of points in \f$x\f$-direction which has the maximum x
- */
- void GetLeftRight(int& ileft, int& iright)const;
- /**
- Calculate width of shape.
- @param ileft Index of points in \f$x\f$-direction which has the minimum x
- @param iright Index of points in \f$x\f$-direction which has the maximum x
- */
- const double GetWidth(int ileft = -1, int iright = -1)const;
- /**
- Calculate height of shape.
- */
- const double GetHeight()const { return MaxY()-MinY(); }
- /**
- Calculate center of gravity for shape.
- @param x Value of center in \f$x\f$-direction
- @param y Value of center in \f$y\f$-direction
- */
- void COG(double &x, double &y)const;
- /**
- Translate the shape to make its center locate at (0, 0).
- */
- void Centralize();
- /**
- Translate the shape.
- @param x Value of translation factor in \f$x\f$-direction
- @param y Value of translation factor in \f$y\f$-direction
- */
- void Translate(double x, double y);
- /**
- Scale shape by an uniform factor.
- @param s Scaling factor
- */
- void Scale(double s);
- /**
- Rotate shape by anti clock-wise.
- @param theta Angle to be rotated
- */
- void Rotate(double theta);
- /**
- Scale shape in x and y direction respectively.
- @param sx Scaling factor in \f$x\f$-direction
- @param sy Scaling factor in \f$y\f$-direction
- */
- void ScaleXY(double sx, double sy);
- /**
- Normalize shape (zero_mean_unit_length) so that its center locates at (0, 0) and its \f$L2\f$-norm is 1.
- @return the \f$L2\f$-norm of original shape
- */
- double Normalize();
- enum{ LU, SVD, Direct };
- /**
- Calculate the similarity transform between one shape and another reference shape.
- Where the similarity transform is:
- <BR>
- \f$T(a,b,tx,ty) = [a \ -b \ Tx; b \ a \ Ty ; 0 \ 0 \ 1]\f$.
- @param ref_shape the reference shape
- @param a will return \f$ s \times cos(theta) \f$ in form of similarity transform
- @param b will return \f$ s \times sin(theta) \f$ in form of similarity transform
- @param tx will return \f$ Tx \f$ in form of similarity transform
- @param ty will return \f$ Ty \f$ in form of similarity transform
- @param method Method of similarity transform
- */
- void AlignTransformation(const asm_shape &ref_shape, double &a, double &b,
- double &tx, double &ty, int method = SVD)const;
- /**
- Align the shape to the reference shape.
- @param ref_shape the reference shape
- @param method method of similarity transform
- */
- void AlignTo(const asm_shape &ref_shape, int method = SVD);
- /**
- Transform Shape using the similarity transform \f$T(a,b,tx,ty)\f$.
- */
- void TransformPose(double a, double b, double tx, double ty);
- /**
- Calculate the angular bisector between two lines \f$Pi-Pj\f$ and \f$Pj-Pk\f$.
- @param i the index of point vertex
- @param j the index of point vertex
- @param k the index of point vertex
- @return Angular bisector vector in form of \f$(cos(x), sin(x))^T\f$
- */
- Point2D32f CalcBisector(int i, int j, int k)const;
- /**
- Calculate the Euclidean norm (\f$L2\f$-norm).
- @return Euclidean norm
- */
- double GetNorm2()const;
- /**
- Calculate the normal vector at certain vertex around the shape contour.
- @param cos_alpha the normal vector in \f$x\f$-direction
- @param sin_alpha the normal vector in \f$y\f$-direction
- @param i the index of point vertex
- */
- void CalcNormalVector(double &cos_alpha, double &sin_alpha, int i)const;
- /**
- Convert from OpenCV's \a CvMat to class asm_shape
- @param mat \a CvMat that converted from
- */
- void CopyFrom(const CvMat* mat);
- /**
- Convert from class asm_shape to OpenCV's CvMat.
- @param mat CvMat that converted to
- */
- void CopyTo(CvMat* mat)const;
- private:
- void Transform(double c00, double c01, double c10, double c11);
- private:
- Point2D32f* m_vPoints; /**< point data */
- int m_nPoints; /**< number of points */
- };
- /** Left and Right index in \f$x\f$-direction of shape */
- typedef struct scale_param
- {
- int left; /**< Index of points in \f$x\f$-direction which has the minimum x */
- int right; /**< Index of points in \f$x\f$-direction which has the maximum x */
- }scale_param;
- /** Class for active shape model. */
- class ASMLIB asm_model
- {
- public:
- /**
- Constructor
- */
- asm_model();
- /**
- Destructor
- */
- ~asm_model();
- /**
- Image alignment/fitting with an initial shape.
- @param shape the point features that carries initial shape and also restores result after fitting
- @param grayimage the gray image resource
- @param max_iter the number of iteration
- @param param the left and right index for \f$x\f$-direction in the shape (Always set \a NULL )
- @return false on failure, true otherwise
- */
- bool Fit(asm_shape& shape, const IplImage *grayimage,
- int max_iter = 30, const scale_param* param = NULL);
- /**
- Write model data to file stream.
- @param f stream to write to
- */
- void WriteModel(FILE* f);
- /**
- Read model data from file stream.
- @param f stream to read from
- */
- void ReadModel(FILE* f);
- /**
- Get mean shape of model.
- */
- const asm_shape& GetMeanShape()const { return m_asm_meanshape; }
- /**
- Get modes of shape distribution model (Will be calculated in shape's PCA)
- */
- const int GetModesOfModel()const { return m_nModes;}
- /**
- Get the width of mean shape [Identical to \a m_asm_meanshape.\a GetWidth()].
- */
- const double GetReferenceWidthOfFace()const { return m_dReferenceFaceWidth; }
- private:
- /**
- Get the optimal offset at one certain point vertex during the process of
- best profile matching (work for 1d/2d profile model).
- @param image the image resource
- @param ilev one certain pyramid level
- @param shape the shape data
- @param ipoint the index of point vertex
- @param cos_alpha the normal vector in \f$x\f$-direction
- @param sin_alpha the normal vector in \f$y\f$-direction
- @return offset bias from \a Shape[\a iPoint]
- */
- int FindBestOffsetForNd(const IplImage* image, int ilev,
- const asm_shape& shape, int ipoint,
- double& cos_alpha, double& sin_alpha);
- /**
- Get the optimal offset at one certain point vertex during the process of
- best profile matching (work for lbp profile model).
- @param lbp_img the target image processed with LBP
- @param nrows the height of \a lbp_img
- @param ncols the width of \a lbp_img
- @param ilev one certain pyramid level
- @param shape the shape data
- @param ipoint the index of point vertex
- @param xoffset the returned offset in \f$x\f$-direction away from \a Shape[\a iPoint]
- @param yoffset the returned offset in \f$y\f$-direction away from \a Shape[\a iPoint]
- */
- void FindBestOffsetForLBP(const int* lbp_img, int nrows, int ncols, int ilev,
- const asm_shape& shape, int ipoint, int& xoffset, int& yoffset);
- /**
- Update shape by matching the image profile to the model profile.
- @param update_shape the updated shape
- @param shape the point feature that will be matched
- @param ilev one certain pyramid level
- @param image the image resource
- @param lbp_img the LBP-operator image
- @param norm the \f$L2\f$-norm of the difference between \a shape and \a update_shape
- @return how many point vertex will be updated?
- */
- int MatchToModel(asm_shape& update_shape, const asm_shape& shape,
- int ilev, const IplImage* image, const int *lbp_img, double* norm = NULL);
- /**
- Calculate shape parameters (\a a, \a b, \a Tx, \a Ty) and pose parameters \a p.
- @param p Shape parameters
- @param a \f$ s \times cos(theta) \f$ in form of similarity transform
- @param b \f$ s \times sin(theta) \f$ in form of similarity transform
- @param tx \f$ Tx \f$ in form of similarity transform
- @param ty \f$ Ty \f$ in form of similarity transform
- @param shape the point features data
- @param iter_no Number of iteration
- */
- void CalcParams(CvMat* p, double& a, double& b, double& tx, double& ty,
- const asm_shape& shape, int iter_no = 2);
- /**
- Constrain the shape parameters.
- @param p Shape parameters
- */
- void Clamp(CvMat* p);
- /**
- Generate shape instance according to shape parameters p and pose parameters.
- @param shape the point feature data
- @param p the shape parameters
- @param a Return \f$ s \times cos(theta) \f$ in form of similarity transform
- @param b Return \f$ s \times sin(theta) \f$ in form of similarity transform
- @param tx Return \f$ Tx \f$ in form of similarity transform
- @param ty Return \f$ Ty \f$ in form of similarity transform
- */
- void CalcGlobalShape(asm_shape& shape, const CvMat* p,
- double a, double b, double tx, double ty);
- /**
- Pyramid fitting at one certain level.
- @param shape the point feature data
- @param image the image resource
- @param ilev one certain pyramid level
- @param iter_no the number of iteration
- */
- void PyramidFit(asm_shape& shape, const IplImage* image, int ilev, int iter_no);
- private:
- CvMat* m_M; /**< mean vector of shape data */
- CvMat* m_B; /**< eigenvetors of shape data */
- CvMat* m_V; /**< eigenvalues of shape data */
- CvMat* m_SM; /**< mean of shapes projected space */
- CvMat* m_SSD; /**< standard deviation of shapes projected space */
- ASM_PROFILE_TYPE m_type; /**< the type of sampling profile */
- /**< the profile distribution model */
- union
- {
- struct profile_lbp_model* lbp_tdm; /**< lbp profile model */
- struct profile_Nd_model* classical_tdm; /**< 1d/2d profile model */
- };
- asm_shape m_asm_meanshape; /**< mean shape of aligned shapes */
- int m_nPoints; /**< number of shape points */
- int m_nWidth; /**< width of each landmark's profile */
- int m_nLevels; /**< pyramid level of multi-resolution */
- int m_nModes; /**< number of truncated eigenvalues */
- double m_dReferenceFaceWidth; /**< width of reference face */
- bool m_bInterpolate; /**< whether to using image interpolate or not*/
- double m_dMeanCost; /**< the mean of fitting cost to determine whether fitting succeed or not*/
- double m_dVarCost; /**< the variance of fitting cost determine whether fitting succeed or not*/
- private:
- CvMat* m_CBackproject; /**< Cached variables for speed up */
- CvMat* m_CBs; /**< Cached variables for speed up */
- double* m_dist; /**< Cached variables for speed up */
- asm_profile* m_profile; /**< Cached variables for speed up */
- asm_shape m_search_shape; /**< Cached variables for speed up */
- asm_shape m_temp_shape; /**< Cached variables for speed up */
- };
- /** You can define your own face detector function here
- @param shapes Returned face detected box which stores the Top-Left and Bottom-Right points, so its \a NPoints() = 2 here.
- @param image Image resource.
- @return false on no face exists in image, true otherwise.
- */
- typedef bool (*detect_func)(asm_shape& shape, const IplImage* image);
- #endif // _ASM_LIBRARY_H_
(5)DemoFit.cpp
- #include <opencv2/core/core.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/contrib/detection_based_tracker.hpp>
- #include "asmfitting.h"
- #include "vjfacedetect.h"
- #include <string>
- #include <vector>
- #include <android/log.h>
- #include <jni.h>
- using namespace std;
- using namespace cv;
- #define LOG_TAG "ASMLIBRARY"
- #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
- #define BEGINT() double t = (double)cvGetTickCount();
- #define ENDT(exp) t = ((double)cvGetTickCount() - t )/ (cvGetTickFrequency()*1000.); \
- LOGD(exp " time cost: %.2f millisec\n", t);
- asmfitting fit_asm;
- DetectionBasedTracker *track = NULL;
- #ifdef __cplusplus
- extern "C" {
- #endif
- JNIEXPORT jboolean JNICALL Java_org_asmlibrary_fit_ASMFit_nativeReadModel
- (JNIEnv * jenv, jclass, jstring jFileName)
- {
- LOGD("nativeReadModel enter");
- const char* filename = jenv->GetStringUTFChars(jFileName, NULL);
- jboolean result = false;
- try
- {
- if(fit_asm.Read(filename) == true)
- result = true;
- }
- catch (...)
- {
- LOGD("nativeReadModel caught unknown exception");
- jclass je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, "Unknown exception in JNI code");
- }
- LOGD("nativeReadModel %s exit %d", filename, result);
- return result;
- }
- JNIEXPORT jboolean JNICALL Java_org_asmlibrary_fit_ASMFit_nativeInitCascadeDetector
- (JNIEnv * jenv, jclass, jstring jFileName)
- {
- const char* cascade_name = jenv->GetStringUTFChars(jFileName, NULL);
- LOGD("nativeInitCascadeDetector %s enter", cascade_name);
- if(init_detect_cascade(cascade_name) == false)
- return false;
- LOGD("nativeInitCascadeDetector exit");
- return true;
- }
- JNIEXPORT jboolean JNICALL Java_org_asmlibrary_fit_ASMFit_nativeInitFastCascadeDetector
- (JNIEnv * jenv, jclass, jstring jFileName)
- {
- const char* cascade_name = jenv->GetStringUTFChars(jFileName, NULL);
- LOGD("nativeInitFastCascadeDetector %s enter", cascade_name);
- DetectionBasedTracker::Parameters DetectorParams;
- DetectorParams.minObjectSize = 45;
- track = new DetectionBasedTracker(cascade_name, DetectorParams);
- if(track == NULL) return false;
- DetectorParams = track->getParameters();
- DetectorParams.minObjectSize = 64;
- track->setParameters(DetectorParams);
- track->run();
- LOGD("nativeInitFastCascadeDetector exit");
- return true;
- }
- JNIEXPORT void JNICALL Java_org_asmlibrary_fit_ASMFit_nativeDestroyCascadeDetector
- (JNIEnv * jenv, jclass)
- {
- LOGD("nativeDestroyCascadeDetector enter");
- destory_detect_cascade();
- LOGD("nativeDestroyCascadeDetector exit");
- }
- JNIEXPORT void JNICALL Java_org_asmlibrary_fit_ASMFit_nativeDestroyFastCascadeDetector
- (JNIEnv * jenv, jclass)
- {
- LOGD("nativeDestroyFastCascadeDetector enter");
- if(track){
- track->stop();
- delete track;
- }
- LOGD("nativeDestroyFastCascadeDetector exit");
- }
- inline void shape_to_Mat(asm_shape shapes[], int nShape, Mat& mat)
- {
- mat = Mat(nShape, shapes[0].NPoints()*2, CV_64FC1);
- for(int i = 0; i < nShape; i++)
- {
- double *pt = mat.ptr<double>(i);
- for(int j = 0; j < mat.cols/2; j++)
- {
- pt[2*j] = shapes[i][j].x;
- pt[2*j+1] = shapes[i][j].y;
- }
- }
- }
- inline void Mat_to_shape(asm_shape shapes[], int nShape, Mat& mat)
- {
- for(int i = 0; i < nShape; i++)
- {
- double *pt = mat.ptr<double>(i);
- shapes[i].Resize(mat.cols/2);
- for(int j = 0; j < mat.cols/2; j++)
- {
- shapes[i][j].x = pt[2*j];
- shapes[i][j].y = pt[2*j+1];
- }
- }
- }
- JNIEXPORT jboolean JNICALL Java_org_asmlibrary_fit_ASMFit_nativeFastDetectAll
- (JNIEnv * jenv, jclass, jlong imageGray, jlong faces)
- {
- if(!track) return false;
- BEGINT();
- vector<Rect> RectFaces;
- try{
- Mat image = *(Mat*)imageGray;
- LOGD("image: (%d, %d)", image.cols, image.rows);
- track->process(image);
- track->getObjects(RectFaces);
- }
- catch(cv::Exception& e)
- {
- LOGD("nativeFastDetectAll caught 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("nativeFastDetectAll caught unknown exception");
- jclass je = jenv->FindClass("java/lang/Exception");
- jenv->ThrowNew(je, "Unknown exception in JNI code");
- }
- int nFaces = RectFaces.size();
- if(nFaces <= 0){
- ENDT("FastCascadeDetector CANNOT detect any face");
- return false;
- }
- LOGD("FastCascadeDetector found %d faces", nFaces);
- asm_shape* detshapes = new asm_shape[nFaces];
- for(int i = 0; i < nFaces; i++){
- Rect r = RectFaces[i];
- detshapes[i].Resize(2);
- detshapes[i][0].x = r.x;
- detshapes[i][0].y = r.y;
- detshapes[i][1].x = r.x+r.width;
- detshapes[i][1].y = r.y+r.height;
- }
- asm_shape* shapes = new asm_shape[nFaces];
- for(int i = 0; i < nFaces; i++)
- {
- InitShapeFromDetBox(shapes[i], detshapes[i], fit_asm.GetMappingDetShape(), fit_asm.GetMeanFaceWidth());
- }
- shape_to_Mat(shapes, nFaces, *((Mat*)faces));
- delete []detshapes;
- delete []shapes;
- ENDT("FastCascadeDetector detect");
- return true;
- }
- JNIEXPORT jboolean JNICALL Java_org_asmlibrary_fit_ASMFit_nativeDetectAll
- (JNIEnv * jenv, jclass, jlong imageGray, jlong faces)
- {
- IplImage image = *(Mat*)imageGray;
- int nFaces;
- asm_shape *detshapes = NULL;
- LOGD("image: (%d, %d)", image.width, image.height);
- BEGINT();
- bool flag =detect_all_faces(&detshapes, nFaces, &image);
- if(flag == false) {
- ENDT("CascadeDetector CANNOT detect any face");
- return false;
- }
- LOGD("CascadeDetector found %d faces", nFaces);
- asm_shape* shapes = new asm_shape[nFaces];
- for(int i = 0; i < nFaces; i++)
- {
- InitShapeFromDetBox(shapes[i], detshapes[i], fit_asm.GetMappingDetShape(), fit_asm.GetMeanFaceWidth());
- }
- shape_to_Mat(shapes, nFaces, *((Mat*)faces));
- free_shape_memeory(&detshapes);
- delete []shapes;
- ENDT("CascadeDetector detect");
- return true;
- }
- JNIEXPORT void JNICALL Java_org_asmlibrary_fit_ASMFit_nativeInitShape(JNIEnv * jenv, jclass, jlong faces)
- {
- Mat faces1 = *((Mat*)faces);
- int nFaces = faces1.rows;
- asm_shape* detshapes = new asm_shape[nFaces];
- asm_shape* shapes = new asm_shape[nFaces];
- Mat_to_shape(detshapes, nFaces, faces1);
- for(int i = 0; i < nFaces; i++)
- {
- InitShapeFromDetBox(shapes[i], detshapes[i], fit_asm.GetMappingDetShape(), fit_asm.GetMeanFaceWidth());
- }
- shape_to_Mat(shapes, nFaces, *((Mat*)faces));
- delete []detshapes;
- delete []shapes;
- }
- JNIEXPORT jboolean JNICALL Java_org_asmlibrary_fit_ASMFit_nativeDetectOne
- (JNIEnv * jenv, jclass, jlong imageGray, jlong faces)
- {
- IplImage image = *(Mat*)imageGray;
- asm_shape shape, detshape;
- BEGINT();
- bool flag = detect_one_face(detshape, &image);
- if(flag == false) {
- ENDT("CascadeDetector CANNOT detect any face");
- return false;
- }
- InitShapeFromDetBox(shape, detshape, fit_asm.GetMappingDetShape(), fit_asm.GetMeanFaceWidth());
- shape_to_Mat(&shape, 1, *((Mat*)faces));
- ENDT("CascadeDetector detects central face");
- return true;
- }
- JNIEXPORT void JNICALL Java_org_asmlibrary_fit_ASMFit_nativeFitting
- (JNIEnv * jenv, jclass, jlong imageGray, jlong shapes0)
- {
- IplImage image = *(Mat*)imageGray;
- Mat shapes1 = *(Mat*)shapes0;
- int nFaces = shapes1.rows;
- asm_shape* shapes = new asm_shape[nFaces];
- BEGINT();
- Mat_to_shape(shapes, nFaces, shapes1);
- fit_asm.Fitting2(shapes, nFaces, &image);
- shape_to_Mat(shapes, nFaces, *((Mat*)shapes0));
- ENDT("nativeFitting");
- //for(int i = 0; i < shapes[0].NPoints(); i++)
- // LOGD("points: (%f, %f)", shapes[0][i].x, shapes[0][i].y);
- delete []shapes;
- }
- JNIEXPORT jboolean JNICALL Java_org_asmlibrary_fit_ASMFit_nativeVideoFitting
- (JNIEnv * jenv, jclass, jlong imageGray, jlong shapes0, jlong frame)
- {
- IplImage image = *(Mat*)imageGray;
- Mat shapes1 = *(Mat*)shapes0;
- bool flag = false;
- if(shapes1.rows == 1)
- {
- asm_shape shape;
- LOGD("nativeVideoFitting %d x %d", image.width, image.height);
- BEGINT();
- Mat_to_shape(&shape, 1, shapes1);
- flag = fit_asm.ASMSeqSearch(shape, &image, frame, true);
- shape_to_Mat(&shape, 1, *((Mat*)shapes0));
- ENDT("nativeVideoFitting");
- }
- return flag;
- }
- #ifdef __cplusplus
- }
- #endif
(6)vjfacedetect.h
- #ifndef _VJFACE_DETECT_H_
- #define _VJFACE_DETECT_H_
- #include "asmlibrary.h"
- /**
- Load adaboost cascade file for detect face.
- @param cascade_name Filename the cascade detector located in
- @return false on failure, true otherwise
- */
- bool init_detect_cascade(const char* cascade_name = "haarcascade_frontalface_alt2.xml");
- /**
- Release the memory of adaboost cascade face detector
- */
- void destory_detect_cascade();
- /**
- Detect only one face from image, and this human face is located as close as to the center of image
- @param shape return face detected box which stores the Top-Left and Bottom-Right points, so its \a NPoints() = 2 here
- @param image the image resource
- @return false on no face exists in image, true otherwise
- */
- bool detect_one_face(asm_shape& shape, const IplImage* image);
- /**
- Detect all human face from image.
- @param shapes return face detected box which stores the Top-Left and Bottom-Right points, so its \a NPoints() = 2 here
- @param n_shapes the numbers of faces to return
- @param image the image resource
- @return false on no face exists in image, true otherwise
- */
- bool detect_all_faces(asm_shape** shapes, int& n_shapes, const IplImage* image);
- /**
- Release the shape resource allocated by detect_all_faces().
- @param shapes the ptr of asm_shape []
- */
- void free_shape_memeory(asm_shape** shapes);
- #endif // _VJFACE_DETECT_H_
未完待续,我发现这样去看代码,有点看不懂
(4)opencv在android平台上实现 物体跟踪的更多相关文章
- OpenCV在Android平台上的应用
今年8月份, OpenCV 2.3.1发布了. 虽然从2.2开始, OpenCV就号称支持Android平台, 但真正能让OpenCV在Android上运行起来还是在2.3.1版本上. 在这个版本上, ...
- 随笔之Android平台上的进程调度探讨
http://blog.csdn.net/innost/article/details/6940136 随笔之Android平台上的进程调度探讨 一由来 最近在翻阅MediaProvider的时候,突 ...
- (转) Android平台上关于IM的实践总结
前言 IM通信在互联网发展到现在已经是码农的世界里人尽皆知的技术,特别在当下移动互联网迅猛发展的时代这种技术的开发也更加火热,其中老牌的代表作就有QQ和MSN,和最近新崛起的微信,默默,易信,来往等眼 ...
- Android平台上最好的几款免费的代码编辑器
使用正确的开发工具能够快速有效地完成源代码的编写和测试,使编程事半功倍.在网络信息高速发展的今天,移动设备的方便快捷已经深入人心,越来越多的程序员会选择在任何感觉舒适的地方使用移动设备查看或者编辑源代 ...
- Qt在Android平台上实现html转PDF的功能
Qt for Android Qt for Android enables you to run Qt 5 applications Android devices. All Qt modules ( ...
- [原]详解如何将cocos2dx项目编译到Android平台上的(方式一:Cywin+NDK)
链接地址:http://m.blog.csdn.net/blog/yhc13429826359/29357815 2014-6-8阅读578 评论0 前言:cocos2dx作为一个开源的移动2D游戏框 ...
- unity3D开发的程序发布到Android平台上进行运行测试的详细步骤
第一步 下载安装JDK 和SDK 1.需要配置java环境.点击链接进入ava的配置的方法:http://www.cnblogs.com/Study088/p/7496158.html 2.下载 ...
- 如何在Android平台上使用USB Audio设备
http://blog.csdn.net/kevinx_xu/article/details/12951131 需求:USB Headset插上去后,声音要从本地CODEC切换到USB Headset ...
- 移动端开发:iOS与Android平台上问题列表
要CSS伪类 :active 生效,只需要给 document 绑定 touchstart 或 touchend 事件 <style> a { color: #000; } a:activ ...
随机推荐
- [转]unzip解压windows zip乱码的处理
[转]unzip解压windows zip乱码的处理 http://blog.sina.com.cn/s/blog_6c9d65a101012gz0.html 朋友从windows传过来的zip文件, ...
- [转]VC的DDK编译环境构建
[转]VC的DDK编译环境构建 http://blog.csdn.net/skdev/article/details/1336935 1 环境状况 Windows XP SP1 NTDDK(win ...
- 2. VS使用---HelloWorld
摘要: ------------------------------------------------------------------------------------- 1. VS2010里 ...
- 如何给ActiveX控件添加“事件”“属性”“标准事件”“自定义事件”等一些相关操作
上一篇小编带大家熟悉了一下ActiveX的建立以及相关的概念,(http://blog.csdn.net/u014028070/article/details/38424611) 本文介绍下如何给控件 ...
- 搭建SpringMVC+MyBatis开发框架五
建立web结构 1.在webapp目录下新建css.img和js文件夹,删除默认的index.jsp文件:  2.在WEB-INF文件夹下建立一个page文件夹,然后在page下新建一个index. ...
- 如何用pdfbox-app-1.8.10.jar批处理将pdf文档转换成text文档
1.首先下载pdfbox-app-1.8.10.jar(下载地址:http://pdfbox.apache.org/download.html) 2.将pdfbox-app-1.8.10.jar加载到 ...
- 文件读写器FileRW 1.0发布
这个软件未发布前,当年被计算机杂志报道过. FileRW 文件读写器 1.0功能介绍:1.可以以各种方式读普通文件和I/O文件.2.可以以各种方式写文件.3.可以配置文件的分享读写方式.4.可以指定文 ...
- 【工具】openwrt安装记录
步骤: 1 从以太网引导启动.由于我们实验室在服务器上放了一个openwrt镜像,安装时先从以太网启动,将服务器上的镜像载入到RAM中启动系统. 2 用SCP将在PC上编译好的openwrt-XX ...
- 使用IntersectionObserver更高效的监视某个页面元素是否进入了可见窗口
比如说,你想跟踪 DOM 树里的一个元素,当它进入可见窗口时得到通知. 也许想实现即时延迟加载图片功能,或者你需要知道用户是否真的在看一个广告 banner. 你可以通过绑定 scroll 事件或者用 ...
- 【Python】代码调试(pdb与logging使用)
一.pdb使用 pdb 是 python 自带的一个包,为 python 程序提供了一种交互的源代码调试功能,主要特性包括设置断点.单步调试.进入函数调试.查看当前代码.查看栈片段.动态改变变量的值等 ...