├── FaceDetectAndTracking ├── .classpath ├── .externalToolBuilders │ └── New_Builder.launch ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── AndroidManifest.xml ├── ic_launcher-web.png ├── jni │ ├── Android.mk │ ├── Application.mk │ ├── CompressiveTracker.cpp │ ├── CompressiveTracker.h │ ├── DetectionFace.cpp │ ├── DetectionFace.h │ └── TrackObj.h ├── libs │ ├── android-support-v4.jar │ └── armeabi-v7a │ │ ├── libface.so │ │ └── libopencv_java3.so ├── proguard-project.txt ├── project.properties ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── drawable-xxhdpi │ │ └── ic_launcher.png │ ├── layout │ │ ├── activity_main.xml │ │ └── activity_main_x.xml │ ├── raw │ │ ├── haarcascade_eye.xml │ │ ├── haarcascade_eye_tree_eyeglasses.xml │ │ ├── haarcascade_frontalface_alt2.xml │ │ ├── haarcascade_mcs_lefteye.xml │ │ ├── haarcascade_mcs_mouth.xml │ │ ├── haarcascade_mcs_nose.xml │ │ ├── haarcascade_mcs_righteye.xml │ │ ├── lbpcascade_frontalcatface.xml │ │ └── lbpcascade_frontalface.xml │ └── values │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml └── src │ └── com │ └── smartcamera │ ├── HomeActivity.java │ ├── MainActivity.java │ ├── core │ ├── CameraManager.java │ ├── Face.java │ └── ImageUtils.java │ ├── utils │ └── Utils.java │ └── widget │ ├── CameraFaceFrameView.java │ ├── CameraView.java │ └── XCameraView.java ├── README.md └── apk └── FaceDetectAndTracking.apk /FaceDetectAndTracking/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/.externalToolBuilders/New_Builder.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FaceDetectAndTracking 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.ui.externaltools.ExternalToolBuilder 30 | auto,full,incremental, 31 | 32 | 33 | LaunchConfigHandle 34 | <project>/.externalToolBuilders/New_Builder.launch 35 | 36 | 37 | 38 | 39 | 40 | com.android.ide.eclipse.adt.AndroidNature 41 | org.eclipse.jdt.core.javanature 42 | 43 | 44 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.6 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.source=1.6 13 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guojunyi/Android-FaceDetectAndTracking/d7f0a899ae54dfe74a499a97f7b14182ac53da1e/FaceDetectAndTracking/ic_launcher-web.png -------------------------------------------------------------------------------- /FaceDetectAndTracking/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | OPENCV_INSTALL_MODULES:=on 6 | OPENCV_CAMERA_MODULES:=off 7 | 8 | OPENCV_LIB_TYPE:=SHARED 9 | include F:\develop\YEclipse\OpenCV-android-sdk\sdk\native\jni/OpenCV.mk 10 | 11 | LOCAL_SRC_FILES := DetectionFace.cpp CompressiveTracker.cpp 12 | LOCAL_C_INCLUDES += $(LOCAL_PATH) 13 | LOCAL_LDLIBS += -llog -ldl 14 | 15 | LOCAL_MODULE := face 16 | 17 | include $(BUILD_SHARED_LIBRARY) 18 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_STL := gnustl_static 2 | APP_CPPFLAGS := -frtti -fexceptions 3 | APP_ABI := armeabi-v7a 4 | APP_PLATFORM := android-8 5 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/jni/CompressiveTracker.cpp: -------------------------------------------------------------------------------- 1 | #include "CompressiveTracker.h" 2 | #include 3 | #include 4 | using namespace cv; 5 | using namespace std; 6 | 7 | //------------------------------------------------ 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | CompressiveTracker::CompressiveTracker(void) 12 | { 13 | featureMinNumRect = 2; 14 | featureMaxNumRect = 4; // number of rectangle from 2 to 4 15 | featureNum = 50; // number of all weaker classifiers, i.e,feature pool 16 | rOuterPositive = 4; // radical scope of positive samples 17 | rSearchWindow = 25; // size of search window 18 | muPositive = vector(featureNum, 0.0f); 19 | muNegative = vector(featureNum, 0.0f); 20 | sigmaPositive = vector(featureNum, 1.0f); 21 | sigmaNegative = vector(featureNum, 1.0f); 22 | learnRate = 0.85f; // Learning rate parameter 23 | } 24 | 25 | CompressiveTracker::~CompressiveTracker(void) 26 | { 27 | } 28 | 29 | 30 | void CompressiveTracker::HaarFeature(Rect& _objectBox, int _numFeature) 31 | /*Description: compute Haar features 32 | Arguments: 33 | -_objectBox: [x y width height] object rectangle 34 | -_numFeature: total number of features.The default is 50. 35 | */ 36 | { 37 | features = vector< vector >(_numFeature, vector()); 38 | featuresWeight = vector< vector >(_numFeature, vector()); 39 | 40 | int numRect; 41 | Rect rectTemp; 42 | float weightTemp; 43 | 44 | for (int i=0; i<_numFeature; i++) 45 | { 46 | numRect = cvFloor(rng.uniform((double)featureMinNumRect, (double)featureMaxNumRect)); 47 | 48 | for (int j=0; j& _sampleBox) 66 | /* Description: compute the coordinate of positive and negative sample image templates 67 | Arguments: 68 | -_image: processing frame 69 | -_objectBox: recent object position 70 | -_rInner: inner sampling radius 71 | -_rOuter: Outer sampling radius 72 | -_maxSampleNum: maximal number of sampled images 73 | -_sampleBox: Storing the rectangle coordinates of the sampled images. 74 | */ 75 | { 76 | int rowsz = _image.rows - _objectBox.height - 1; 77 | int colsz = _image.cols - _objectBox.width - 1; 78 | float inradsq = _rInner*_rInner; 79 | float outradsq = _rOuter*_rOuter; 80 | 81 | 82 | int dist; 83 | 84 | int minrow = max(0,(int)_objectBox.y-(int)_rInner); 85 | int maxrow = min((int)rowsz-1,(int)_objectBox.y+(int)_rInner); 86 | int mincol = max(0,(int)_objectBox.x-(int)_rInner); 87 | int maxcol = min((int)colsz-1,(int)_objectBox.x+(int)_rInner); 88 | 89 | 90 | 91 | int i = 0; 92 | 93 | float prob = ((float)(_maxSampleNum))/(maxrow-minrow+1)/(maxcol-mincol+1); 94 | 95 | int r; 96 | int c; 97 | 98 | _sampleBox.clear();//important 99 | Rect rec(0,0,0,0); 100 | 101 | for( r=minrow; r<=(int)maxrow; r++ ) 102 | for( c=mincol; c<=(int)maxcol; c++ ){ 103 | dist = (_objectBox.y-r)*(_objectBox.y-r) + (_objectBox.x-c)*(_objectBox.x-c); 104 | 105 | if( rng.uniform(0.,1.)= outradsq ){ 106 | 107 | rec.x = c; 108 | rec.y = r; 109 | rec.width = _objectBox.width; 110 | rec.height= _objectBox.height; 111 | 112 | _sampleBox.push_back(rec); 113 | 114 | i++; 115 | } 116 | } 117 | 118 | _sampleBox.resize(i); 119 | 120 | } 121 | 122 | void CompressiveTracker::sampleRect(Mat& _image, Rect& _objectBox, float _srw, vector& _sampleBox) 123 | /* Description: Compute the coordinate of samples when detecting the object.*/ 124 | { 125 | int rowsz = _image.rows - _objectBox.height - 1; 126 | int colsz = _image.cols - _objectBox.width - 1; 127 | float inradsq = _srw*_srw; 128 | 129 | 130 | int dist; 131 | 132 | int minrow = max(0,(int)_objectBox.y-(int)_srw); 133 | int maxrow = min((int)rowsz-1,(int)_objectBox.y+(int)_srw); 134 | int mincol = max(0,(int)_objectBox.x-(int)_srw); 135 | int maxcol = min((int)colsz-1,(int)_objectBox.x+(int)_srw); 136 | 137 | int i = 0; 138 | 139 | int r; 140 | int c; 141 | 142 | Rect rec(0,0,0,0); 143 | _sampleBox.clear();//important 144 | 145 | for( r=minrow; r<=(int)maxrow; r++ ) 146 | for( c=mincol; c<=(int)maxcol; c++ ){ 147 | dist = (_objectBox.y-r)*(_objectBox.y-r) + (_objectBox.x-c)*(_objectBox.x-c); 148 | 149 | if( dist < inradsq ){ 150 | 151 | rec.x = c; 152 | rec.y = r; 153 | rec.width = _objectBox.width; 154 | rec.height= _objectBox.height; 155 | 156 | _sampleBox.push_back(rec); 157 | 158 | i++; 159 | } 160 | } 161 | 162 | _sampleBox.resize(i); 163 | 164 | } 165 | // Compute the features of samples 166 | void CompressiveTracker::getFeatureValue(Mat& _imageIntegral, vector& _sampleBox, Mat& _sampleFeatureValue) 167 | { 168 | int sampleBoxSize = _sampleBox.size(); 169 | _sampleFeatureValue.create(featureNum, sampleBoxSize, CV_32F); 170 | float tempValue; 171 | int xMin; 172 | int xMax; 173 | int yMin; 174 | int yMax; 175 | 176 | for (int i=0; i(yMin, xMin) + 189 | _imageIntegral.at(yMax, xMax) - 190 | _imageIntegral.at(yMin, xMax) - 191 | _imageIntegral.at(yMax, xMin)); 192 | } 193 | _sampleFeatureValue.at(i,j) = tempValue; 194 | } 195 | } 196 | } 197 | 198 | // Update the mean and variance of the gaussian classifier 199 | void CompressiveTracker::classifierUpdate(Mat& _sampleFeatureValue, vector& _mu, vector& _sigma, float _learnRate) 200 | { 201 | Scalar muTemp; 202 | Scalar sigmaTemp; 203 | 204 | for (int i=0; i& _muPos, vector& _sigmaPos, vector& _muNeg, vector& _sigmaNeg, 217 | Mat& _sampleFeatureValue, float& _radioMax, int& _radioMaxIndex) 218 | { 219 | float sumRadio; 220 | _radioMax = -FLT_MAX; 221 | _radioMaxIndex = 0; 222 | float pPos; 223 | float pNeg; 224 | int sampleBoxNum = _sampleFeatureValue.cols; 225 | 226 | for (int j=0; j(i,j)-_muPos[i])*(_sampleFeatureValue.at(i,j)-_muPos[i]) / -(2.0f*_sigmaPos[i]*_sigmaPos[i]+1e-30) ) / (_sigmaPos[i]+1e-30); 232 | pNeg = exp( (_sampleFeatureValue.at(i,j)-_muNeg[i])*(_sampleFeatureValue.at(i,j)-_muNeg[i]) / -(2.0f*_sigmaNeg[i]*_sigmaNeg[i]+1e-30) ) / (_sigmaNeg[i]+1e-30); 233 | sumRadio += log(pPos+1e-30) - log(pNeg+1e-30); // equation 4 234 | } 235 | if (_radioMax < sumRadio) 236 | { 237 | _radioMax = sumRadio; 238 | _radioMaxIndex = j; 239 | } 240 | } 241 | } 242 | void CompressiveTracker::init(Mat& _frame, Rect& _objectBox) 243 | { 244 | // compute feature template 245 | HaarFeature(_objectBox, featureNum); 246 | 247 | // compute sample templates 248 | sampleRect(_frame, _objectBox, rOuterPositive, 0, 1000000, samplePositiveBox); 249 | sampleRect(_frame, _objectBox, rSearchWindow*1.5, rOuterPositive+4.0, 100, sampleNegativeBox); 250 | 251 | integral(_frame, imageIntegral, CV_32F); 252 | 253 | getFeatureValue(imageIntegral, samplePositiveBox, samplePositiveFeatureValue); 254 | getFeatureValue(imageIntegral, sampleNegativeBox, sampleNegativeFeatureValue); 255 | classifierUpdate(samplePositiveFeatureValue, muPositive, sigmaPositive, learnRate); 256 | classifierUpdate(sampleNegativeFeatureValue, muNegative, sigmaNegative, learnRate); 257 | } 258 | void CompressiveTracker::processFrame(Mat& _frame, Rect& _objectBox) 259 | { 260 | // predict 261 | sampleRect(_frame, _objectBox, rSearchWindow,detectBox); 262 | integral(_frame, imageIntegral, CV_32F); 263 | getFeatureValue(imageIntegral, detectBox, detectFeatureValue); 264 | int radioMaxIndex; 265 | float radioMax; 266 | radioClassifier(muPositive, sigmaPositive, muNegative, sigmaNegative, detectFeatureValue, radioMax, radioMaxIndex); 267 | _objectBox = detectBox[radioMaxIndex]; 268 | 269 | // update 270 | sampleRect(_frame, _objectBox, rOuterPositive, 0.0, 1000000, samplePositiveBox); 271 | sampleRect(_frame, _objectBox, rSearchWindow*1.5, rOuterPositive+4.0, 100, sampleNegativeBox); 272 | 273 | getFeatureValue(imageIntegral, samplePositiveBox, samplePositiveFeatureValue); 274 | getFeatureValue(imageIntegral, sampleNegativeBox, sampleNegativeFeatureValue); 275 | classifierUpdate(samplePositiveFeatureValue, muPositive, sigmaPositive, learnRate); 276 | classifierUpdate(sampleNegativeFeatureValue, muNegative, sigmaNegative, learnRate); 277 | } 278 | 279 | #ifdef __cplusplus 280 | } 281 | #endif 282 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/jni/CompressiveTracker.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * File: CompressiveTracker.h 3 | * Brief: C++ demo for paper: Kaihua Zhang, Lei Zhang, Ming-Hsuan Yang,"Real-Time Compressive Tracking," ECCV 2012. 4 | * Version: 1.0 5 | * Author: Yang Xian 6 | * Email: yang_xian521@163.com 7 | * Date: 2012/08/03 8 | * History: 9 | * Revised by Kaihua Zhang on 14/8/2012, 23/8/2012 10 | * Email: zhkhua@gmail.com 11 | * Homepage: http://www4.comp.polyu.edu.hk/~cskhzhang/ 12 | * Project Website: http://www4.comp.polyu.edu.hk/~cslzhang/CT/CT.htm 13 | ************************************************************************/ 14 | #pragma once 15 | #include 16 | #include 17 | #include 18 | 19 | using std::vector; 20 | using namespace cv; 21 | //--------------------------------------------------- 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | class CompressiveTracker 27 | { 28 | public: 29 | CompressiveTracker(void); 30 | ~CompressiveTracker(void); 31 | 32 | private: 33 | int featureMinNumRect; 34 | int featureMaxNumRect; 35 | int featureNum; 36 | vector< vector > features; 37 | vector< vector > featuresWeight; 38 | int rOuterPositive; 39 | vector samplePositiveBox; 40 | vector sampleNegativeBox; 41 | int rSearchWindow; 42 | Mat imageIntegral; 43 | Mat samplePositiveFeatureValue; 44 | Mat sampleNegativeFeatureValue; 45 | vector muPositive; 46 | vector sigmaPositive; 47 | vector muNegative; 48 | vector sigmaNegative; 49 | float learnRate; 50 | vector detectBox; 51 | Mat detectFeatureValue; 52 | RNG rng; 53 | 54 | private: 55 | void HaarFeature(Rect& _objectBox, int _numFeature); 56 | void sampleRect(Mat& _image, Rect& _objectBox, float _rInner, float _rOuter, int _maxSampleNum, vector& _sampleBox); 57 | void sampleRect(Mat& _image, Rect& _objectBox, float _srw, vector& _sampleBox); 58 | void getFeatureValue(Mat& _imageIntegral, vector& _sampleBox, Mat& _sampleFeatureValue); 59 | void classifierUpdate(Mat& _sampleFeatureValue, vector& _mu, vector& _sigma, float _learnRate); 60 | void radioClassifier(vector& _muPos, vector& _sigmaPos, vector& _muNeg, vector& _sigmaNeg, 61 | Mat& _sampleFeatureValue, float& _radioMax, int& _radioMaxIndex); 62 | public: 63 | void processFrame(Mat& _frame, Rect& _objectBox); 64 | void init(Mat& _frame, Rect& _objectBox); 65 | }; 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/jni/DetectionFace.cpp: -------------------------------------------------------------------------------- 1 | #include "DetectionFace.h" 2 | 3 | #include 4 | #include 5 | #include "TrackObj.h" 6 | #include 7 | #include "CompressiveTracker.h" 8 | #define TAG "**guojunyi**" 9 | 10 | #undef LOG // 取消默认的LOG #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__) #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG,__VA_ARGS__) using namespace cv; using namespace std; static CascadeClassifier mCascade1; static CascadeClassifier mCascade2; static CascadeClassifier mCascade3; static CascadeClassifier mCascade4; int vmin = 65, vmax = 256, smin = 55; bool enableTracking; 11 | bool enableAsyncDetect; 12 | int trackingCount; 13 | 14 | #define MAX_FACES 30 15 | 16 | #define TRACKING_IMAGE_WIDTH 640 17 | #define TRACKING_IMAGE_HEIGHT 480 18 | #define MAX_TRACKING_OBJ_SIZE 6 19 | 20 | TrackObj trackObjs[MAX_TRACKING_OBJ_SIZE]; 21 | 22 | jint Java_com_smartcamera_core_CameraManager_loadCascade(JNIEnv *env, 23 | jobject obj, jstring cascade1, jstring cascade2, jstring cascade3, 24 | jstring cascade4) { 25 | 26 | enableTracking = false; 27 | trackingCount = 1; 28 | enableAsyncDetect = false; 29 | 30 | for (int i = 0; i < MAX_TRACKING_OBJ_SIZE; i++) { 31 | trackObjs[i].flag = false; 32 | } 33 | const char *cascadePath1 = env->GetStringUTFChars(cascade1, 0); 34 | const char *cascadePath2 = env->GetStringUTFChars(cascade2, 0); 35 | const char *cascadePath3 = env->GetStringUTFChars(cascade3, 0); 36 | const char *cascadePath4 = env->GetStringUTFChars(cascade4, 0); 37 | jint result = 1; 38 | if (!mCascade1.load(cascadePath1)) { 39 | LOGE("load cascade file fault."); 40 | result = 0; 41 | } 42 | 43 | if (!mCascade2.load(cascadePath2)) { 44 | LOGE("load cascade file fault."); 45 | result = 0; 46 | } 47 | 48 | if (!mCascade3.load(cascadePath3)) { 49 | LOGE("load cascade file fault."); 50 | result = 0; 51 | } 52 | 53 | if (!mCascade4.load(cascadePath4)) { 54 | LOGE("load cascade file fault."); 55 | result = 0; 56 | } 57 | 58 | return result; 59 | } 60 | 61 | void decodeYUV420(char *yuvDatas, int width, int height, int *rgb) { 62 | int frameSize = width * height; 63 | int i = 0, j = 0, yp = 0; 64 | int uvp = 0, u = 0, v = 0; 65 | for (j = 0, yp = 0; j < height; j++) { 66 | uvp = frameSize + (j >> 1) * width; 67 | u = 0; 68 | v = 0; 69 | for (i = 0; i < width; i++, yp++) { 70 | int y = (0xff & ((int) yuvDatas[yp])) - 16; 71 | if (y < 0) 72 | y = 0; 73 | if ((i & 1) == 0) { 74 | v = (0xff & yuvDatas[uvp++]) - 128; 75 | u = (0xff & yuvDatas[uvp++]) - 128; 76 | } 77 | 78 | int y1192 = 1192 * y; 79 | int r = (y1192 + 1634 * v); 80 | int g = (y1192 - 833 * v - 400 * u); 81 | int b = (y1192 + 2066 * u); 82 | 83 | if (r < 0) 84 | r = 0; 85 | else if (r > 262143) 86 | r = 262143; 87 | if (g < 0) 88 | g = 0; 89 | else if (g > 262143) 90 | g = 262143; 91 | if (b < 0) 92 | b = 0; 93 | else if (b > 262143) 94 | b = 262143; 95 | 96 | rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) 97 | | ((b >> 10) & 0xff); 98 | } 99 | } 100 | } 101 | 102 | jintArray Java_com_smartcamera_core_CameraManager_decodeYUV420(JNIEnv *env, 103 | jobject obj, jbyteArray buf, jint width, jint height) { 104 | jbyte * yuv420sp = env->GetByteArrayElements(buf, 0); 105 | 106 | int *rgb = (int*) malloc(width * height * sizeof(int)); 107 | decodeYUV420((char*) yuv420sp, width, height, rgb); 108 | 109 | jintArray result = env->NewIntArray(width * height); 110 | env->SetIntArrayRegion(result, 0, width * height, rgb); 111 | free(rgb); 112 | env->ReleaseByteArrayElements(buf, yuv420sp, 0); 113 | return result; 114 | } 115 | 116 | void rotate(Mat& src, double angle, Mat& dst) { 117 | // get rotation matrix for rotating the image around its center 118 | Point2f center(src.cols / 2.0, src.rows / 2.0); 119 | Mat rot = getRotationMatrix2D(center, angle, 1.0); 120 | 121 | // determine bounding rectangle 122 | Rect bbox = RotatedRect(center, src.size(), angle).boundingRect(); 123 | 124 | // adjust transformation matrix 125 | rot.at(0, 2) += bbox.width / 2.0 - center.x; 126 | rot.at(1, 2) += bbox.height / 2.0 - center.y; 127 | 128 | warpAffine(src, dst, rot, bbox.size()); 129 | } 130 | 131 | bool isOverlap(Rect r1, Rect r2) { 132 | int nMaxLeft = 0; 133 | int nMaxTop = 0; 134 | int nMinRight = 0; 135 | int nMinBottom = 0; 136 | 137 | nMaxLeft = r1.x >= r2.x ? r1.x : r2.x; 138 | nMaxTop = r1.y >= r2.y ? r1.y : r2.y; 139 | nMinRight = 140 | (r1.x + r1.width) <= (r2.x + r2.width) ? 141 | (r1.x + r1.width) : (r2.x + r2.width); 142 | nMinBottom = 143 | (r1.y + r1.height) <= (r2.y + r2.height) ? 144 | (r1.y + r1.height) : (r2.y + r2.height); 145 | 146 | if (nMaxLeft > nMinRight || nMaxTop > nMinBottom) { 147 | return false; 148 | } else { 149 | return true; 150 | } 151 | } 152 | 153 | void initTracker(Mat image, int winWidth, int winHeight, Rect rect) { 154 | int i; 155 | for (i = 0; i < trackingCount; i++) { 156 | if (trackObjs[i].flag) { 157 | Rect r1 = trackObjs[i].trackFaceRect; 158 | bool result = isOverlap(r1, rect); 159 | if (result) { 160 | return; 161 | } 162 | } 163 | } 164 | 165 | int index = -1; 166 | for (i = 0; i < trackingCount; i++) { 167 | if (!trackObjs[i].flag) { 168 | index = i; 169 | break; 170 | } 171 | } 172 | if (index < 0) { 173 | return; 174 | } 175 | 176 | TrackObj &obj = trackObjs[index]; 177 | obj.index = index; 178 | obj.initSize = rect.width * rect.height; 179 | obj.trackFaceRect = rect; 180 | obj.frame = Scalar::all(0); 181 | obj.hsv = Scalar::all(0); 182 | obj.hue = Scalar::all(0); 183 | obj.mask = Scalar::all(0); 184 | obj.hist = Scalar::all(0); 185 | obj.histimg = Mat::zeros(200, 320, CV_8UC3); 186 | obj.backproj = Scalar::all(0); 187 | obj.hsize = 16; 188 | 189 | cvtColor(image, obj.hsv, CV_BGR2HSV); 190 | int _vmin = vmin, _vmax = vmax; 191 | inRange(obj.hsv, Scalar(0, smin, MIN(_vmin, _vmax)), 192 | Scalar(180, 256, MAX(_vmin, _vmax)), obj.mask); 193 | int ch[] = { 0, 0 }; 194 | obj.hue.create(obj.hsv.size(), obj.hsv.depth()); 195 | mixChannels(&obj.hsv, 1, &obj.hue, 1, ch, 1); 196 | 197 | Mat roi(obj.hue, obj.trackFaceRect), maskroi(obj.mask, obj.trackFaceRect); 198 | calcHist(&roi, 1, 0, maskroi, obj.hist, 1, &obj.hsize, &obj.phranges); 199 | 200 | normalize(obj.hist, obj.hist, 0, 255, CV_MINMAX); 201 | 202 | obj.flag = true; 203 | } 204 | 205 | void trackFace(TrackObj& trackObj, Mat image, float *result, int imageWidth, 206 | int imageHeight, JNIEnv *env, jobject obj) { 207 | cvtColor(image, trackObj.hsv, CV_BGR2HSV); 208 | int _vmin = vmin, _vmax = vmax; 209 | inRange(trackObj.hsv, Scalar(0, smin, MIN(_vmin, _vmax)), 210 | Scalar(180, 256, MAX(_vmin, _vmax)), trackObj.mask); 211 | int ch[] = { 0, 0 }; 212 | trackObj.hue.create(trackObj.hsv.size(), trackObj.hsv.depth()); 213 | mixChannels(&trackObj.hsv, 1, &trackObj.hue, 1, ch, 1); 214 | 215 | calcBackProject(&trackObj.hue, 1, 0, trackObj.hist, trackObj.backproj, 216 | &trackObj.phranges); 217 | trackObj.backproj &= trackObj.mask; 218 | 219 | RotatedRect track_box = CamShift(trackObj.backproj, trackObj.trackFaceRect, 220 | TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1)); 221 | 222 | // trackObj.trackFaceRect = Rect(trackObj.trackFaceRect.x, 223 | // trackObj.trackFaceRect.y, trackObj.trackFaceRect.height, 224 | // trackObj.trackFaceRect.height); 225 | 226 | Rect finalRect = Rect(trackObj.trackFaceRect.x, trackObj.trackFaceRect.y, 227 | trackObj.trackFaceRect.height, trackObj.trackFaceRect.height); 228 | int scaleSize = finalRect.width - (int) ((float) finalRect.width / 5.0 * 4); 229 | finalRect = Rect(finalRect.x, finalRect.y + scaleSize / 2, 230 | finalRect.width / 2, finalRect.height - scaleSize); 231 | 232 | // rectangle(image,finalRect,Scalar(255,0,0)); 233 | // imwrite("/storage/emulated/0/123.jpg",image); 234 | 235 | // if(!beOnce){ 236 | // beOnce = true; 237 | // rectangle(image,finalRect,Scalar(255,0,0)); 238 | // imwrite("/storage/emulated/0/123.jpg",image); 239 | // } 240 | 241 | trackObj.trackFaceRect = finalRect; 242 | 243 | Rect brect = trackObj.trackFaceRect; 244 | int x = TRACKING_IMAGE_HEIGHT - brect.y - brect.height; 245 | int y = brect.x; 246 | int width = brect.height; 247 | int height = brect.height; 248 | 249 | //Mat rotateMat; 250 | //rotate(image, -90, rotateMat); 251 | 252 | //rectangle(rotateMat,Rect(x,y,width,height),Scalar(255,0,0)); 253 | //imwrite("/storage/emulated/0/123.jpg",rotateMat); 254 | 255 | float left = (float) x / (float) TRACKING_IMAGE_HEIGHT; 256 | float top = (float) y / (float) TRACKING_IMAGE_WIDTH; 257 | float right = (float) (x + width) / (float) TRACKING_IMAGE_HEIGHT; 258 | float bottom = (float) (y + height) / (float) TRACKING_IMAGE_WIDTH; 259 | 260 | result[0] = left; 261 | result[1] = top; 262 | result[2] = right; 263 | result[3] = bottom; 264 | 265 | } 266 | 267 | int detectFace(Mat image, float *result, int imageWidth, int imageHeight, 268 | int angle) { 269 | vector < Rect > faces; 270 | Mat frame_gray; 271 | cvtColor(image, frame_gray, CV_BGR2GRAY); 272 | equalizeHist(frame_gray, frame_gray); 273 | 274 | mCascade1.detectMultiScale(frame_gray, faces, 1.1, 2, 0, Size(60, 60), 275 | Size(2147483647, 2147483647)); 276 | int effectiveFaceCount = 0; 277 | for (int i = 0; i < faces.size(); i++) { 278 | if (effectiveFaceCount >= MAX_FACES) { 279 | break; 280 | } 281 | 282 | vector < Rect > leftEyes; 283 | vector < Rect > rightEyes; 284 | 285 | Mat faceROI = image(faces[i]); 286 | mCascade2.detectMultiScale(faceROI, leftEyes, 1.1, 2, 287 | 0 | CV_HAAR_SCALE_IMAGE, Size(10, 10)); 288 | 289 | mCascade3.detectMultiScale(faceROI, rightEyes, 1.1, 2, 290 | 0 | CV_HAAR_SCALE_IMAGE, Size(10, 10)); 291 | 292 | if (leftEyes.size() > 0 && rightEyes.size() > 0) { 293 | int centerX = faces[i].x + faces[i].width / 2; 294 | int centerY = faces[i].y + faces[i].height / 2; 295 | int width = (int) ((float) faces[i].width / 5.0 * 4); 296 | int height = (int) ((float) faces[i].height / 5.0 * 4); 297 | 298 | result[4 * effectiveFaceCount + 0] = (float) (centerX - width / 2) 299 | / (float) imageWidth; 300 | result[4 * effectiveFaceCount + 1] = (float) (centerY - height / 2) 301 | / (float) imageHeight; 302 | result[4 * effectiveFaceCount + 2] = (float) (centerX - width / 2 303 | + width) / (float) imageWidth; 304 | result[4 * effectiveFaceCount + 3] = (float) (centerY - height / 2 305 | + height) / (float) imageHeight; 306 | 307 | if (enableTracking) { 308 | int width = (int) ((float) faces[i].width / 5.0 * 5); 309 | int height = (int) ((float) faces[i].height / 5.0 * 5); 310 | Mat rotateMat; 311 | rotate(image, -angle, rotateMat); 312 | int x = centerY - height / 2; 313 | int y = imageWidth - (centerX + width / 2); 314 | Rect rect = Rect(x, y, width, width); 315 | 316 | float left = (float) rect.x / (float) imageHeight; 317 | float top = (float) rect.y / (float) imageWidth; 318 | float right = (float) (rect.x + rect.width) 319 | / (float) imageHeight; 320 | float bottom = (float) (rect.y + rect.height) 321 | / (float) imageWidth; 322 | resize(rotateMat, rotateMat, 323 | Size(TRACKING_IMAGE_WIDTH, TRACKING_IMAGE_HEIGHT)); 324 | Rect finalRect = Rect(TRACKING_IMAGE_WIDTH * left, 325 | TRACKING_IMAGE_HEIGHT * top, 326 | TRACKING_IMAGE_WIDTH * right - TRACKING_IMAGE_WIDTH * left, 327 | TRACKING_IMAGE_HEIGHT * bottom - TRACKING_IMAGE_HEIGHT * top); 328 | 329 | int scaleSize = finalRect.width 330 | - (int) ((float) finalRect.width / 5.0 * 4); 331 | finalRect = Rect(finalRect.x, finalRect.y + scaleSize / 2, 332 | finalRect.width / 2, finalRect.height - scaleSize); 333 | // rectangle(rotateMat,finalRect,Scalar(255,0,0)); 334 | // imwrite("/storage/emulated/0/456.jpg",rotateMat); 335 | initTracker(rotateMat, imageWidth, imageHeight, finalRect); 336 | 337 | } 338 | effectiveFaceCount++; 339 | } 340 | } 341 | 342 | return effectiveFaceCount; 343 | } 344 | 345 | bool isMissTracking(TrackObj& trackObj, float left, float top, float right, 346 | float bottom) { 347 | if (left <= 0 || top <= 0 || right >= 1.0 || (bottom >= 1.0)) { 348 | return true; 349 | } 350 | 351 | int width = TRACKING_IMAGE_HEIGHT * (right - left); 352 | int height = TRACKING_IMAGE_WIDTH * (bottom - top) / 2; 353 | if (width * height > (trackObj.initSize * 1.5)) { 354 | 355 | LOGE("too large missing tracking. %d %d", width * height, 356 | trackObj.initSize); 357 | return true; 358 | } 359 | 360 | if (width * height < (trackObj.initSize * 0.25)) { 361 | LOGE("too small missing tracking."); 362 | return true; 363 | } 364 | 365 | for (int i = 0; i < MAX_TRACKING_OBJ_SIZE; i++) { 366 | TrackObj& obj = trackObjs[i]; 367 | if (obj.index != trackObj.index) { 368 | if (obj.flag) { 369 | Rect r1 = trackObj.trackFaceRect; 370 | Rect r2 = obj.trackFaceRect; 371 | bool result = isOverlap(r1, r2); 372 | if (result) { 373 | if (r1.height > r2.height) { 374 | trackObj.flag = false; 375 | } else { 376 | obj.flag = false; 377 | } 378 | LOGE("overlap missing tracking."); 379 | return true; 380 | } 381 | 382 | } 383 | } 384 | } 385 | return false; 386 | } 387 | 388 | bool isTracking() { 389 | for (int i = 0; i < MAX_TRACKING_OBJ_SIZE; i++) { 390 | if (trackObjs[i].flag) { 391 | return true; 392 | } 393 | } 394 | return false; 395 | } 396 | 397 | jfloatArray Java_com_smartcamera_core_CameraManager_nativeTrackingFace( 398 | JNIEnv *env, jobject obj, jbyteArray yuvDatas, jint width, jint height, 399 | jint angle) { 400 | 401 | if (isTracking() && enableTracking && enableAsyncDetect) { 402 | clock_t time_a, time_b; 403 | time_a = clock(); 404 | jbyte *pBuf = (jbyte*) env->GetByteArrayElements(yuvDatas, 0); 405 | Mat yuv420Mat(height + height / 2, width, CV_8UC1, 406 | (unsigned char *) pBuf); 407 | Mat bgrMat; 408 | cvtColor(yuv420Mat, bgrMat, CV_YUV2BGR_NV21); 409 | resize(bgrMat, bgrMat, 410 | Size(TRACKING_IMAGE_WIDTH, TRACKING_IMAGE_HEIGHT)); 411 | 412 | int i; 413 | int effectiveFaceCount = 0; 414 | float *facesData = (float*) malloc( 415 | MAX_TRACKING_OBJ_SIZE * 4 * sizeof(float)); 416 | for (i = 0; i < trackingCount; i++) { 417 | TrackObj &trackObj = trackObjs[i]; 418 | if (trackObj.flag) { 419 | float *result = (float*) malloc(4 * sizeof(float)); 420 | trackFace(trackObj, bgrMat, result, TRACKING_IMAGE_WIDTH, 421 | TRACKING_IMAGE_HEIGHT, env, obj); 422 | if (isMissTracking(trackObj, result[0], result[1], result[2], 423 | result[3])) { 424 | 425 | trackObj.flag = false; 426 | LOGE("miss tracking"); 427 | } else { 428 | facesData[4 * effectiveFaceCount + 0] = result[0]; 429 | facesData[4 * effectiveFaceCount + 1] = result[1]; 430 | facesData[4 * effectiveFaceCount + 2] = result[2]; 431 | facesData[4 * effectiveFaceCount + 3] = result[3]; 432 | effectiveFaceCount++; 433 | } 434 | free(result); 435 | } 436 | } 437 | 438 | int size = effectiveFaceCount * 4; 439 | jfloatArray result = env->NewFloatArray(size); 440 | env->SetFloatArrayRegion(result, 0, size, facesData); 441 | free(facesData); 442 | env->ReleaseByteArrayElements(yuvDatas, pBuf, 0); 443 | time_b = clock(); 444 | double duration = (double) (time_b - time_a) / CLOCKS_PER_SEC; 445 | //LOGE("%f", duration); 446 | return result; 447 | } 448 | 449 | return NULL; 450 | } 451 | 452 | jfloatArray Java_com_smartcamera_core_CameraManager_nativeDetectFace( 453 | JNIEnv *env, jobject obj, jbyteArray yuvDatas, jint width, jint height, 454 | jint angle) { 455 | 456 | if (isTracking() && !enableAsyncDetect && enableTracking) { 457 | jbyte *pBuf = (jbyte*) env->GetByteArrayElements(yuvDatas, 0); 458 | Mat yuv420Mat(height + height / 2, width, CV_8UC1, 459 | (unsigned char *) pBuf); 460 | Mat bgrMat; 461 | cvtColor(yuv420Mat, bgrMat, CV_YUV2BGR_NV21); 462 | resize(bgrMat, bgrMat, 463 | Size(TRACKING_IMAGE_WIDTH, TRACKING_IMAGE_HEIGHT)); 464 | 465 | int i; 466 | int effectiveFaceCount = 0; 467 | float *facesData = (float*) malloc( 468 | MAX_TRACKING_OBJ_SIZE * 4 * sizeof(float)); 469 | for (i = 0; i < trackingCount; i++) { 470 | TrackObj &trackObj = trackObjs[i]; 471 | if (trackObj.flag) { 472 | float *result = (float*) malloc(4 * sizeof(float)); 473 | trackFace(trackObj, bgrMat, result, TRACKING_IMAGE_WIDTH, 474 | TRACKING_IMAGE_HEIGHT, env, obj); 475 | if (isMissTracking(trackObj, result[0], result[1], result[2], 476 | result[3])) { 477 | 478 | trackObj.flag = false; 479 | LOGE("miss tracking"); 480 | } else { 481 | facesData[4 * effectiveFaceCount + 0] = result[0]; 482 | facesData[4 * effectiveFaceCount + 1] = result[1]; 483 | facesData[4 * effectiveFaceCount + 2] = result[2]; 484 | facesData[4 * effectiveFaceCount + 3] = result[3]; 485 | effectiveFaceCount++; 486 | } 487 | free(result); 488 | } 489 | } 490 | 491 | int size = effectiveFaceCount * 4; 492 | jfloatArray result = env->NewFloatArray(size); 493 | env->SetFloatArrayRegion(result, 0, size, facesData); 494 | free(facesData); 495 | env->ReleaseByteArrayElements(yuvDatas, pBuf, 0); 496 | return result; 497 | } 498 | 499 | jbyte *pBuf = (jbyte*) env->GetByteArrayElements(yuvDatas, 0); 500 | Mat yuv420Mat(height + height / 2, width, CV_8UC1, (unsigned char *) pBuf); 501 | Mat bgrMat; 502 | cvtColor(yuv420Mat, bgrMat, CV_YUV2BGR_NV21); 503 | 504 | Mat rotateMat; 505 | rotate(bgrMat, angle, rotateMat); 506 | 507 | float *facesData = (float*) malloc(MAX_FACES * 4 * sizeof(float)); 508 | int facesSize = detectFace(rotateMat, facesData, height, width, angle); 509 | int size = facesSize * 4; 510 | jfloatArray result = env->NewFloatArray(size); 511 | env->SetFloatArrayRegion(result, 0, size, facesData); 512 | free(facesData); 513 | 514 | env->ReleaseByteArrayElements(yuvDatas, pBuf, 0); 515 | 516 | return result; 517 | } 518 | 519 | jint Java_com_smartcamera_core_CameraManager_nativeEnableTracking(JNIEnv *env, 520 | jobject obj, jint isEnable) { 521 | enableTracking = isEnable == 1 ? true : false; 522 | if (!enableTracking) { 523 | for (int i = 0; i < MAX_TRACKING_OBJ_SIZE; i++) { 524 | trackObjs[i].flag = false; 525 | } 526 | } 527 | return isEnable; 528 | } 529 | 530 | int Java_com_smartcamera_core_CameraManager_nativeIsEnableTracking(JNIEnv *env, 531 | jobject obj) { 532 | return enableTracking; 533 | } 534 | 535 | int Java_com_smartcamera_core_CameraManager_nativeSetTrackingMode(JNIEnv *env, 536 | jobject obj, jint mode) { 537 | for (int i = 0; i < MAX_TRACKING_OBJ_SIZE; i++) { 538 | trackObjs[i].flag = false; 539 | } 540 | if (mode == 0) { 541 | trackingCount = 1; 542 | } else if (mode == 1) { 543 | trackingCount = 2; 544 | } else if (mode == 2) { 545 | trackingCount = MAX_TRACKING_OBJ_SIZE; 546 | } 547 | } 548 | 549 | int Java_com_smartcamera_core_CameraManager_nativeEnableAsyncDetect(JNIEnv *env, 550 | jobject obj, jint isEnable) { 551 | enableAsyncDetect = isEnable == 1 ? true : false; 552 | return isEnable; 553 | } 554 | 555 | int Java_com_smartcamera_core_CameraManager_nativeIsEnableAsyncDetect( 556 | JNIEnv *env, jobject obj) { 557 | return enableAsyncDetect; 558 | } 559 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/jni/DetectionFace.h: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef _DetectionFace 3 | #define _DetectionFace 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | jint Java_com_smartcamera_core_CameraManager_loadCascade(JNIEnv *env, 9 | jobject obj, jstring,jstring,jstring,jstring); 10 | 11 | jintArray Java_com_smartcamera_core_CameraManager_decodeYUV420(JNIEnv *env, 12 | jobject obj, jbyteArray buf, jint width, jint height); 13 | 14 | jfloatArray Java_com_smartcamera_core_CameraManager_nativeDetectFace(JNIEnv *env, 15 | jobject obj,jbyteArray,jint,jint,jint); 16 | 17 | jfloatArray Java_com_smartcamera_core_CameraManager_nativeTrackingFace(JNIEnv *env, 18 | jobject obj,jbyteArray,jint,jint,jint); 19 | 20 | int Java_com_smartcamera_core_CameraManager_nativeEnableTracking(JNIEnv *env, 21 | jobject obj,jint); 22 | 23 | int Java_com_smartcamera_core_CameraManager_nativeIsEnableTracking(JNIEnv *env, 24 | jobject obj); 25 | 26 | int Java_com_smartcamera_core_CameraManager_nativeEnableAsyncDetect(JNIEnv *env, 27 | jobject obj,jint); 28 | 29 | int Java_com_smartcamera_core_CameraManager_nativeIsEnableAsyncDetect(JNIEnv *env, 30 | jobject obj); 31 | 32 | int Java_com_smartcamera_core_CameraManager_nativeSetTrackingMode(JNIEnv *env, 33 | jobject obj,jint); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | #endif 39 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/jni/TrackObj.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace cv; 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | class TrackObj 10 | { 11 | 12 | public: 13 | 14 | TrackObj(void) 15 | { 16 | hranges[0] = 0; 17 | hranges[1] = 180; 18 | phranges = hranges; 19 | hsize = 16; 20 | flag = false; 21 | } 22 | 23 | Rect trackFaceRect; 24 | Mat frame; 25 | Mat hsv; 26 | Mat hue; 27 | Mat mask; 28 | Mat hist; 29 | Mat histimg; 30 | Mat backproj; 31 | 32 | int index; 33 | int initSize; 34 | int hsize; 35 | float hranges[2]; 36 | const float* phranges; 37 | 38 | bool flag; 39 | }; 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guojunyi/Android-FaceDetectAndTracking/d7f0a899ae54dfe74a499a97f7b14182ac53da1e/FaceDetectAndTracking/libs/android-support-v4.jar -------------------------------------------------------------------------------- /FaceDetectAndTracking/libs/armeabi-v7a/libface.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guojunyi/Android-FaceDetectAndTracking/d7f0a899ae54dfe74a499a97f7b14182ac53da1e/FaceDetectAndTracking/libs/armeabi-v7a/libface.so -------------------------------------------------------------------------------- /FaceDetectAndTracking/libs/armeabi-v7a/libopencv_java3.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guojunyi/Android-FaceDetectAndTracking/d7f0a899ae54dfe74a499a97f7b14182ac53da1e/FaceDetectAndTracking/libs/armeabi-v7a/libopencv_java3.so -------------------------------------------------------------------------------- /FaceDetectAndTracking/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-21 15 | android.library.reference.1=../OpenCV Library - 3.0.0 16 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guojunyi/Android-FaceDetectAndTracking/d7f0a899ae54dfe74a499a97f7b14182ac53da1e/FaceDetectAndTracking/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guojunyi/Android-FaceDetectAndTracking/d7f0a899ae54dfe74a499a97f7b14182ac53da1e/FaceDetectAndTracking/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guojunyi/Android-FaceDetectAndTracking/d7f0a899ae54dfe74a499a97f7b14182ac53da1e/FaceDetectAndTracking/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guojunyi/Android-FaceDetectAndTracking/d7f0a899ae54dfe74a499a97f7b14182ac53da1e/FaceDetectAndTracking/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | 11 | 15 | 16 | 20 | 21 | 28 | 29 | 30 | 35 | 36 | 41 | 42 | 50 | 51 | 59 | 60 | 68 | 69 | 77 | 78 | 79 | 84 | 85 | 89 | 90 | 98 | 99 | 107 | 108 | 116 | 117 | 125 | 126 | 134 | 135 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/layout/activity_main_x.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/raw/lbpcascade_frontalface.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | BOOST 9 | LBP 10 | 24 11 | 24 12 | 13 | GAB 14 | 0.9950000047683716 15 | 0.5000000000000000 16 | 0.9500000000000000 17 | 1 18 | 100 19 | 20 | 256 21 | 20 22 | 23 | 24 | <_> 25 | 3 26 | -0.7520892024040222 27 | 28 | 29 | <_> 30 | 31 | 0 -1 46 -67130709 -21569 -1426120013 -1275125205 -21585 32 | -16385 587145899 -24005 33 | 34 | -0.6543210148811340 0.8888888955116272 35 | 36 | <_> 37 | 38 | 0 -1 13 -163512766 -769593758 -10027009 -262145 -514457854 39 | -193593353 -524289 -1 40 | 41 | -0.7739216089248657 0.7278633713722229 42 | 43 | <_> 44 | 45 | 0 -1 2 -363936790 -893203669 -1337948010 -136907894 46 | 1088782736 -134217726 -741544961 -1590337 47 | 48 | -0.7068563103675842 0.6761534214019775 49 | 50 | <_> 51 | 4 52 | -0.4872078299522400 53 | 54 | 55 | <_> 56 | 57 | 0 -1 84 2147483647 1946124287 -536870913 2147450879 58 | 738132490 1061101567 243204619 2147446655 59 | 60 | -0.8083735704421997 0.7685696482658386 61 | 62 | <_> 63 | 64 | 0 -1 21 2147483647 263176079 1879048191 254749487 1879048191 65 | -134252545 -268435457 801111999 66 | 67 | -0.7698410153388977 0.6592915654182434 68 | 69 | <_> 70 | 71 | 0 -1 106 -98110272 1610939566 -285484400 -850010381 72 | -189334372 -1671954433 -571026695 -262145 73 | 74 | -0.7506558895111084 0.5444605946540833 75 | 76 | <_> 77 | 78 | 0 -1 48 -798690576 -131075 1095771153 -237144073 -65569 -1 79 | -216727745 -69206049 80 | 81 | -0.7775990366935730 0.5465461611747742 82 | 83 | <_> 84 | 4 85 | -1.1592328548431396 86 | 87 | 88 | <_> 89 | 90 | 0 -1 47 -21585 -20549 -100818262 -738254174 -20561 -36865 91 | -151016790 -134238549 92 | 93 | -0.5601882934570313 0.7743113040924072 94 | 95 | <_> 96 | 97 | 0 -1 12 -286003217 183435247 -268994614 -421330945 98 | -402686081 1090387966 -286785545 -402653185 99 | 100 | -0.6124526262283325 0.6978127956390381 101 | 102 | <_> 103 | 104 | 0 -1 26 -50347012 970882927 -50463492 -1253377 -134218251 105 | -50364513 -33619992 -172490753 106 | 107 | -0.6114496588706970 0.6537628173828125 108 | 109 | <_> 110 | 111 | 0 -1 8 -273 -135266321 1877977738 -2088243418 -134217987 112 | 2146926575 -18910642 1095231247 113 | 114 | -0.6854077577590942 0.5403239130973816 115 | 116 | <_> 117 | 5 118 | -0.7562355995178223 119 | 120 | 121 | <_> 122 | 123 | 0 -1 96 -1273 1870659519 -20971602 -67633153 -134250731 124 | 2004875127 -250 -150995969 125 | 126 | -0.4051094949245453 0.7584033608436585 127 | 128 | <_> 129 | 130 | 0 -1 33 -868162224 -76810262 -4262145 -257 1465211989 131 | -268959873 -2656269 -524289 132 | 133 | -0.7388162612915039 0.5340843200683594 134 | 135 | <_> 136 | 137 | 0 -1 57 -12817 -49 -541103378 -152950 -38993 -20481 -1153876 138 | -72478976 139 | 140 | -0.6582943797111511 0.5339496731758118 141 | 142 | <_> 143 | 144 | 0 -1 125 -269484161 -452984961 -319816180 -1594032130 -2111 145 | -990117891 -488975296 -520947741 146 | 147 | -0.5981323719024658 0.5323504805564880 148 | 149 | <_> 150 | 151 | 0 -1 53 557787431 670265215 -1342193665 -1075892225 152 | 1998528318 1056964607 -33570977 -1 153 | 154 | -0.6498787999153137 0.4913350641727448 155 | 156 | <_> 157 | 5 158 | -0.8085358142852783 159 | 160 | 161 | <_> 162 | 163 | 0 -1 60 -536873708 880195381 -16842788 -20971521 -176687276 164 | -168427659 -16777260 -33554626 165 | 166 | -0.5278195738792419 0.6946372389793396 167 | 168 | <_> 169 | 170 | 0 -1 7 -1 -62981529 -1090591130 805330978 -8388827 -41945787 171 | -39577 -531118985 172 | 173 | -0.5206505060195923 0.6329920291900635 174 | 175 | <_> 176 | 177 | 0 -1 98 -725287348 1347747543 -852489 -16809993 1489881036 178 | -167903241 -1 -1 179 | 180 | -0.7516061067581177 0.4232024252414703 181 | 182 | <_> 183 | 184 | 0 -1 44 -32777 1006582562 -65 935312171 -8388609 -1078198273 185 | -1 733886267 186 | 187 | -0.7639313936233521 0.4123568832874298 188 | 189 | <_> 190 | 191 | 0 -1 24 -85474705 2138828511 -1036436754 817625855 192 | 1123369029 -58796809 -1013468481 -194513409 193 | 194 | -0.5123769044876099 0.5791834592819214 195 | 196 | <_> 197 | 5 198 | -0.5549971461296082 199 | 200 | 201 | <_> 202 | 203 | 0 -1 42 -17409 -20481 -268457797 -134239493 -17473 -1 -21829 204 | -21846 205 | 206 | -0.3763174116611481 0.7298233509063721 207 | 208 | <_> 209 | 210 | 0 -1 6 -805310737 -2098262358 -269504725 682502698 211 | 2147483519 1740574719 -1090519233 -268472385 212 | 213 | -0.5352765917778015 0.5659480094909668 214 | 215 | <_> 216 | 217 | 0 -1 61 -67109678 -6145 -8 -87884584 -20481 -1073762305 218 | -50856216 -16849696 219 | 220 | -0.5678374171257019 0.4961479902267456 221 | 222 | <_> 223 | 224 | 0 -1 123 -138428633 1002418167 -1359008245 -1908670465 225 | -1346685918 910098423 -1359010520 -1346371657 226 | 227 | -0.5706262588500977 0.4572288393974304 228 | 229 | <_> 230 | 231 | 0 -1 9 -89138513 -4196353 1256531674 -1330665426 1216308261 232 | -36190633 33498198 -151796633 233 | 234 | -0.5344601869583130 0.4672054052352905 235 | 236 | <_> 237 | 5 238 | -0.8776460289955139 239 | 240 | 241 | <_> 242 | 243 | 0 -1 105 1073769576 206601725 -34013449 -33554433 -789514004 244 | -101384321 -690225153 -264193 245 | 246 | -0.7700348496437073 0.5943940877914429 247 | 248 | <_> 249 | 250 | 0 -1 30 -1432340997 -823623681 -49153 -34291724 -269484035 251 | -1342767105 -1078198273 -1277955 252 | 253 | -0.5043668746948242 0.6151274442672730 254 | 255 | <_> 256 | 257 | 0 -1 35 -1067385040 -195758209 -436748425 -134217731 258 | -50855988 -129 -1 -1 259 | 260 | -0.6808040738105774 0.4667325913906097 261 | 262 | <_> 263 | 264 | 0 -1 119 832534325 -34111555 -26050561 -423659521 -268468364 265 | 2105014143 -2114244 -17367185 266 | 267 | -0.4927591383457184 0.5401885509490967 268 | 269 | <_> 270 | 271 | 0 -1 82 -1089439888 -1080524865 2143059967 -1114121 272 | -1140949004 -3 -2361356 -739516 273 | 274 | -0.6445107460021973 0.4227822124958038 275 | 276 | <_> 277 | 6 278 | -1.1139287948608398 279 | 280 | 281 | <_> 282 | 283 | 0 -1 52 -1074071553 -1074003969 -1 -1280135430 -5324817 -1 284 | -335548482 582134442 285 | 286 | -0.5307556986808777 0.6258179545402527 287 | 288 | <_> 289 | 290 | 0 -1 99 -706937396 -705364068 -540016724 -570495027 291 | -570630659 -587857963 -33628164 -35848193 292 | 293 | -0.5227634310722351 0.5049746036529541 294 | 295 | <_> 296 | 297 | 0 -1 18 -2035630093 42119158 -268503053 -1671444 261017599 298 | 1325432815 1954394111 -805306449 299 | 300 | -0.4983572661876679 0.5106441378593445 301 | 302 | <_> 303 | 304 | 0 -1 111 -282529488 -1558073088 1426018736 -170526448 305 | -546832487 -5113037 -34243375 -570427929 306 | 307 | -0.4990860521793366 0.5060507059097290 308 | 309 | <_> 310 | 311 | 0 -1 92 1016332500 -606301707 915094269 -1080086049 312 | -1837027144 -1361600280 2147318747 1067975613 313 | 314 | -0.5695009231567383 0.4460467398166657 315 | 316 | <_> 317 | 318 | 0 -1 51 -656420166 -15413034 -141599534 -603435836 319 | 1505950458 -787556946 -79823438 -1326199134 320 | 321 | -0.6590405106544495 0.3616424500942230 322 | 323 | <_> 324 | 7 325 | -0.8243625760078430 326 | 327 | 328 | <_> 329 | 330 | 0 -1 28 -901591776 -201916417 -262 -67371009 -143312112 331 | -524289 -41943178 -1 332 | 333 | -0.4972776770591736 0.6027074456214905 334 | 335 | <_> 336 | 337 | 0 -1 112 -4507851 -411340929 -268437513 -67502145 -17350859 338 | -32901 -71344315 -29377 339 | 340 | -0.4383158981800079 0.5966237187385559 341 | 342 | <_> 343 | 344 | 0 -1 69 -75894785 -117379438 -239063587 -12538500 1485072126 345 | 2076233213 2123118847 801906927 346 | 347 | -0.6386105418205261 0.3977999985218048 348 | 349 | <_> 350 | 351 | 0 -1 19 -823480413 786628589 -16876049 -1364262914 242165211 352 | 1315930109 -696268833 -455082829 353 | 354 | -0.5512794256210327 0.4282079637050629 355 | 356 | <_> 357 | 358 | 0 -1 73 -521411968 6746762 -1396236286 -2038436114 359 | -185612509 57669627 -143132877 -1041235973 360 | 361 | -0.6418755054473877 0.3549866080284119 362 | 363 | <_> 364 | 365 | 0 -1 126 -478153869 1076028979 -1645895615 1365298272 366 | -557859073 -339771473 1442574528 -1058802061 367 | 368 | -0.4841901361942291 0.4668019413948059 369 | 370 | <_> 371 | 372 | 0 -1 45 -246350404 -1650402048 -1610612745 -788400696 373 | 1467604861 -2787397 1476263935 -4481349 374 | 375 | -0.5855734348297119 0.3879135847091675 376 | 377 | <_> 378 | 7 379 | -1.2237116098403931 380 | 381 | 382 | <_> 383 | 384 | 0 -1 114 -24819 1572863935 -16809993 -67108865 2146778388 385 | 1433927541 -268608444 -34865205 386 | 387 | -0.2518476545810700 0.7088654041290283 388 | 389 | <_> 390 | 391 | 0 -1 97 -1841359 -134271049 -32769 -5767369 -1116675 -2185 392 | -8231 -33603327 393 | 394 | -0.4303432404994965 0.5283288359642029 395 | 396 | <_> 397 | 398 | 0 -1 25 -1359507589 -1360593090 -1073778729 -269553812 399 | -809512977 1744707583 -41959433 -134758978 400 | 401 | -0.4259553551673889 0.5440809130668640 402 | 403 | <_> 404 | 405 | 0 -1 34 729753407 -134270989 -1140907329 -235200777 406 | 658456383 2147467263 -1140900929 -16385 407 | 408 | -0.5605589151382446 0.4220733344554901 409 | 410 | <_> 411 | 412 | 0 -1 134 -310380553 -420675595 -193005472 -353568129 413 | 1205338070 -990380036 887604324 -420544526 414 | 415 | -0.5192656517028809 0.4399855434894562 416 | 417 | <_> 418 | 419 | 0 -1 16 -1427119361 1978920959 -287119734 -487068946 420 | 114759245 -540578051 -707510259 -671660453 421 | 422 | -0.5013077259063721 0.4570254683494568 423 | 424 | <_> 425 | 426 | 0 -1 74 -738463762 -889949281 -328301948 -121832450 427 | -1142658284 -1863576559 2146417353 -263185 428 | 429 | -0.4631414115428925 0.4790246188640595 430 | 431 | <_> 432 | 7 433 | -0.5544230937957764 434 | 435 | 436 | <_> 437 | 438 | 0 -1 113 -76228780 -65538 -1 -67174401 -148007 -33 -221796 439 | -272842924 440 | 441 | -0.3949716091156006 0.6082032322883606 442 | 443 | <_> 444 | 445 | 0 -1 110 369147696 -1625232112 2138570036 -1189900 790708019 446 | -1212613127 799948719 -4456483 447 | 448 | -0.4855885505676270 0.4785369932651520 449 | 450 | <_> 451 | 452 | 0 -1 37 784215839 -290015241 536832799 -402984963 453 | -1342414991 -838864897 -176769 -268456129 454 | 455 | -0.4620285332202911 0.4989669024944305 456 | 457 | <_> 458 | 459 | 0 -1 41 -486418688 -171915327 -340294900 -21938 -519766032 460 | -772751172 -73096060 -585322623 461 | 462 | -0.6420643329620361 0.3624351918697357 463 | 464 | <_> 465 | 466 | 0 -1 117 -33554953 -475332625 -1423463824 -2077230421 467 | -4849669 -2080505925 -219032928 -1071915349 468 | 469 | -0.4820112884044647 0.4632140696048737 470 | 471 | <_> 472 | 473 | 0 -1 65 -834130468 -134217476 -1349314083 -1073803559 474 | -619913764 -1449131844 -1386890321 -1979118423 475 | 476 | -0.4465552568435669 0.5061788558959961 477 | 478 | <_> 479 | 480 | 0 -1 56 -285249779 1912569855 -16530 -1731022870 -1161904146 481 | -1342177297 -268439634 -1464078708 482 | 483 | -0.5190586447715759 0.4441480338573456 484 | 485 | <_> 486 | 7 487 | -0.7161560654640198 488 | 489 | 490 | <_> 491 | 492 | 0 -1 20 1246232575 1078001186 -10027057 60102 -277348353 493 | -43646987 -1210581153 1195769615 494 | 495 | -0.4323809444904327 0.5663768053054810 496 | 497 | <_> 498 | 499 | 0 -1 15 -778583572 -612921106 -578775890 -4036478 500 | -1946580497 -1164766570 -1986687009 -12103599 501 | 502 | -0.4588732719421387 0.4547033011913300 503 | 504 | <_> 505 | 506 | 0 -1 129 -1073759445 2013231743 -1363169553 -1082459201 507 | -1414286549 868185983 -1356133589 -1077936257 508 | 509 | -0.5218553543090820 0.4111092388629913 510 | 511 | <_> 512 | 513 | 0 -1 102 -84148365 -2093417722 -1204850272 564290299 514 | -67121221 -1342177350 -1309195902 -776734797 515 | 516 | -0.4920000731945038 0.4326725304126740 517 | 518 | <_> 519 | 520 | 0 -1 88 -25694458 67104495 -290216278 -168563037 2083877442 521 | 1702788383 -144191964 -234882162 522 | 523 | -0.4494568109512329 0.4448510706424713 524 | 525 | <_> 526 | 527 | 0 -1 59 -857980836 904682741 -1612267521 232279415 528 | 1550862252 -574825221 -357380888 -4579409 529 | 530 | -0.5180826783180237 0.3888972699642181 531 | 532 | <_> 533 | 534 | 0 -1 27 -98549440 -137838400 494928389 -246013630 939541351 535 | -1196072350 -620603549 2137216273 536 | 537 | -0.6081240773200989 0.3333222270011902 538 | 539 | <_> 540 | 8 541 | -0.6743940711021423 542 | 543 | 544 | <_> 545 | 546 | 0 -1 29 -150995201 2071191945 -1302151626 536934335 547 | -1059008937 914128709 1147328110 -268369925 548 | 549 | -0.1790193915367127 0.6605972051620483 550 | 551 | <_> 552 | 553 | 0 -1 128 -134509479 1610575703 -1342177289 1861484541 554 | -1107833788 1577058173 -333558568 -136319041 555 | 556 | -0.3681024610996246 0.5139749646186829 557 | 558 | <_> 559 | 560 | 0 -1 70 -1 1060154476 -1090984524 -630918524 -539492875 561 | 779616255 -839568424 -321 562 | 563 | -0.3217232525348663 0.6171553134918213 564 | 565 | <_> 566 | 567 | 0 -1 4 -269562385 -285029906 -791084350 -17923776 235286671 568 | 1275504943 1344390399 -966276889 569 | 570 | -0.4373284578323364 0.4358185231685638 571 | 572 | <_> 573 | 574 | 0 -1 76 17825984 -747628419 595427229 1474759671 575672208 575 | -1684005538 872217086 -1155858277 576 | 577 | -0.4404836893081665 0.4601220190525055 578 | 579 | <_> 580 | 581 | 0 -1 124 -336593039 1873735591 -822231622 -355795238 582 | -470820869 -1997537409 -1057132384 -1015285005 583 | 584 | -0.4294152259826660 0.4452161788940430 585 | 586 | <_> 587 | 588 | 0 -1 54 -834212130 -593694721 -322142257 -364892500 589 | -951029539 -302125121 -1615106053 -79249765 590 | 591 | -0.3973052501678467 0.4854526817798615 592 | 593 | <_> 594 | 595 | 0 -1 95 1342144479 2147431935 -33554561 -47873 -855685912 -1 596 | 1988052447 536827383 597 | 598 | -0.7054683566093445 0.2697997391223908 599 | 600 | <_> 601 | 9 602 | -1.2042298316955566 603 | 604 | 605 | <_> 606 | 607 | 0 -1 39 1431368960 -183437936 -537002499 -137497097 608 | 1560590321 -84611081 -2097193 -513 609 | 610 | -0.5905947685241699 0.5101932883262634 611 | 612 | <_> 613 | 614 | 0 -1 120 -1645259691 2105491231 2130706431 1458995007 615 | -8567536 -42483883 -33780003 -21004417 616 | 617 | -0.4449204802513123 0.4490709304809570 618 | 619 | <_> 620 | 621 | 0 -1 89 -612381022 -505806938 -362027516 -452985106 622 | 275854917 1920431639 -12600561 -134221825 623 | 624 | -0.4693818688392639 0.4061094820499420 625 | 626 | <_> 627 | 628 | 0 -1 14 -805573153 -161 -554172679 -530519488 -16779441 629 | 2000682871 -33604275 -150997129 630 | 631 | -0.3600351214408875 0.5056326985359192 632 | 633 | <_> 634 | 635 | 0 -1 67 6192 435166195 1467449341 2046691505 -1608493775 636 | -4755729 -1083162625 -71365637 637 | 638 | -0.4459891915321350 0.4132415652275085 639 | 640 | <_> 641 | 642 | 0 -1 86 -41689215 -3281034 1853357967 -420712635 -415924289 643 | -270209208 -1088293113 -825311232 644 | 645 | -0.4466069042682648 0.4135067760944367 646 | 647 | <_> 648 | 649 | 0 -1 80 -117391116 -42203396 2080374461 -188709 -542008165 650 | -356831940 -1091125345 -1073796897 651 | 652 | -0.3394956290721893 0.5658645033836365 653 | 654 | <_> 655 | 656 | 0 -1 75 -276830049 1378714472 -1342181951 757272098 657 | 1073740607 -282199241 -415761549 170896931 658 | 659 | -0.5346512198448181 0.3584479391574860 660 | 661 | <_> 662 | 663 | 0 -1 55 -796075825 -123166849 2113667055 -217530421 664 | -1107432194 -16385 -806359809 -391188771 665 | 666 | -0.4379335641860962 0.4123645126819611 667 | 668 | <_> 669 | 10 670 | -0.8402050137519836 671 | 672 | 673 | <_> 674 | 675 | 0 -1 71 -890246622 15525883 -487690486 47116238 -1212319899 676 | -1291847681 -68159890 -469829921 677 | 678 | -0.2670986354351044 0.6014143228530884 679 | 680 | <_> 681 | 682 | 0 -1 31 -1361180685 -1898008841 -1090588811 -285410071 683 | -1074016265 -840443905 2147221487 -262145 684 | 685 | -0.4149844348430634 0.4670888185501099 686 | 687 | <_> 688 | 689 | 0 -1 40 1426190596 1899364271 2142731795 -142607505 690 | -508232452 -21563393 -41960001 -65 691 | 692 | -0.4985891580581665 0.3719584941864014 693 | 694 | <_> 695 | 696 | 0 -1 109 -201337965 10543906 -236498096 -746195597 697 | 1974565825 -15204415 921907633 -190058309 698 | 699 | -0.4568729996681213 0.3965812027454376 700 | 701 | <_> 702 | 703 | 0 -1 130 -595026732 -656401928 -268649235 -571490699 704 | -440600392 -133131 -358810952 -2004088646 705 | 706 | -0.4770836830139160 0.3862601518630981 707 | 708 | <_> 709 | 710 | 0 -1 66 941674740 -1107882114 1332789109 -67691015 711 | -1360463693 -1556612430 -609108546 733546933 712 | 713 | -0.4877715110778809 0.3778986334800720 714 | 715 | <_> 716 | 717 | 0 -1 49 -17114945 -240061474 1552871558 -82775604 -932393844 718 | -1308544889 -532635478 -99042357 719 | 720 | -0.3721654713153839 0.4994400143623352 721 | 722 | <_> 723 | 724 | 0 -1 133 -655906006 1405502603 -939205164 1884929228 725 | -498859222 559417357 -1928559445 -286264385 726 | 727 | -0.3934195041656494 0.4769641458988190 728 | 729 | <_> 730 | 731 | 0 -1 0 -335837777 1860677295 -90 -1946186226 931096183 732 | 251612987 2013265917 -671232197 733 | 734 | -0.4323300719261169 0.4342164099216461 735 | 736 | <_> 737 | 738 | 0 -1 103 37769424 -137772680 374692301 2002666345 -536176194 739 | -1644484728 807009019 1069089930 740 | 741 | -0.4993278682231903 0.3665378093719482 742 | 743 | <_> 744 | 9 745 | -1.1974394321441650 746 | 747 | 748 | <_> 749 | 750 | 0 -1 43 -5505 2147462911 2143265466 -4511070 -16450 -257 751 | -201348440 -71333206 752 | 753 | -0.3310225307941437 0.5624626278877258 754 | 755 | <_> 756 | 757 | 0 -1 90 -136842268 -499330741 2015250980 -87107126 758 | -641665744 -788524639 -1147864792 -134892563 759 | 760 | -0.5266560912132263 0.3704403042793274 761 | 762 | <_> 763 | 764 | 0 -1 104 -146800880 -1780368555 2111170033 -140904684 765 | -16777551 -1946681885 -1646463595 -839131947 766 | 767 | -0.4171888828277588 0.4540435671806335 768 | 769 | <_> 770 | 771 | 0 -1 85 -832054034 -981663763 -301990281 -578814081 772 | -932319000 -1997406723 -33555201 -69206017 773 | 774 | -0.4556705355644226 0.3704262077808380 775 | 776 | <_> 777 | 778 | 0 -1 24 -118492417 -1209026825 1119023838 -1334313353 779 | 1112948738 -297319313 1378887291 -139469193 780 | 781 | -0.4182529747486115 0.4267231225967407 782 | 783 | <_> 784 | 785 | 0 -1 78 -1714382628 -2353704 -112094959 -549613092 786 | -1567058760 -1718550464 -342315012 -1074972227 787 | 788 | -0.3625369668006897 0.4684656262397766 789 | 790 | <_> 791 | 792 | 0 -1 5 -85219702 316836394 -33279 1904970288 2117267315 793 | -260901769 -621461759 -88607770 794 | 795 | -0.4742925167083740 0.3689507246017456 796 | 797 | <_> 798 | 799 | 0 -1 11 -294654041 -353603585 -1641159686 -50331921 800 | -2080899877 1145569279 -143132713 -152044037 801 | 802 | -0.3666271567344666 0.4580127298831940 803 | 804 | <_> 805 | 806 | 0 -1 32 1887453658 -638545712 -1877976819 -34320972 807 | -1071067983 -661345416 -583338277 1060190561 808 | 809 | -0.4567637443542481 0.3894708156585693 810 | 811 | <_> 812 | 9 813 | -0.5733128190040588 814 | 815 | 816 | <_> 817 | 818 | 0 -1 122 -994063296 1088745462 -318837116 -319881377 819 | 1102566613 1165490103 -121679694 -134744129 820 | 821 | -0.4055117964744568 0.5487945079803467 822 | 823 | <_> 824 | 825 | 0 -1 68 -285233233 -538992907 1811935199 -369234005 -529 826 | -20593 -20505 -1561401854 827 | 828 | -0.3787897229194641 0.4532003402709961 829 | 830 | <_> 831 | 832 | 0 -1 58 -1335245632 1968917183 1940861695 536816369 833 | -1226071367 -570908176 457026619 1000020667 834 | 835 | -0.4258328974246979 0.4202791750431061 836 | 837 | <_> 838 | 839 | 0 -1 94 -1360318719 -1979797897 -50435249 -18646473 840 | -608879292 -805306691 -269304244 -17840167 841 | 842 | -0.4561023116111755 0.4002747833728790 843 | 844 | <_> 845 | 846 | 0 -1 87 2062765935 -16449 -1275080721 -16406 45764335 847 | -1090552065 -772846337 -570464322 848 | 849 | -0.4314672648906708 0.4086346626281738 850 | 851 | <_> 852 | 853 | 0 -1 127 -536896021 1080817663 -738234288 -965478709 854 | -2082767969 1290855887 1993822934 -990381609 855 | 856 | -0.4174543321132660 0.4249868988990784 857 | 858 | <_> 859 | 860 | 0 -1 3 -818943025 168730891 -293610428 -79249354 669224671 861 | 621166734 1086506807 1473768907 862 | 863 | -0.4321364760398865 0.4090838730335236 864 | 865 | <_> 866 | 867 | 0 -1 79 -68895696 -67107736 -1414315879 -841676168 868 | -619843344 -1180610531 -1081990469 1043203389 869 | 870 | -0.5018386244773865 0.3702533841133118 871 | 872 | <_> 873 | 874 | 0 -1 116 -54002134 -543485719 -2124882422 -1437445858 875 | -115617074 -1195787391 -1096024366 -2140472445 876 | 877 | -0.5037505626678467 0.3564981222152710 878 | 879 | <_> 880 | 9 881 | -0.4892596900463104 882 | 883 | 884 | <_> 885 | 886 | 0 -1 132 -67113211 2003808111 1862135111 846461923 -2752 887 | 2002237273 -273154752 1937223539 888 | 889 | -0.2448196411132813 0.5689709186553955 890 | 891 | <_> 892 | 893 | 0 -1 62 1179423888 -78064940 -611839555 -539167899 894 | -1289358360 -1650810108 -892540499 -1432827684 895 | 896 | -0.4633283913135529 0.3587929606437683 897 | 898 | <_> 899 | 900 | 0 -1 23 -285212705 -78450761 -656212031 -264050110 -27787425 901 | -1334349961 -547662981 -135796924 902 | 903 | -0.3731099069118500 0.4290455579757690 904 | 905 | <_> 906 | 907 | 0 -1 77 341863476 403702016 -550588417 1600194541 908 | -1080690735 951127993 -1388580949 -1153717473 909 | 910 | -0.3658909499645233 0.4556473195552826 911 | 912 | <_> 913 | 914 | 0 -1 22 -586880702 -204831512 -100644596 -39319550 915 | -1191150794 705692513 457203315 -75806957 916 | 917 | -0.5214384198188782 0.3221037387847900 918 | 919 | <_> 920 | 921 | 0 -1 72 -416546870 545911370 -673716192 -775559454 922 | -264113598 139424 -183369982 -204474641 923 | 924 | -0.4289036989212036 0.4004956185817719 925 | 926 | <_> 927 | 928 | 0 -1 50 -1026505020 -589692154 -1740499937 -1563770497 929 | 1348491006 -60710713 -1109853489 -633909413 930 | 931 | -0.4621542394161224 0.3832748532295227 932 | 933 | <_> 934 | 935 | 0 -1 108 -1448872304 -477895040 -1778390608 -772418127 936 | -1789923416 -1612057181 -805306693 -1415842113 937 | 938 | -0.3711548447608948 0.4612701535224915 939 | 940 | <_> 941 | 942 | 0 -1 92 407905424 -582449988 52654751 -1294472 -285103725 943 | -74633006 1871559083 1057955850 944 | 945 | -0.5180652141571045 0.3205870389938355 946 | 947 | <_> 948 | 10 949 | -0.5911940932273865 950 | 951 | 952 | <_> 953 | 954 | 0 -1 81 4112 -1259563825 -846671428 -100902460 1838164148 955 | -74153752 -90653988 -1074263896 956 | 957 | -0.2592592537403107 0.5873016119003296 958 | 959 | <_> 960 | 961 | 0 -1 1 -285216785 -823206977 -1085589 -1081346 1207959293 962 | 1157103471 2097133565 -2097169 963 | 964 | -0.3801195919513702 0.4718827307224274 965 | 966 | <_> 967 | 968 | 0 -1 121 -12465 -536875169 2147478367 2130706303 -37765492 969 | -866124467 -318782328 -1392509185 970 | 971 | -0.3509117066860199 0.5094807147979736 972 | 973 | <_> 974 | 975 | 0 -1 38 2147449663 -20741 -16794757 1945873146 -16710 -1 976 | -8406341 -67663041 977 | 978 | -0.4068757295608521 0.4130136370658875 979 | 980 | <_> 981 | 982 | 0 -1 17 -155191713 866117231 1651407483 548272812 -479201468 983 | -447742449 1354229504 -261884429 984 | 985 | -0.4557141065597534 0.3539792001247406 986 | 987 | <_> 988 | 989 | 0 -1 100 -225319378 -251682065 -492783986 -792341777 990 | -1287261695 1393643841 -11274182 -213909521 991 | 992 | -0.4117803275585175 0.4118592441082001 993 | 994 | <_> 995 | 996 | 0 -1 63 -382220122 -2002072729 -51404800 -371201558 997 | -923011069 -2135301457 -2066104743 -1042557441 998 | 999 | -0.4008397758007050 0.4034757018089294 1000 | 1001 | <_> 1002 | 1003 | 0 -1 101 -627353764 -48295149 1581203952 -436258614 1004 | -105268268 -1435893445 -638126888 -1061107126 1005 | 1006 | -0.5694189667701721 0.2964762747287750 1007 | 1008 | <_> 1009 | 1010 | 0 -1 118 -8399181 1058107691 -621022752 -251003468 -12582915 1011 | -574619739 -994397789 -1648362021 1012 | 1013 | -0.3195341229438782 0.5294018983840942 1014 | 1015 | <_> 1016 | 1017 | 0 -1 92 -348343812 -1078389516 1717960437 364735981 1018 | -1783841602 -4883137 -457572354 -1076950384 1019 | 1020 | -0.3365339040756226 0.5067458748817444 1021 | 1022 | <_> 1023 | 10 1024 | -0.7612916231155396 1025 | 1026 | 1027 | <_> 1028 | 1029 | 0 -1 10 -1976661318 -287957604 -1659497122 -782068 43591089 1030 | -453637880 1435470000 -1077438561 1031 | 1032 | -0.4204545319080353 0.5165745615959168 1033 | 1034 | <_> 1035 | 1036 | 0 -1 131 -67110925 14874979 -142633168 -1338923040 1037 | 2046713291 -2067933195 1473503712 -789579837 1038 | 1039 | -0.3762553930282593 0.4075302779674530 1040 | 1041 | <_> 1042 | 1043 | 0 -1 83 -272814301 -1577073 -1118685 -305156120 -1052289 1044 | -1073813756 -538971154 -355523038 1045 | 1046 | -0.4253497421741486 0.3728055357933044 1047 | 1048 | <_> 1049 | 1050 | 0 -1 135 -2233 -214486242 -538514758 573747007 -159390971 1051 | 1994225489 -973738098 -203424005 1052 | 1053 | -0.3601998090744019 0.4563256204128265 1054 | 1055 | <_> 1056 | 1057 | 0 -1 115 -261031688 -1330369299 -641860609 1029570301 1058 | -1306461192 -1196149518 -1529767778 683139823 1059 | 1060 | -0.4034293889999390 0.4160816967487335 1061 | 1062 | <_> 1063 | 1064 | 0 -1 64 -572993608 -34042628 -417865 -111109 -1433365268 1065 | -19869715 -1920939864 -1279457063 1066 | 1067 | -0.3620899617671967 0.4594142735004425 1068 | 1069 | <_> 1070 | 1071 | 0 -1 36 -626275097 -615256993 1651946018 805366393 1072 | 2016559730 -430780849 -799868165 -16580645 1073 | 1074 | -0.3903816640377045 0.4381459355354309 1075 | 1076 | <_> 1077 | 1078 | 0 -1 93 1354797300 -1090957603 1976418270 -1342502178 1079 | -1851873892 -1194637077 -1153521668 -1108399474 1080 | 1081 | -0.3591445386409760 0.4624078869819641 1082 | 1083 | <_> 1084 | 1085 | 0 -1 91 68157712 1211368313 -304759523 1063017136 798797750 1086 | -275513546 648167355 -1145357350 1087 | 1088 | -0.4297670423984528 0.4023293554782867 1089 | 1090 | <_> 1091 | 1092 | 0 -1 107 -546318240 -1628569602 -163577944 -537002306 1093 | -545456389 -1325465645 -380446736 -1058473386 1094 | 1095 | -0.5727006793022156 0.2995934784412384 1096 | 1097 | <_> 1098 | 1099 | 0 0 3 5 1100 | <_> 1101 | 1102 | 0 0 4 2 1103 | <_> 1104 | 1105 | 0 0 6 3 1106 | <_> 1107 | 1108 | 0 1 2 3 1109 | <_> 1110 | 1111 | 0 1 3 3 1112 | <_> 1113 | 1114 | 0 1 3 7 1115 | <_> 1116 | 1117 | 0 4 3 3 1118 | <_> 1119 | 1120 | 0 11 3 4 1121 | <_> 1122 | 1123 | 0 12 8 4 1124 | <_> 1125 | 1126 | 0 14 4 3 1127 | <_> 1128 | 1129 | 1 0 5 3 1130 | <_> 1131 | 1132 | 1 1 2 2 1133 | <_> 1134 | 1135 | 1 3 3 1 1136 | <_> 1137 | 1138 | 1 7 4 4 1139 | <_> 1140 | 1141 | 1 12 2 2 1142 | <_> 1143 | 1144 | 1 13 4 1 1145 | <_> 1146 | 1147 | 1 14 4 3 1148 | <_> 1149 | 1150 | 1 17 3 2 1151 | <_> 1152 | 1153 | 2 0 2 3 1154 | <_> 1155 | 1156 | 2 1 2 2 1157 | <_> 1158 | 1159 | 2 2 4 6 1160 | <_> 1161 | 1162 | 2 3 4 4 1163 | <_> 1164 | 1165 | 2 7 2 1 1166 | <_> 1167 | 1168 | 2 11 2 3 1169 | <_> 1170 | 1171 | 2 17 3 2 1172 | <_> 1173 | 1174 | 3 0 2 2 1175 | <_> 1176 | 1177 | 3 1 7 3 1178 | <_> 1179 | 1180 | 3 7 2 1 1181 | <_> 1182 | 1183 | 3 7 2 4 1184 | <_> 1185 | 1186 | 3 18 2 2 1187 | <_> 1188 | 1189 | 4 0 2 3 1190 | <_> 1191 | 1192 | 4 3 2 1 1193 | <_> 1194 | 1195 | 4 6 2 1 1196 | <_> 1197 | 1198 | 4 6 2 5 1199 | <_> 1200 | 1201 | 4 7 5 2 1202 | <_> 1203 | 1204 | 4 8 4 3 1205 | <_> 1206 | 1207 | 4 18 2 2 1208 | <_> 1209 | 1210 | 5 0 2 2 1211 | <_> 1212 | 1213 | 5 3 4 4 1214 | <_> 1215 | 1216 | 5 6 2 5 1217 | <_> 1218 | 1219 | 5 9 2 2 1220 | <_> 1221 | 1222 | 5 10 2 2 1223 | <_> 1224 | 1225 | 6 3 4 4 1226 | <_> 1227 | 1228 | 6 4 4 3 1229 | <_> 1230 | 1231 | 6 5 2 3 1232 | <_> 1233 | 1234 | 6 5 2 5 1235 | <_> 1236 | 1237 | 6 5 4 3 1238 | <_> 1239 | 1240 | 6 6 4 2 1241 | <_> 1242 | 1243 | 6 6 4 4 1244 | <_> 1245 | 1246 | 6 18 1 2 1247 | <_> 1248 | 1249 | 6 21 2 1 1250 | <_> 1251 | 1252 | 7 0 3 7 1253 | <_> 1254 | 1255 | 7 4 2 3 1256 | <_> 1257 | 1258 | 7 9 5 1 1259 | <_> 1260 | 1261 | 7 21 2 1 1262 | <_> 1263 | 1264 | 8 0 1 4 1265 | <_> 1266 | 1267 | 8 5 2 2 1268 | <_> 1269 | 1270 | 8 5 3 2 1271 | <_> 1272 | 1273 | 8 17 3 1 1274 | <_> 1275 | 1276 | 8 18 1 2 1277 | <_> 1278 | 1279 | 9 0 5 3 1280 | <_> 1281 | 1282 | 9 2 2 6 1283 | <_> 1284 | 1285 | 9 5 1 1 1286 | <_> 1287 | 1288 | 9 11 1 1 1289 | <_> 1290 | 1291 | 9 16 1 1 1292 | <_> 1293 | 1294 | 9 16 2 1 1295 | <_> 1296 | 1297 | 9 17 1 1 1298 | <_> 1299 | 1300 | 9 18 1 1 1301 | <_> 1302 | 1303 | 10 5 1 2 1304 | <_> 1305 | 1306 | 10 5 3 3 1307 | <_> 1308 | 1309 | 10 7 1 5 1310 | <_> 1311 | 1312 | 10 8 1 1 1313 | <_> 1314 | 1315 | 10 9 1 1 1316 | <_> 1317 | 1318 | 10 10 1 1 1319 | <_> 1320 | 1321 | 10 10 1 2 1322 | <_> 1323 | 1324 | 10 14 3 3 1325 | <_> 1326 | 1327 | 10 15 1 1 1328 | <_> 1329 | 1330 | 10 15 2 1 1331 | <_> 1332 | 1333 | 10 16 1 1 1334 | <_> 1335 | 1336 | 10 16 2 1 1337 | <_> 1338 | 1339 | 10 17 1 1 1340 | <_> 1341 | 1342 | 10 21 1 1 1343 | <_> 1344 | 1345 | 11 3 2 2 1346 | <_> 1347 | 1348 | 11 5 1 2 1349 | <_> 1350 | 1351 | 11 5 3 3 1352 | <_> 1353 | 1354 | 11 5 4 6 1355 | <_> 1356 | 1357 | 11 6 1 1 1358 | <_> 1359 | 1360 | 11 7 2 2 1361 | <_> 1362 | 1363 | 11 8 1 2 1364 | <_> 1365 | 1366 | 11 10 1 1 1367 | <_> 1368 | 1369 | 11 10 1 2 1370 | <_> 1371 | 1372 | 11 15 1 1 1373 | <_> 1374 | 1375 | 11 17 1 1 1376 | <_> 1377 | 1378 | 11 18 1 1 1379 | <_> 1380 | 1381 | 12 0 2 2 1382 | <_> 1383 | 1384 | 12 1 2 5 1385 | <_> 1386 | 1387 | 12 2 4 1 1388 | <_> 1389 | 1390 | 12 3 1 3 1391 | <_> 1392 | 1393 | 12 7 3 4 1394 | <_> 1395 | 1396 | 12 10 3 2 1397 | <_> 1398 | 1399 | 12 11 1 1 1400 | <_> 1401 | 1402 | 12 12 3 2 1403 | <_> 1404 | 1405 | 12 14 4 3 1406 | <_> 1407 | 1408 | 12 17 1 1 1409 | <_> 1410 | 1411 | 12 21 2 1 1412 | <_> 1413 | 1414 | 13 6 2 5 1415 | <_> 1416 | 1417 | 13 7 3 5 1418 | <_> 1419 | 1420 | 13 11 3 2 1421 | <_> 1422 | 1423 | 13 17 2 2 1424 | <_> 1425 | 1426 | 13 17 3 2 1427 | <_> 1428 | 1429 | 13 18 1 2 1430 | <_> 1431 | 1432 | 13 18 2 2 1433 | <_> 1434 | 1435 | 14 0 2 2 1436 | <_> 1437 | 1438 | 14 1 1 3 1439 | <_> 1440 | 1441 | 14 2 3 2 1442 | <_> 1443 | 1444 | 14 7 2 1 1445 | <_> 1446 | 1447 | 14 13 2 1 1448 | <_> 1449 | 1450 | 14 13 3 3 1451 | <_> 1452 | 1453 | 14 17 2 2 1454 | <_> 1455 | 1456 | 15 0 2 2 1457 | <_> 1458 | 1459 | 15 0 2 3 1460 | <_> 1461 | 1462 | 15 4 3 2 1463 | <_> 1464 | 1465 | 15 4 3 6 1466 | <_> 1467 | 1468 | 15 6 3 2 1469 | <_> 1470 | 1471 | 15 11 3 4 1472 | <_> 1473 | 1474 | 15 13 3 2 1475 | <_> 1476 | 1477 | 15 17 2 2 1478 | <_> 1479 | 1480 | 15 17 3 2 1481 | <_> 1482 | 1483 | 16 1 2 3 1484 | <_> 1485 | 1486 | 16 3 2 4 1487 | <_> 1488 | 1489 | 16 6 1 1 1490 | <_> 1491 | 1492 | 16 16 2 2 1493 | <_> 1494 | 1495 | 17 1 2 2 1496 | <_> 1497 | 1498 | 17 1 2 5 1499 | <_> 1500 | 1501 | 17 12 2 2 1502 | <_> 1503 | 1504 | 18 0 2 2 1505 | 1506 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | FaceDetectAndTracking 5 | Hello world! 6 | Settings 7 | 8 | 9 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/src/com/smartcamera/HomeActivity.java: -------------------------------------------------------------------------------- 1 | package com.smartcamera; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | 8 | import android.app.Activity; 9 | import android.content.res.Configuration; 10 | import android.graphics.Bitmap; 11 | import android.os.Bundle; 12 | import android.os.Environment; 13 | import android.os.Handler; 14 | import android.os.Looper; 15 | import android.view.View; 16 | import android.view.View.OnClickListener; 17 | import android.view.WindowManager; 18 | import android.widget.CheckBox; 19 | import android.widget.CompoundButton; 20 | import android.widget.CompoundButton.OnCheckedChangeListener; 21 | import android.widget.ImageView; 22 | import android.widget.RadioButton; 23 | import android.widget.TextView; 24 | 25 | import com.smartcamera.core.CameraManager; 26 | import com.smartcamera.widget.CameraFaceFrameView; 27 | import com.smartcamera.widget.CameraView; 28 | import com.smartcamera.widget.CameraView.OnDetectEndListener; 29 | 30 | public class HomeActivity extends Activity{ 31 | 32 | static { 33 | System.loadLibrary("opencv_java3"); 34 | System.loadLibrary("face"); 35 | } 36 | 37 | CameraView cameraView; 38 | CameraFaceFrameView faceFrameView; 39 | Handler mHandler = new Handler(Looper.getMainLooper()); 40 | 41 | public TextView textView; 42 | CheckBox checkBox1,checkBox2; 43 | RadioButton radio1,radio2,radio3; 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 48 | setContentView(R.layout.activity_main); 49 | 50 | cameraView = (CameraView) findViewById(R.id.cameraView); 51 | faceFrameView = (CameraFaceFrameView) findViewById(R.id.faceFrameView); 52 | cameraView.setCameraFaceFrameView(faceFrameView); 53 | 54 | initOpencv(); 55 | 56 | checkBox1 = (CheckBox) findViewById(R.id.checkBox1); 57 | checkBox1.setOnClickListener(new OnClickListener(){ 58 | 59 | @Override 60 | public void onClick(View v) { 61 | // TODO Auto-generated method stub 62 | if(CameraManager.getInstance().nativeIsEnableTracking()==1){ 63 | checkBox1.setChecked(false); 64 | CameraManager.getInstance().nativeEnableTracking(0); 65 | }else{ 66 | checkBox1.setChecked(true); 67 | CameraManager.getInstance().nativeEnableTracking(1); 68 | } 69 | } 70 | 71 | }); 72 | 73 | checkBox2 = (CheckBox) findViewById(R.id.checkBox2); 74 | checkBox2.setOnClickListener(new OnClickListener(){ 75 | 76 | @Override 77 | public void onClick(View v) { 78 | // TODO Auto-generated method stub 79 | if(CameraManager.getInstance().nativeIsEnableAsyncDetect()==1){ 80 | checkBox2.setChecked(false); 81 | CameraManager.getInstance().nativeEnableAsyncDetect(0); 82 | }else{ 83 | checkBox2.setChecked(true); 84 | CameraManager.getInstance().nativeEnableAsyncDetect(1); 85 | } 86 | } 87 | 88 | }); 89 | 90 | 91 | textView = (TextView) findViewById(R.id.textView); 92 | 93 | 94 | radio1 = (RadioButton) findViewById(R.id.radio1); 95 | radio2 = (RadioButton) findViewById(R.id.radio2); 96 | radio3 = (RadioButton) findViewById(R.id.radio3); 97 | radio1.setOnCheckedChangeListener(new OnCheckedChangeListener(){ 98 | 99 | @Override 100 | public void onCheckedChanged(CompoundButton buttonView, 101 | boolean isChecked) { 102 | // TODO Auto-generated method stub 103 | if(isChecked){ 104 | CameraManager.getInstance().nativeSetTrackingMode(0); 105 | } 106 | 107 | } 108 | 109 | }); 110 | 111 | radio2.setOnCheckedChangeListener(new OnCheckedChangeListener(){ 112 | 113 | @Override 114 | public void onCheckedChanged(CompoundButton buttonView, 115 | boolean isChecked) { 116 | // TODO Auto-generated method stub 117 | if(isChecked){ 118 | CameraManager.getInstance().nativeSetTrackingMode(1); 119 | } 120 | } 121 | 122 | }); 123 | 124 | radio3.setOnCheckedChangeListener(new OnCheckedChangeListener(){ 125 | 126 | @Override 127 | public void onCheckedChanged(CompoundButton buttonView, 128 | boolean isChecked) { 129 | // TODO Auto-generated method stub 130 | if(isChecked){ 131 | CameraManager.getInstance().nativeSetTrackingMode(2); 132 | } 133 | } 134 | 135 | }); 136 | 137 | } 138 | 139 | @Override 140 | public void onResume() { 141 | super.onResume(); 142 | 143 | } 144 | 145 | @Override 146 | public void onStop() { 147 | super.onStop(); 148 | } 149 | 150 | @Override 151 | public void onDestroy() { 152 | super.onDestroy(); 153 | } 154 | 155 | @Override 156 | public void onConfigurationChanged(Configuration newConfig) { 157 | super.onConfigurationChanged(newConfig); 158 | } 159 | 160 | public void initOpencv() { 161 | try { 162 | // load cascade file from application resources 163 | InputStream is = getResources().openRawResource( 164 | R.raw.lbpcascade_frontalface); 165 | File mCascadeFile = new File(Environment 166 | .getExternalStorageDirectory().getAbsolutePath() 167 | + "/cascade1.xml"); 168 | if (!mCascadeFile.exists()) { 169 | mCascadeFile.createNewFile(); 170 | } else { 171 | mCascadeFile.delete(); 172 | mCascadeFile.createNewFile(); 173 | } 174 | FileOutputStream os = new FileOutputStream(mCascadeFile); 175 | byte[] buffer = new byte[4096]; 176 | int bytesRead; 177 | while ((bytesRead = is.read(buffer)) != -1) { 178 | os.write(buffer, 0, bytesRead); 179 | } 180 | is.close(); 181 | os.close(); 182 | } catch (IOException e) { 183 | e.printStackTrace(); 184 | } 185 | 186 | try { 187 | // load cascade file from application resources 188 | InputStream is = getResources().openRawResource( 189 | R.raw.haarcascade_mcs_lefteye); 190 | File mCascadeFile = new File(Environment 191 | .getExternalStorageDirectory().getAbsolutePath() 192 | + "/cascade2.xml"); 193 | if (!mCascadeFile.exists()) { 194 | mCascadeFile.createNewFile(); 195 | } else { 196 | mCascadeFile.delete(); 197 | mCascadeFile.createNewFile(); 198 | } 199 | FileOutputStream os = new FileOutputStream(mCascadeFile); 200 | byte[] buffer = new byte[4096]; 201 | int bytesRead; 202 | while ((bytesRead = is.read(buffer)) != -1) { 203 | os.write(buffer, 0, bytesRead); 204 | } 205 | is.close(); 206 | os.close(); 207 | } catch (IOException e) { 208 | e.printStackTrace(); 209 | } 210 | 211 | try { 212 | // load cascade file from application resources 213 | InputStream is = getResources().openRawResource( 214 | R.raw.haarcascade_mcs_righteye); 215 | File mCascadeFile = new File(Environment 216 | .getExternalStorageDirectory().getAbsolutePath() 217 | + "/cascade3.xml"); 218 | if (!mCascadeFile.exists()) { 219 | mCascadeFile.createNewFile(); 220 | } else { 221 | mCascadeFile.delete(); 222 | mCascadeFile.createNewFile(); 223 | } 224 | FileOutputStream os = new FileOutputStream(mCascadeFile); 225 | byte[] buffer = new byte[4096]; 226 | int bytesRead; 227 | while ((bytesRead = is.read(buffer)) != -1) { 228 | os.write(buffer, 0, bytesRead); 229 | } 230 | is.close(); 231 | os.close(); 232 | } catch (IOException e) { 233 | e.printStackTrace(); 234 | } 235 | 236 | try { 237 | // load cascade file from application resources 238 | InputStream is = getResources().openRawResource( 239 | R.raw.haarcascade_mcs_mouth); 240 | File mCascadeFile = new File(Environment 241 | .getExternalStorageDirectory().getAbsolutePath() 242 | + "/cascade4.xml"); 243 | if (!mCascadeFile.exists()) { 244 | mCascadeFile.createNewFile(); 245 | } else { 246 | mCascadeFile.delete(); 247 | mCascadeFile.createNewFile(); 248 | } 249 | FileOutputStream os = new FileOutputStream(mCascadeFile); 250 | byte[] buffer = new byte[4096]; 251 | int bytesRead; 252 | while ((bytesRead = is.read(buffer)) != -1) { 253 | os.write(buffer, 0, bytesRead); 254 | } 255 | is.close(); 256 | os.close(); 257 | } catch (IOException e) { 258 | e.printStackTrace(); 259 | } 260 | 261 | CameraManager.getInstance().loadCascade( 262 | Environment.getExternalStorageDirectory().getAbsolutePath() 263 | + "/cascade1.xml", 264 | Environment.getExternalStorageDirectory().getAbsolutePath() 265 | + "/cascade2.xml", 266 | Environment.getExternalStorageDirectory().getAbsolutePath() 267 | + "/cascade3.xml", 268 | Environment.getExternalStorageDirectory().getAbsolutePath() 269 | + "/cascade4.xml"); 270 | } 271 | 272 | 273 | 274 | 275 | } 276 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/src/com/smartcamera/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.smartcamera; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.InputStream; 6 | 7 | import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame; 8 | import org.opencv.core.Core; 9 | import org.opencv.core.Mat; 10 | import org.opencv.core.MatOfRect; 11 | import org.opencv.core.Rect; 12 | import org.opencv.core.RotatedRect; 13 | import org.opencv.core.Scalar; 14 | import org.opencv.core.Size; 15 | import org.opencv.imgproc.Imgproc; 16 | import org.opencv.objdetect.CascadeClassifier; 17 | 18 | import android.app.Activity; 19 | import android.content.Context; 20 | import android.content.pm.ActivityInfo; 21 | import android.content.res.Configuration; 22 | import android.os.Bundle; 23 | import android.os.Handler; 24 | import android.os.Looper; 25 | import android.view.WindowManager; 26 | 27 | import com.smartcamera.widget.XCameraView; 28 | import com.smartcamera.widget.XCameraView.CvCameraViewListener2; 29 | 30 | public class MainActivity extends Activity implements CvCameraViewListener2{ 31 | 32 | static { 33 | System.loadLibrary("opencv_java3"); 34 | } 35 | 36 | XCameraView cameraView; 37 | Handler mHandler = new Handler(Looper.getMainLooper()); 38 | 39 | private File mCascadeFile; 40 | private CascadeClassifier mJavaDetector; 41 | 42 | private Mat mRgba; 43 | private Mat mGray; 44 | 45 | @Override 46 | protected void onCreate(Bundle savedInstanceState) { 47 | 48 | 49 | super.onCreate(savedInstanceState); 50 | setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 51 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 52 | setContentView(R.layout.activity_main_x); 53 | cameraView = (XCameraView) findViewById(R.id.cameraView); 54 | cameraView.setCvCameraViewListener(this); 55 | initOpencv(); 56 | } 57 | 58 | @Override 59 | public void onResume() { 60 | super.onResume(); 61 | } 62 | 63 | @Override 64 | public void onStop() { 65 | super.onStop(); 66 | cameraView.disconnectCamera(); 67 | mGray.release(); 68 | mRgba.release(); 69 | } 70 | 71 | @Override 72 | public void onDestroy() { 73 | super.onDestroy(); 74 | // CameraManager.getInstance().closeCamera(); 75 | } 76 | 77 | @Override 78 | public void onConfigurationChanged(Configuration newConfig) { 79 | super.onConfigurationChanged(newConfig); 80 | } 81 | 82 | public void initOpencv() { 83 | try{ 84 | InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface); 85 | File cascadeDir = getDir("cascade", Context.MODE_PRIVATE); 86 | mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml"); 87 | FileOutputStream os = new FileOutputStream(mCascadeFile); 88 | 89 | byte[] buffer = new byte[4096]; 90 | int bytesRead; 91 | while ((bytesRead = is.read(buffer)) != -1) { 92 | os.write(buffer, 0, bytesRead); 93 | } 94 | is.close(); 95 | os.close(); 96 | 97 | mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath()); 98 | 99 | 100 | cascadeDir.delete(); 101 | 102 | cameraView.connectCamera(); 103 | 104 | mGray = new Mat(); 105 | mRgba = new Mat(); 106 | }catch(Exception e){ 107 | e.printStackTrace(); 108 | } 109 | } 110 | 111 | 112 | long time; 113 | private float mRelativeFaceSize = 0.2f; 114 | private int mAbsoluteFaceSize = 0; 115 | private static final Scalar FACE_RECT_COLOR = new Scalar(0, 255, 0, 255); 116 | 117 | Rect[] facesArray; 118 | @Override 119 | public Mat onCameraFrame(CvCameraViewFrame inputFrame) { 120 | // TODO Auto-generated method stub 121 | mRgba = inputFrame.rgba(); 122 | mGray = inputFrame.gray(); 123 | 124 | MatOfRect faces = new MatOfRect(); 125 | if (mAbsoluteFaceSize == 0) { 126 | int height = mGray.rows(); 127 | if (Math.round(height * mRelativeFaceSize) > 0) { 128 | mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize); 129 | } 130 | } 131 | if (mJavaDetector != null) 132 | mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE 133 | new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size()); 134 | 135 | 136 | facesArray = faces.toArray(); 137 | for (int i = 0; i < facesArray.length; i++){ 138 | Imgproc.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3); 139 | } 140 | 141 | 142 | 143 | return mRgba; 144 | } 145 | 146 | 147 | } 148 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/src/com/smartcamera/core/CameraManager.java: -------------------------------------------------------------------------------- 1 | package com.smartcamera.core; 2 | 3 | import android.graphics.RectF; 4 | import android.hardware.Camera; 5 | import android.util.Log; 6 | 7 | public class CameraManager { 8 | 9 | 10 | private static final String TAG = "CameraManager"; 11 | private static CameraManager mCameraManager = null; 12 | public static CameraManager getInstance() { 13 | 14 | if (null == mCameraManager) { 15 | synchronized (CameraManager.class) { 16 | if (null == mCameraManager) { 17 | mCameraManager = new CameraManager(); 18 | } 19 | } 20 | } 21 | return mCameraManager; 22 | } 23 | 24 | 25 | private Camera mCamera; 26 | private int currentCameraId; 27 | //private PreviewCallback mPreviewCallback; 28 | public Camera open(int cameraId){ 29 | if (null != mCamera) { 30 | return mCamera; 31 | } 32 | 33 | try { 34 | mCamera = Camera.open(cameraId); 35 | currentCameraId = cameraId; 36 | //mCamera.setDisplayOrientation(90); 37 | //setParams(); 38 | } catch (Exception e) { 39 | Log.e(TAG, "open camera error"); 40 | e.printStackTrace(); 41 | if(null!=mCamera){ 42 | mCamera.release(); 43 | mCamera = null; 44 | } 45 | } 46 | return mCamera; 47 | } 48 | 49 | public Camera getCamera(){ 50 | return mCamera; 51 | } 52 | 53 | 54 | public void closeCamera(){ 55 | try{ 56 | synchronized(CameraManager.this){ 57 | if (mCamera != null) { 58 | mCamera.stopPreview(); 59 | mCamera.setPreviewCallback(null); 60 | mCamera.release(); 61 | mCamera = null; 62 | } 63 | } 64 | }catch(Exception e){ 65 | e.printStackTrace(); 66 | } 67 | 68 | } 69 | 70 | 71 | public int getCurrentCameraId(){ 72 | return this.currentCameraId; 73 | } 74 | 75 | public Face[] findFaces(byte[] datas,int width,int height,int angle){ 76 | float[] faceDatas = nativeDetectFace(datas,width,height,angle); 77 | if(null!=faceDatas&&faceDatas.length>0){ 78 | int count = faceDatas.length/4; 79 | Face[] faces = new Face[count]; 80 | for(int i=0;i0){ 97 | int count = faceDatas.length/4; 98 | Face[] faces = new Face[count]; 99 | for(int i=0;i width || size.y > height) 92 | return Math.max(Math.round((float) size.y / (float) height), 93 | Math.round((float) size.x / (float) width)); 94 | else 95 | return 1; 96 | } 97 | 98 | /** 99 | * Get size of image 100 | * 101 | * @param imagePath 102 | * @return size 103 | */ 104 | public static Point getSize(final String imagePath) { 105 | final Options options = new Options(); 106 | options.inJustDecodeBounds = true; 107 | RandomAccessFile file = null; 108 | try { 109 | file = new RandomAccessFile(imagePath, "r"); 110 | BitmapFactory.decodeFileDescriptor(file.getFD(), null, options); 111 | return new Point(options.outWidth, options.outHeight); 112 | } catch (IOException e) { 113 | Log.d(TAG, e.getMessage(), e); 114 | return null; 115 | } finally { 116 | if (file != null) 117 | try { 118 | file.close(); 119 | } catch (IOException e) { 120 | Log.d(TAG, e.getMessage(), e); 121 | } 122 | } 123 | } 124 | 125 | /** 126 | * Get size of image 127 | * 128 | * @param image 129 | * @return size 130 | */ 131 | public static Point getSize(final byte[] image) { 132 | final Options options = new Options(); 133 | options.inJustDecodeBounds = true; 134 | BitmapFactory.decodeByteArray(image, 0, image.length, options); 135 | return new Point(options.outWidth, options.outHeight); 136 | } 137 | 138 | /** 139 | * Get bitmap with maximum height or width 140 | * 141 | * @param imagePath 142 | * @param width 143 | * @param height 144 | * @return image 145 | */ 146 | public static Bitmap getBitmap(final String imagePath, int width, int height) { 147 | Point size = getSize(imagePath); 148 | return getBitmap(imagePath, getScale(size, width, height)); 149 | } 150 | 151 | /** 152 | * Get bitmap with maximum height or width 153 | * 154 | * @param image 155 | * @param width 156 | * @param height 157 | * @return image 158 | */ 159 | public static Bitmap getBitmap(final byte[] image, int width, int height) { 160 | Point size = getSize(image); 161 | return getBitmap(image, getScale(size, width, height)); 162 | } 163 | 164 | /** 165 | * Get bitmap with maximum height or width 166 | * 167 | * @param image 168 | * @param width 169 | * @param height 170 | * @return image 171 | */ 172 | public static Bitmap getBitmap(final File image, int width, int height) { 173 | return getBitmap(image.getAbsolutePath(), width, height); 174 | } 175 | 176 | /** 177 | * Get a bitmap from the image file 178 | * 179 | * @param image 180 | * @return bitmap or null if read fails 181 | */ 182 | public static Bitmap getBitmap(final File image) { 183 | return getBitmap(image.getAbsolutePath()); 184 | } 185 | 186 | /** 187 | * Load a {@link Bitmap} from the given path and set it on the given 188 | * {@link ImageView} 189 | * 190 | * @param imagePath 191 | * @param view 192 | */ 193 | public static void setImage(final String imagePath, final ImageView view) { 194 | setImage(new File(imagePath), view); 195 | } 196 | 197 | /** 198 | * Load a {@link Bitmap} from the given {@link File} and set it on the given 199 | * {@link ImageView} 200 | * 201 | * @param image 202 | * @param view 203 | */ 204 | public static void setImage(final File image, final ImageView view) { 205 | Bitmap bitmap = getBitmap(image); 206 | if (bitmap != null) 207 | view.setImageBitmap(bitmap); 208 | } 209 | 210 | /** 211 | * Round the corners of a {@link Bitmap} 212 | * 213 | * @param source 214 | * @param radius 215 | * @return rounded corner bitmap 216 | */ 217 | public static Bitmap roundCorners(final Bitmap source, final float radius) { 218 | int width = source.getWidth(); 219 | int height = source.getHeight(); 220 | Paint paint = new Paint(); 221 | paint.setAntiAlias(true); 222 | paint.setColor(WHITE); 223 | Bitmap clipped = Bitmap.createBitmap(width, height, ARGB_8888); 224 | Canvas canvas = new Canvas(clipped); 225 | canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, 226 | paint); 227 | paint.setXfermode(new PorterDuffXfermode(DST_IN)); 228 | Bitmap rounded = Bitmap.createBitmap(width, height, ARGB_8888); 229 | canvas = new Canvas(rounded); 230 | canvas.drawBitmap(source, 0, 0, null); 231 | canvas.drawBitmap(clipped, 0, 0, paint); 232 | source.recycle(); 233 | clipped.recycle(); 234 | return rounded; 235 | } 236 | } -------------------------------------------------------------------------------- /FaceDetectAndTracking/src/com/smartcamera/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package com.smartcamera.utils; 2 | 3 | import android.content.Context; 4 | import android.util.TypedValue; 5 | import android.view.View; 6 | 7 | public class Utils { 8 | 9 | public static int dp2px(Context context, int dp) { 10 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, 11 | context.getResources().getDisplayMetrics()); 12 | } 13 | 14 | public static int px2dp(Context context,float pxValue){ 15 | final float scale = context.getResources().getDisplayMetrics().density; 16 | return (int)((pxValue*160)/scale); 17 | } 18 | 19 | 20 | public static int px2sp(Context context, float pxValue) { 21 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 22 | return (int) (pxValue / fontScale + 0.5f); 23 | } 24 | 25 | public static int sp2px(Context context, float spValue) { 26 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 27 | return (int) (spValue * fontScale + 0.5f); 28 | } 29 | 30 | public static int getRelativeTop(View myView) { 31 | // if (myView.getParent() == myView.getRootView()) 32 | if(myView.getId() == android.R.id.content) 33 | return myView.getTop(); 34 | else 35 | return myView.getTop() + getRelativeTop((View) myView.getParent()); 36 | } 37 | 38 | public static int getRelativeLeft(View myView) { 39 | // if (myView.getParent() == myView.getRootView()) 40 | if(myView.getId() == android.R.id.content) 41 | return myView.getLeft(); 42 | else 43 | return myView.getLeft() + getRelativeLeft((View) myView.getParent()); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/src/com/smartcamera/widget/CameraFaceFrameView.java: -------------------------------------------------------------------------------- 1 | package com.smartcamera.widget; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import android.content.Context; 7 | import android.graphics.Canvas; 8 | import android.graphics.Matrix; 9 | import android.graphics.Paint; 10 | import android.graphics.Paint.Style; 11 | import android.graphics.RectF; 12 | import android.os.Handler; 13 | import android.os.Looper; 14 | import android.util.AttributeSet; 15 | import android.util.Log; 16 | import android.view.View; 17 | 18 | import com.smartcamera.core.Face; 19 | import com.smartcamera.utils.Utils; 20 | 21 | public class CameraFaceFrameView extends View { 22 | Paint mPaint; 23 | 24 | Face[] faces; 25 | float animateMargin = 30; 26 | Handler mHandler = new Handler(Looper.getMainLooper()); 27 | boolean clearFlag; 28 | public CameraFaceFrameView(Context context, AttributeSet attrs) { 29 | super(context, attrs); 30 | // TODO Auto-generated constructor stub 31 | mPaint = new Paint(); 32 | mPaint.setStyle(Style.STROKE); 33 | mPaint.setAntiAlias(true); 34 | mPaint.setStrokeWidth(Utils.dp2px(context, 2)); 35 | mPaint.setColor(0xff5cb7f0); 36 | 37 | animateMargin = Utils.dp2px(context, (int)animateMargin); 38 | } 39 | 40 | @Override 41 | public void onDraw(Canvas canvas) { 42 | if(null!=faces&&faces.length>0){ 43 | for (Face face : faces) { 44 | int left = (int) (face.left*getWidth()); 45 | int top = (int) (face.top*getHeight()); 46 | int right = (int) (face.right*getWidth()); 47 | int bottom = (int) (face.bottom*getHeight()); 48 | canvas.drawRoundRect(new RectF(left,top,right,bottom), Utils.dp2px(getContext(), 5), Utils.dp2px(getContext(), 5), mPaint); 49 | } 50 | } 51 | } 52 | 53 | public void drawFaceFrames(Face[] faces) { 54 | this.faces = faces; 55 | invalidate(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/src/com/smartcamera/widget/CameraView.java: -------------------------------------------------------------------------------- 1 | package com.smartcamera.widget; 2 | 3 | import java.util.Collections; 4 | import java.util.Comparator; 5 | import java.util.List; 6 | 7 | import android.content.Context; 8 | import android.graphics.Bitmap; 9 | import android.graphics.ImageFormat; 10 | import android.graphics.RectF; 11 | import android.hardware.Camera; 12 | import android.hardware.Camera.AutoFocusCallback; 13 | import android.hardware.Camera.Size; 14 | import android.os.Build; 15 | import android.os.Handler; 16 | import android.os.Looper; 17 | import android.os.Message; 18 | import android.util.AttributeSet; 19 | import android.util.Log; 20 | import android.view.OrientationEventListener; 21 | import android.view.SurfaceHolder; 22 | import android.view.SurfaceView; 23 | 24 | import com.smartcamera.HomeActivity; 25 | import com.smartcamera.core.CameraManager; 26 | import com.smartcamera.core.CameraManager.TrackingCallback; 27 | import com.smartcamera.core.Face; 28 | 29 | public class CameraView extends SurfaceView implements SurfaceHolder.Callback, 30 | Camera.PreviewCallback, TrackingCallback { 31 | private static final String TAG = "CameraView"; 32 | private Context mContext; 33 | private SurfaceHolder mHolder; 34 | 35 | private CameraFaceFrameView mCameraFaceFrameView; 36 | 37 | private Handler mHandler = new Handler(Looper.getMainLooper()) { 38 | 39 | @Override 40 | public void handleMessage(Message msg) { 41 | // TODO Auto-generated method stub 42 | super.handleMessage(msg); 43 | mCameraFaceFrameView.drawFaceFrames((Face[]) msg.obj); 44 | 45 | } 46 | 47 | }; 48 | 49 | private OrientationEventListener mOrientationEventListener; 50 | private int rotateAngle; 51 | 52 | private byte[] mDatas1; 53 | private byte[] mDatas2; 54 | private int index = 0; 55 | 56 | private Thread mThread; 57 | private Object syncObject = new Object(); 58 | 59 | private boolean mStopThread; 60 | private boolean mCameraFrameReady; 61 | 62 | private boolean isEnableAsyncDetect; 63 | public CameraView(Context context) { 64 | // TODO Auto-generated constructor stub 65 | this(context, null); 66 | } 67 | 68 | public CameraView(Context context, AttributeSet attrs) { 69 | super(context, attrs); 70 | // TODO Auto-generated constructor stub 71 | mContext = context; 72 | init(); 73 | } 74 | 75 | private void init() { 76 | mHolder = getHolder(); 77 | mHolder.addCallback(this); 78 | mHolder.setKeepScreenOn(true); 79 | mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 80 | CameraManager.getInstance().open(0); 81 | CameraManager.getInstance().setTrackingCallback(this); 82 | mOrientationEventListener = new OrientationEventListener(mContext) { 83 | 84 | @Override 85 | public void onOrientationChanged(int orientation) { 86 | // TODO Auto-generated method stub 87 | rotateAngle = orientation; 88 | } 89 | 90 | }; 91 | 92 | mStopThread = false; 93 | mThread = new Thread(new CameraWorker()); 94 | mThread.start(); 95 | } 96 | 97 | public void setCameraFaceFrameView(CameraFaceFrameView cameraFaceFrameView) { 98 | mCameraFaceFrameView = cameraFaceFrameView; 99 | } 100 | 101 | @Override 102 | public void surfaceCreated(SurfaceHolder holder) { 103 | // TODO Auto-generated method stub 104 | Log.e(TAG, "surfaceCreated"); 105 | } 106 | 107 | @Override 108 | public void surfaceChanged(SurfaceHolder holder, int format, int width, 109 | int height) { 110 | // TODO Auto-generated method stub 111 | Log.e(TAG, "surfaceChanged"); 112 | mOrientationEventListener.enable(); 113 | Camera camera = CameraManager.getInstance().getCamera(); 114 | if (null == mHolder.getSurface() || null == camera) { 115 | return; 116 | } 117 | handleSurfaceChanged(); 118 | try { 119 | camera.stopPreview(); 120 | camera.setPreviewCallback(this); 121 | camera.setPreviewDisplay(holder); 122 | camera.startPreview(); 123 | } catch (Exception e) { 124 | Log.e(TAG, "Error starting camera preview: " + e.getMessage()); 125 | } 126 | } 127 | 128 | @Override 129 | public void surfaceDestroyed(SurfaceHolder holder) { 130 | // TODO Auto-generated method stub 131 | try { 132 | mStopThread = true; 133 | Log.e(TAG, "Notify thread"); 134 | synchronized (syncObject) { 135 | syncObject.notify(); 136 | } 137 | Log.e(TAG, "Wating for thread"); 138 | if (mThread != null) 139 | mThread.join(); 140 | } catch (InterruptedException e) { 141 | e.printStackTrace(); 142 | } finally { 143 | mThread = null; 144 | } 145 | 146 | mCameraFrameReady = false; 147 | mOrientationEventListener.disable(); 148 | CameraManager.getInstance().closeCamera(); 149 | 150 | } 151 | 152 | private AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback() { 153 | 154 | @Override 155 | public void onAutoFocus(boolean success, Camera camera) { 156 | // TODO Auto-generated method stub 157 | if (success) { 158 | Log.e(TAG, "focus success"); 159 | 160 | } else { 161 | Log.e(TAG, "focus failure"); 162 | } 163 | } 164 | 165 | }; 166 | 167 | public static class ResolutionComparator implements Comparator { 168 | @Override 169 | public int compare(Camera.Size size1, Camera.Size size2) { 170 | if (size1.height != size2.height) 171 | return size1.height - size2.height; 172 | else 173 | return size1.width - size2.width; 174 | } 175 | } 176 | 177 | private void handleSurfaceChanged() { 178 | try { 179 | Camera camera = CameraManager.getInstance().getCamera(); 180 | Camera.Parameters parameters = camera.getParameters(); 181 | 182 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH 183 | && !android.os.Build.MODEL.equals("GT-I9100")) 184 | parameters.setRecordingHint(true); 185 | 186 | // set camera preview format 187 | parameters.setPreviewFormat(ImageFormat.NV21); 188 | 189 | // set camera preview size 190 | List resolutionList = parameters 191 | .getSupportedPreviewSizes(); 192 | if (resolutionList != null && resolutionList.size() > 0) { 193 | Collections.sort(resolutionList, new ResolutionComparator()); 194 | Camera.Size previewSize = null; 195 | int maxSize = 0; 196 | for (int i = 0; i < resolutionList.size(); i++) { 197 | Size size = resolutionList.get(i); 198 | 199 | if (size.width % 160 == 0 && size.height % 160 == 0) { 200 | if (size.width * size.height > maxSize) { 201 | maxSize = size.width * size.height; 202 | previewSize = size; 203 | } 204 | } 205 | } 206 | 207 | if (null != previewSize) { 208 | parameters.setPreviewSize(previewSize.width, 209 | previewSize.height); 210 | } 211 | 212 | } 213 | 214 | Log.e(TAG, 215 | parameters.getPreviewSize().width + ":" 216 | + parameters.getPreviewSize().height); 217 | 218 | // set camera framerate 219 | parameters.setPreviewFrameRate(30); 220 | 221 | // set camera focus mode 222 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) { 223 | List focusModes = parameters.getSupportedFocusModes(); 224 | if (focusModes != null) { 225 | if (((Build.MODEL.startsWith("GT-I950")) 226 | || (Build.MODEL.endsWith("SCH-I959")) || (Build.MODEL 227 | .endsWith("MEIZU MX3"))) 228 | && focusModes 229 | .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { 230 | 231 | parameters 232 | .setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 233 | } else if (focusModes 234 | .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { 235 | parameters 236 | .setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); 237 | } else 238 | parameters 239 | .setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED); 240 | } 241 | } 242 | 243 | camera.setDisplayOrientation(90); 244 | camera.setParameters(parameters); 245 | } catch (Exception e) { 246 | e.printStackTrace(); 247 | } 248 | 249 | } 250 | 251 | @Override 252 | public void onPreviewFrame(byte[] data, Camera camera) { 253 | // TODO Auto-generated method stub 254 | // the bitmap we want to fill with the image 255 | Camera.Parameters p = camera.getParameters(); 256 | 257 | synchronized (syncObject) { 258 | 259 | if (index == 0) { 260 | mDatas1 = data; 261 | } else if (index == 1) { 262 | mDatas2 = data; 263 | } 264 | 265 | mCameraFrameReady = true; 266 | syncObject.notify(); 267 | } 268 | 269 | } 270 | 271 | // public int[] detectFace(byte[] datas) { 272 | // Camera camera = CameraManager.getInstance().getCamera(); 273 | // Camera.Parameters p = camera.getParameters(); 274 | // int[] rgb = CameraManager.getInstance().decodeYUV420(datas, 275 | // p.getPreviewSize().width, p.getPreviewSize().height); 276 | // Bitmap localBitmap1 = Bitmap.createBitmap(rgb, 277 | // p.getPreviewSize().width, p.getPreviewSize().height, 278 | // Config.RGB_565); 279 | // 280 | // Matrix localMatrix = new Matrix(); 281 | // localMatrix.setRotate(90.0F); 282 | // localMatrix.preScale(0.75f, 0.75f); 283 | // Bitmap localBitmap2 = Bitmap.createBitmap(localBitmap1, 0, 0, 284 | // localBitmap1.getWidth(), localBitmap1.getHeight(), localMatrix, 285 | // true); 286 | // int w = localBitmap2.getWidth(); 287 | // int h = localBitmap2.getHeight(); 288 | // // Log.e(TAG,w+":"+h); 289 | // 290 | // // mOnDetectEndListener.onDetectEnd(localBitmap2); 291 | // 292 | // int[] pix = new int[w * h]; 293 | // localBitmap2.getPixels(pix, 0, w, 0, 0, w, h); 294 | // mCameraFaceFrameView.scaleFactorW = (float) localBitmap2.getWidth() 295 | // / (float) getMeasuredWidth(); 296 | // mCameraFaceFrameView.scaleFactorH = (float) localBitmap2.getHeight() 297 | // / (float) getMeasuredHeight(); 298 | // int[] faces = CameraManager.getInstance().detectFace(40, 40, pix, w, h); 299 | // 300 | // return faces; 301 | // } 302 | // 303 | // private void saveJPG(byte[] data) { 304 | // Camera camera = CameraManager.getInstance().getCamera(); 305 | // Camera.Parameters p = camera.getParameters(); 306 | // 307 | // File file = new File(Environment.getExternalStorageDirectory() 308 | // .getAbsolutePath() + "/xxxx.jpg"); 309 | // 310 | // YuvImage localYuvImage = new YuvImage(data, 17, 311 | // p.getPreviewSize().width, p.getPreviewSize().height, null); 312 | // ByteArrayOutputStream bos = new ByteArrayOutputStream(); 313 | // FileOutputStream outStream = null; 314 | // 315 | // try { 316 | // if (!file.exists()) 317 | // file.createNewFile(); 318 | // localYuvImage.compressToJpeg(new Rect(0, 0, 319 | // p.getPreviewSize().width, p.getPreviewSize().height), 100, 320 | // bos); 321 | // Bitmap localBitmap1 = BitmapFactory.decodeByteArray( 322 | // bos.toByteArray(), 0, bos.toByteArray().length); 323 | // bos.close(); 324 | // Matrix localMatrix = new Matrix(); 325 | // localMatrix.setRotate(90.0F + rotateAngle); 326 | // Bitmap localBitmap2 = Bitmap.createBitmap(localBitmap1, 0, 0, 327 | // localBitmap1.getWidth(), localBitmap1.getHeight(), 328 | // localMatrix, true); 329 | // int w = localBitmap2.getWidth(); 330 | // int h = localBitmap2.getHeight(); 331 | // Log.e(TAG, w + ":" + h); 332 | // 333 | // ByteArrayOutputStream bos2 = new ByteArrayOutputStream(); 334 | // localBitmap2.compress(Bitmap.CompressFormat.JPEG, 100, bos2); 335 | // mCameraFaceFrameView.scaleFactorW = (float) localBitmap2.getWidth() 336 | // / (float) getMeasuredWidth(); 337 | // mCameraFaceFrameView.scaleFactorH = (float) localBitmap2 338 | // .getHeight() / (float) getMeasuredHeight(); 339 | // outStream = new FileOutputStream(file); 340 | // outStream.write(bos2.toByteArray()); 341 | // outStream.close(); 342 | // localBitmap1.recycle(); 343 | // localBitmap2.recycle(); 344 | // 345 | // } catch (FileNotFoundException e) { 346 | // e.printStackTrace(); 347 | // } catch (IOException e) { 348 | // e.printStackTrace(); 349 | // } 350 | // } 351 | 352 | private OnDetectEndListener mOnDetectEndListener; 353 | 354 | public interface OnDetectEndListener { 355 | public void onDetectEnd(Bitmap bitmap); 356 | } 357 | 358 | public void setOnDetectEndListener(OnDetectEndListener listener) { 359 | mOnDetectEndListener = listener; 360 | } 361 | 362 | private void drawFaces(Face[] faces) { 363 | Message msg = new Message(); 364 | msg.obj = faces; 365 | mHandler.sendMessage(msg); 366 | } 367 | 368 | long time; 369 | 370 | private class CameraWorker implements Runnable { 371 | 372 | @Override 373 | public void run() { 374 | do { 375 | synchronized (syncObject) { 376 | try { 377 | while (!mCameraFrameReady && !mStopThread) { 378 | syncObject.wait(); 379 | } 380 | } catch (InterruptedException e) { 381 | e.printStackTrace(); 382 | } 383 | 384 | index++; 385 | if (index > 1) { 386 | index = 0; 387 | } 388 | } 389 | 390 | if (!mStopThread && mCameraFrameReady) { 391 | mCameraFrameReady = false; 392 | 393 | Camera camera = CameraManager.getInstance().getCamera(); 394 | Camera.Parameters p = camera.getParameters(); 395 | byte[] imageBytes = index == 0 ? mDatas2 : mDatas1; 396 | 397 | if(CameraManager.getInstance().nativeIsEnableAsyncDetect()==1){ 398 | if (!isDetecting) { 399 | isDetecting = true; 400 | new DetectWorker(imageBytes, p.getPreviewSize().width, 401 | p.getPreviewSize().height).start(); 402 | } 403 | 404 | Face[] faces = CameraManager.getInstance().trackingFace( 405 | imageBytes, p.getPreviewSize().width, 406 | p.getPreviewSize().height, -90); 407 | 408 | if (faces != null && faces.length != 0) { 409 | drawFaces(faces); 410 | } else { 411 | drawFaces(null); 412 | } 413 | }else{ 414 | Face[] faces = CameraManager.getInstance().findFaces(imageBytes, p.getPreviewSize().width, 415 | p.getPreviewSize().height, 416 | -90); 417 | if (faces != null && faces.length != 0) { 418 | drawFaces(faces); 419 | } else { 420 | drawFaces(null); 421 | } 422 | } 423 | 424 | 425 | 426 | 427 | 428 | Log.e(TAG, 429 | "Detect Time Interval:" 430 | + (System.currentTimeMillis() - time)); 431 | time = System.currentTimeMillis(); 432 | } 433 | } while (!mStopThread); 434 | Log.e(TAG, "Finish processing thread"); 435 | } 436 | } 437 | 438 | @Override 439 | public void onCallback(final RectF rect, final double clearFlag) { 440 | // TODO Auto-generated method stub 441 | mHandler.post(new Runnable() { 442 | 443 | @Override 444 | public void run() { 445 | // TODO Auto-generated method stub 446 | ((HomeActivity) mContext).textView.setText("" + clearFlag); 447 | } 448 | }); 449 | } 450 | 451 | boolean isDetecting; 452 | private class DetectWorker extends Thread { 453 | 454 | byte[] imageBytes; 455 | int width; 456 | int height; 457 | 458 | public DetectWorker(byte[] datas, int width, int height) { 459 | this.imageBytes = datas; 460 | this.width = width; 461 | this.height = height; 462 | } 463 | 464 | @Override 465 | public void run() { 466 | CameraManager.getInstance().findFaces(imageBytes, width, height, 467 | -90); 468 | isDetecting = false; 469 | } 470 | }; 471 | } 472 | -------------------------------------------------------------------------------- /FaceDetectAndTracking/src/com/smartcamera/widget/XCameraView.java: -------------------------------------------------------------------------------- 1 | package com.smartcamera.widget; 2 | import java.util.Collections; 3 | import java.util.List; 4 | 5 | import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame; 6 | import org.opencv.android.Utils; 7 | import org.opencv.core.CvType; 8 | import org.opencv.core.Mat; 9 | import org.opencv.imgproc.Imgproc; 10 | 11 | import android.content.Context; 12 | import android.graphics.Bitmap; 13 | import android.graphics.Canvas; 14 | import android.graphics.ImageFormat; 15 | import android.graphics.Rect; 16 | import android.graphics.SurfaceTexture; 17 | import android.hardware.Camera; 18 | import android.hardware.Camera.PreviewCallback; 19 | import android.hardware.Camera.Size; 20 | import android.os.Build; 21 | import android.util.AttributeSet; 22 | import android.util.Log; 23 | import android.view.SurfaceHolder; 24 | import android.view.SurfaceView; 25 | 26 | import com.smartcamera.core.CameraManager; 27 | import com.smartcamera.widget.CameraView.ResolutionComparator; 28 | 29 | 30 | public class XCameraView extends SurfaceView implements PreviewCallback,SurfaceHolder.Callback{ 31 | public static final String TAG = "XCameraView"; 32 | 33 | private static final int MAGIC_TEXTURE_ID = 10; 34 | 35 | private Bitmap mCacheBitmap; 36 | private byte mBuffer[]; 37 | private int mFrameWidth,mFrameHeight; 38 | private Mat[] mFrameChain; 39 | protected JavaCameraFrame[] mCameraFrame; 40 | private SurfaceTexture mSurfaceTexture; 41 | private int mChainIdx = 0; 42 | private boolean mStopThread; 43 | private boolean mCameraFrameReady; 44 | private Thread mThread; 45 | private Object syncObject = new Object(); 46 | 47 | public XCameraView(Context context, AttributeSet attrs) { 48 | super(context, attrs); 49 | // TODO Auto-generated constructor stub 50 | } 51 | 52 | private void initCamera(){ 53 | getHolder().addCallback(this); 54 | Camera camera = CameraManager.getInstance().open(0); 55 | 56 | try { 57 | Camera.Parameters params = camera.getParameters(); 58 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && !android.os.Build.MODEL.equals("GT-I9100")) 59 | params.setRecordingHint(true); 60 | 61 | //set camera preview size 62 | List resolutionList = params 63 | .getSupportedPreviewSizes(); 64 | if (resolutionList != null && resolutionList.size() > 0) { 65 | Collections.sort(resolutionList, new ResolutionComparator()); 66 | Camera.Size previewSize = null; 67 | int maxSize = 0; 68 | for (int i = 0; i < resolutionList.size(); i++) { 69 | Size size = resolutionList.get(i); 70 | 71 | if(size.width%160==0&&size.height%160==0){ 72 | if(size.width*size.height>maxSize){ 73 | maxSize = size.width*size.height; 74 | previewSize = size; 75 | } 76 | } 77 | } 78 | 79 | if(null!=previewSize){ 80 | params.setPreviewSize(previewSize.width,previewSize.height); 81 | } 82 | 83 | } 84 | 85 | Log.e(TAG,params.getPreviewSize().width+":"+params.getPreviewSize().height); 86 | 87 | //set camera preview format 88 | params.setPreviewFormat(ImageFormat.NV21); 89 | 90 | //set camera focus mode 91 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) { 92 | List focusModes = params.getSupportedFocusModes(); 93 | if (focusModes != null) { 94 | Log.e("video", Build.MODEL); 95 | if (((Build.MODEL.startsWith("GT-I950")) 96 | || (Build.MODEL.endsWith("SCH-I959")) || (Build.MODEL 97 | .endsWith("MEIZU MX3"))) 98 | && focusModes 99 | .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { 100 | 101 | params 102 | .setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 103 | } else if (focusModes 104 | .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { 105 | params 106 | .setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); 107 | } else 108 | params.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED); 109 | } 110 | } 111 | 112 | camera.setParameters(params); 113 | 114 | mFrameWidth = params.getPreviewSize().width; 115 | mFrameHeight = params.getPreviewSize().height; 116 | 117 | int size = mFrameWidth * mFrameHeight; 118 | size = size * ImageFormat.getBitsPerPixel(params.getPreviewFormat()) / 8; 119 | mBuffer = new byte[size]; 120 | camera.addCallbackBuffer(mBuffer); 121 | camera.setPreviewCallbackWithBuffer(this); 122 | 123 | mFrameChain = new Mat[2]; 124 | mFrameChain[0] = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1); 125 | mFrameChain[1] = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1); 126 | mCacheBitmap = Bitmap.createBitmap(mFrameWidth, mFrameHeight, Bitmap.Config.ARGB_8888); 127 | 128 | mCameraFrame = new JavaCameraFrame[2]; 129 | mCameraFrame[0] = new JavaCameraFrame(mFrameChain[0], mFrameWidth, mFrameHeight); 130 | mCameraFrame[1] = new JavaCameraFrame(mFrameChain[1], mFrameWidth, mFrameHeight); 131 | 132 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 133 | Log.e(TAG, "startPreview"); 134 | mSurfaceTexture = new SurfaceTexture(MAGIC_TEXTURE_ID); 135 | camera.setPreviewTexture(mSurfaceTexture); 136 | } else 137 | camera.setPreviewDisplay(null); 138 | 139 | Log.e(TAG, "startPreview"); 140 | camera.startPreview(); 141 | } catch (Exception e) { 142 | e.printStackTrace(); 143 | } 144 | } 145 | 146 | 147 | public boolean connectCamera() { 148 | Log.e(TAG, "Connecting to camera"); 149 | initCamera(); 150 | 151 | mCameraFrameReady = false; 152 | 153 | Log.e(TAG, "Starting processing thread"); 154 | mStopThread = false; 155 | mThread = new Thread(new CameraWorker()); 156 | mThread.start(); 157 | 158 | return true; 159 | } 160 | 161 | public void disconnectCamera() { 162 | Log.e(TAG, "Disconnecting from camera"); 163 | try { 164 | mStopThread = true; 165 | Log.e(TAG, "Notify thread"); 166 | synchronized (syncObject) { 167 | syncObject.notify(); 168 | } 169 | Log.e(TAG, "Wating for thread"); 170 | if (mThread != null) 171 | mThread.join(); 172 | } catch (InterruptedException e) { 173 | e.printStackTrace(); 174 | } finally { 175 | mThread = null; 176 | } 177 | 178 | /* Now release camera */ 179 | CameraManager.getInstance().closeCamera(); 180 | 181 | synchronized (syncObject) { 182 | if (mFrameChain != null) { 183 | mFrameChain[0].release(); 184 | mFrameChain[1].release(); 185 | } 186 | if (mCameraFrame != null) { 187 | mCameraFrame[0].release(); 188 | mCameraFrame[1].release(); 189 | } 190 | } 191 | 192 | mCameraFrameReady = false; 193 | 194 | if (mCacheBitmap != null) { 195 | mCacheBitmap.recycle(); 196 | } 197 | 198 | } 199 | 200 | @Override 201 | public void onPreviewFrame(byte[] data, Camera camera) { 202 | // TODO Auto-generated method stub 203 | //Log.e(TAG, "Preview Frame received. Frame size: " + data.length); 204 | Log.e(TAG,"Detect Time Interval:"+(System.currentTimeMillis()-time)); 205 | time = System.currentTimeMillis(); 206 | synchronized (syncObject) { 207 | mFrameChain[mChainIdx].put(0, 0, data); 208 | mCameraFrameReady = true; 209 | syncObject.notify(); 210 | } 211 | 212 | if (camera != null) 213 | camera.addCallbackBuffer(mBuffer); 214 | } 215 | 216 | @Override 217 | public void surfaceCreated(SurfaceHolder holder) { 218 | // TODO Auto-generated method stub 219 | 220 | } 221 | 222 | @Override 223 | public void surfaceChanged(SurfaceHolder holder, int format, int width, 224 | int height) { 225 | // TODO Auto-generated method stub 226 | 227 | } 228 | 229 | @Override 230 | public void surfaceDestroyed(SurfaceHolder holder) { 231 | // TODO Auto-generated method stub 232 | 233 | } 234 | 235 | private class JavaCameraFrame implements CvCameraViewFrame { 236 | @Override 237 | public Mat gray() { 238 | return mYuvFrameData.submat(0, mHeight, 0, mWidth); 239 | } 240 | 241 | @Override 242 | public Mat rgba() { 243 | Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4); 244 | return mRgba; 245 | } 246 | 247 | public JavaCameraFrame(Mat Yuv420sp, int width, int height) { 248 | super(); 249 | mWidth = width; 250 | mHeight = height; 251 | mYuvFrameData = Yuv420sp; 252 | mRgba = new Mat(); 253 | } 254 | 255 | public void release() { 256 | mRgba.release(); 257 | } 258 | 259 | private Mat mYuvFrameData; 260 | private Mat mRgba; 261 | private int mWidth; 262 | private int mHeight; 263 | }; 264 | 265 | private class CameraWorker implements Runnable { 266 | 267 | @Override 268 | public void run() { 269 | do { 270 | synchronized (syncObject) { 271 | try { 272 | while (!mCameraFrameReady && !mStopThread) { 273 | syncObject.wait(); 274 | } 275 | } catch (InterruptedException e) { 276 | e.printStackTrace(); 277 | } 278 | if (mCameraFrameReady) 279 | mChainIdx = 1 - mChainIdx; 280 | } 281 | 282 | if (!mStopThread && mCameraFrameReady) { 283 | mCameraFrameReady = false; 284 | if (!mFrameChain[1 - mChainIdx].empty()){ 285 | deliverAndDrawFrame(mCameraFrame[1 - mChainIdx]); 286 | } 287 | } 288 | } while (!mStopThread); 289 | Log.e(TAG, "Finish processing thread"); 290 | } 291 | } 292 | 293 | long time; 294 | private void deliverAndDrawFrame(CvCameraViewFrame frame) { 295 | Mat modified; 296 | 297 | if (mListener != null) { 298 | modified = mListener.onCameraFrame(frame); 299 | } else { 300 | modified = frame.rgba(); 301 | } 302 | 303 | boolean bmpValid = true; 304 | if (modified != null) { 305 | try { 306 | Utils.matToBitmap(modified, mCacheBitmap); 307 | } catch(Exception e) { 308 | Log.e(TAG, "Mat type: " + modified); 309 | Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight()); 310 | Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage()); 311 | bmpValid = false; 312 | } 313 | } 314 | 315 | if (bmpValid && mCacheBitmap != null) { 316 | Canvas canvas = getHolder().lockCanvas(); 317 | if (canvas != null) { 318 | canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR); 319 | 320 | canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()), 321 | new Rect(0, 322 | 0, 323 | canvas.getWidth(), 324 | canvas.getHeight()), null); 325 | 326 | getHolder().unlockCanvasAndPost(canvas); 327 | } 328 | } 329 | 330 | // Log.e(TAG,(System.currentTimeMillis()-time)+""); 331 | // time = System.currentTimeMillis(); 332 | } 333 | 334 | private CvCameraViewListener2 mListener; 335 | 336 | public void setCvCameraViewListener(CvCameraViewListener2 listener) { 337 | mListener = listener; 338 | } 339 | 340 | public interface CvCameraViewListener2 { 341 | public Mat onCameraFrame(CvCameraViewFrame inputFrame); 342 | }; 343 | } 344 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android-FaceDetectAndTracking 2 | 3 | ## Sample Application 4 | Click to Download the simple apk 6 | 7 | ##Other 8 | 9 | ##2015-07-03 10 | 因为扫描人脸需要正脸扫描 所以在jni对图片进行了90度旋转再扫描人脸,而camshit追踪不依赖于物体的形状变化所以 11 | 在追踪时取消图片旋转,最终对Rect坐标旋转,速度按我的测试机从130ms左右提高到60ms左右,差不多一倍的速度,丢失的情况也好一点了. 12 | 13 | 14 | ##2015-07-08 15 | 为了更远距离精准扫描人脸 摄像头预览大小设置成最大,以我的测试机为例是1280x960,而camshift 不依赖物体大小变化所以在追踪时对图片进行压缩640x480(太小也不行,容易变形),速度从60ms每次提高在35ms左右, 16 | 另外增加丢失判断追踪区域大小大于初始化大小1.5倍或者小于初始化大小0.25视为严重变形判断为丢失,快速移动下丢失情况又好一点了,但复杂背景色差变形依然存在. 17 | 18 | 19 | ##2015-07-11 20 | 增加多人追踪,异步检测,camshift追踪区域从整个脸部缩小范围锁定额头,复杂背景下更容易锁定不易变形,但多个人追踪导致速度下降了一些。 21 | 22 | -------------------------------------------------------------------------------- /apk/FaceDetectAndTracking.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guojunyi/Android-FaceDetectAndTracking/d7f0a899ae54dfe74a499a97f7b14182ac53da1e/apk/FaceDetectAndTracking.apk --------------------------------------------------------------------------------