├── 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
--------------------------------------------------------------------------------