}
})
.show();
}
public void showMessage(String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message)
.setPositiveButton(“Ok”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setCancelable(false) // cancel with button only
.show();
}
private void resetTrackerParameters() {
int errpos[] = new int[1];
FSDK.SetTrackerMultipleParameters(mDraw.mTracker, “ContinuousVideoFeed=true;FacialFeatureJitterSuppression=0;RecognitionPrecision=1;Threshold=0.996;Threshold2=0.9995;ThresholdFeed=0.97;MemoryLimit=2000;HandleArbitraryRotations=false;DetermineFaceRotationAngle=false;InternalResizeWidth=70;FaceDetectionThreshold=3;”, errpos);
if (errpos[0] != 0) {
showErrorAndClose(“Error setting tracker parameters, position”, errpos[0]);
}
}
/**
- Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sDensity = getResources().getDisplayMetrics().scaledDensity;
int res = FSDK.ActivateLibrary("******");
if (res != FSDK.FSDKE_OK) {
mIsFailed = true;
showErrorAndClose(“FaceSDK activation failed”, res);
} else {
FSDK.Initialize();
// Hide the window title (it is done in manifest too)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Lock orientation
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// Camera layer and drawing layer
mDraw = new ProcessImageAndDrawResults(this);
mPreview = new Preview(this, mDraw);
mDraw.mTracker = new HTracker();
String templatePath = this.getApplicationInfo().dataDir + “/” + database;
if (FSDK.FSDKE_OK != FSDK.LoadTrackerMemoryFromFile(mDraw.mTracker, templatePath)) {
res = FSDK.CreateTracker(mDraw.mTracker);
if (FSDK.FSDKE_OK != res) {
showErrorAndClose(“Error creating tracker”, res);
}
}
resetTrackerParameters();
this.getWindow().setBackgroundDrawable(new ColorDrawable()); //black background
setContentView(mPreview); //creates MainActivity contents
addContentView(mDraw, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
// Menu
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View buttons = inflater.inflate(R.layout.bottom_menu, null);
buttons.findViewById(R.id.helpButton).setOnClickListener(this);
buttons.findViewById(R.id.clearButton).setOnClickListener(this);
addContentView(buttons, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.helpButton) {
showMessage(help_text);
} else if (view.getId() == R.id.clearButton) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(“Are you sure to clear the memory?”)
.setPositiveButton(“Ok”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int j) {
pauseProcessingFrames();
FSDK.ClearTracker(mDraw.mTracker);
resetTrackerParameters();
resumeProcessingFrames();
}
})
.setNegativeButton(“Cancel”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int j) {
}
})
.setCancelable(false) // cancel with button only
.show();
}
}
@Override
public void onPause() {
super.onPause();
pauseProcessingFrames();
String templatePath = this.getApplicationInfo().dataDir + “/” + database;
FSDK.SaveTrackerMemoryToFile(mDraw.mTracker, templatePath);
}
@Override
public void onResume() {
super.onResume();
if (mIsFailed)
return;
resumeProcessingFrames();
}
private void pauseProcessingFrames() {
mDraw.mStopping = 1;
// It is essential to limit wait time, because mStopped will not be set to 0, if no frames are feeded to mDraw
for (int i = 0; i < 100; ++i) {
if (mDraw.mStopped != 0) break;
try {
Thread.sleep(10);
} catch (Exception ex) {
}
}
}
private void resumeProcessingFrames() {
mDraw.mStopped = 0;
mDraw.mStopping = 0;
}
}
class FaceRectangle {
public int x1, y1, x2, y2;
}
// Draw graphics on top of the video
class ProcessImageAndDrawResults extends View {
public HTracker mTracker;
final int MAX_FACES = 5;
final FaceRectangle[] mFacePositions = new FaceRectangle[MAX_FACES];
final long[] mIDs = new long[MAX_FACES];
final Lock faceLock = new ReentrantLock();
int mTouchedIndex;
long mTouchedID;
int mStopping;
int mStopped;
Context mContext;
Paint mPaintGreen, mPaintBlue, mPaintBlueTransparent;
byte[] mYUVData;
byte[] mRGBData;
int mImageWidth, mImageHeight;
boolean first_frame_saved;
boolean rotated;
int GetFaceFrame(FSDK.FSDK_Features Features, FaceRectangle fr) {
if (Features == null || fr == null)
return FSDK.FSDKE_INVALID_ARGUMENT;
float u1 = Features.features[0].x;
float v1 = Features.features[0].y;
float u2 = Features.features[1].x;
float v2 = Features.features[1].y;
float xc = (u1 + u2) / 2;
float yc = (v1 + v2) / 2;
int w = (int) Math.pow((u2 - u1) * (u2 - u1) + (v2 - v1) * (v2 - v1), 0.5);
fr.x1 = (int) (xc - w * 1.6 * 0.9);
fr.y1 = (int) (yc - w * 1.1 * 0.9);
fr.x2 = (int) (xc + w * 1.6 * 0.9);
fr.y2 = (int) (yc + w * 2.1 * 0.9);
if (fr.x2 - fr.x1 > fr.y2 - fr.y1) {
fr.x2 = fr.x1 + fr.y2 - fr.y1;
} else {
fr.y2 = fr.y1 + fr.x2 - fr.x1;
}
return 0;
}
public ProcessImageAndDrawResults(Context context) {
super(context);
mTouchedIndex = -1;
mStopping = 0;
mStopped = 0;
rotated = false;
mContext = context;
mPaintGreen = new Paint();
mPaintGreen.setStyle(Paint.Style.FILL);
mPaintGreen.setColor(Color.GREEN);
mPaintGreen.setTextSize(18 * MainActivity.sDensity);
mPaintGreen.setTextAlign(Align.CENTER);
mPaintBlue = new Paint();
mPaintBlue.setStyle(Paint.Style.FILL);
mPaintBlue.setColor(Color.BLUE);
mPaintBlue.setTextSize(18 * MainActivity.sDensity);
mPaintBlue.setTextAlign(Align.CENTER);
mPaintBlueTransparent = new Paint();
mPaintBlueTransparent.setStyle(Paint.Style.STROKE);
mPaintBlueTransparent.setStrokeWidth(2);
mPaintBlueTransparent.setColor(Color.BLUE);
mPaintBlueTransparent.setTextSize(25);
//mBitmap = null;
mYUVData = null;
mRGBData = null;
first_frame_saved = false;
}
@Override
protected void onDraw(Canvas canvas) {
if (mStopping == 1) {
mStopped = 1;
super.onDraw(canvas);
return;
}
if (mYUVData == null || mTouchedIndex != -1) {
super.onDraw(canvas);
return; //nothing to process or name is being entered now
}
int canvasWidth = canvas.getWidth();
//int canvasHeight = canvas.getHeight();
// Convert from YUV to RGB
decodeYUV420SP(mRGBData, mYUVData, mImageWidth, mImageHeight);
// Load image to FaceSDK
FSDK.HImage Image = new FSDK.HImage();
FSDK.FSDK_IMAGEMODE imagemode = new FSDK.FSDK_IMAGEMODE();
imagemode.mode = FSDK.FSDK_IMAGEMODE.FSDK_IMAGE_COLOR_24BIT;
FSDK.LoadImageFromBuffer(Image, mRGBData, mImageWidth, mImageHeight, mImageWidth * 3, imagemode);
FSDK.MirrorImage(Image, false);
FSDK.HImage RotatedImage = new FSDK.HImage();
FSDK.CreateEmptyImage(RotatedImage);
//it is necessary to work with local variables (onDraw called not the time when mImageWidth,… being reassigned, so swapping mImageWidth and mImageHeight may be not safe)
int ImageWidth = mImageWidth;
//int ImageHeight = mImageHeight;
if (rotated) {
ImageWidth = mImageHeight;
//ImageHeight = mImageWidth;
FSDK.RotateImage90(Image, -1, RotatedImage);
} else {
FSDK.CopyImage(Image, RotatedImage);
}
FSDK.FreeImage(Image);
// Save first frame to gallery to debug (e.g. rotation angle)
/*
if (!first_frame_saved) {
first_frame_saved = true;
String galleryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath();
FSDK.SaveImageToFile(RotatedImage, galleryPath + “/first_frame.jpg”); //frame is rotated!
}
*/
long IDs[] = new long[MAX_FACES];
long face_count[] = new long[1];
FSDK.FeedFrame(mTracker, 0, RotatedImage, face_count, IDs);
FSDK.FreeImage(RotatedImage);
faceLock.lock();
for (int i = 0; i < MAX_FACES; ++i) {
mFacePositions[i] = new FaceRectangle();
mFacePositions[i].x1 = 0;
mFacePositions[i].y1 = 0;
mFacePositions[i].x2 = 0;
mFacePositions[i].y2 = 0;
mIDs[i] = IDs[i];
}
float ratio = (canvasWidth * 1.0f) / ImageWidth;
for (int i = 0; i < (int) face_count[0]; ++i) {
FSDK.FSDK_Features Eyes = new FSDK.FSDK_Features();
FSDK.GetTrackerEyes(mTracker, 0, mIDs[i], Eyes);
GetFaceFrame(Eyes, mFacePositions[i]);
mFacePositions[i].x1 *= ratio;
mFacePositions[i].y1 *= ratio;
mFacePositions[i].x2 *= ratio;
mFacePositions[i].y2 *= ratio;
}
faceLock.unlock();
int shift = (int) (22 * MainActivity.sDensity);
// Mark and name faces
for (int i = 0; i < face_count[0]; ++i) {
canvas.drawRect(mFacePositions[i].x1, mFacePositions[i].y1, mFacePositions[i].x2, mFacePositions[i].y2, mPaintBlueTransparent);
boolean named = false;
if (IDs[i] != -1) {
String names[] = new String[1];
FSDK.GetAllNames(mTracker, IDs[i], names, 1024);
if (names[0] != null && names[0].length() > 0) {
canvas.drawText(names[0], (mFacePositions[i].x1 + mFacePositions[i].x2) / 2, mFacePositions[i].y2 + shift, mPaintBlue);
named = true;
}
}
if (!named) {
canvas.drawText(“Tap to name”, (mFacePositions[i].x1 + mFacePositions[i].x2) / 2, mFacePositions[i].y2 + shift, mPaintGreen);
}
}
总结
学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!
最后如何才能让我们在面试中对答如流呢?
答案当然是平时在工作或者学习中多提升自身实力的啦,那如何才能正确的学习,有方向的学习呢?有没有免费资料可以借鉴?为此我整理了一份Android学习资料路线:
这里是一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套BAT大厂面试资料专题包,在这里免费分享给大家,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家。需要的小伙伴们可以点击我的GitHub获取免费领取方式
好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以去我的主页加一下技术群。来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。
最后,祝愿即将跳槽和已经开始求职的大家都能找到一份好的工作!
的学习呢?有没有免费资料可以借鉴?为此我整理了一份Android学习资料路线:
[外链图片转存中…(img-NEeOgshe-1646549845312)]
这里是一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套BAT大厂面试资料专题包,在这里免费分享给大家,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家。需要的小伙伴们可以点击我的GitHub获取免费领取方式
[外链图片转存中…(img-cpcy8J4L-1646549845313)]
好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以去我的主页加一下技术群。来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。
最后,祝愿即将跳槽和已经开始求职的大家都能找到一份好的工作!