.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);
}
}
super.onDraw(canvas);
} // end onDraw method
@Override
public boolean onTouchEvent(MotionEvent event) { //NOTE: the method can be implemented in Preview class
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int x = (int) event.getX();
int y = (int) event.getY();
faceLock.lock();
FaceRectangle rects[] = new FaceRectangle[MAX_FACES];
long IDs[] = new long[MAX_FACES];
for (int i = 0; i < MAX_FACES; ++i) {
rects[i] = new FaceRectangle();
rects[i].x1 = mFacePositions[i].x1;
rects[i].y1 = mFacePositions[i].y1;
rects[i].x2 = mFacePositions[i].x2;
rects[i].y2 = mFacePositions[i].y2;
IDs[i] = mIDs[i];
}
faceLock.unlock();
for (int i = 0; i < MAX_FACES; ++i) {
if (rects[i] != null && rects[i].x1 <= x && x <= rects[i].x2 && rects[i].y1 <= y && y <= rects[i].y2 + 30) {
mTouchedID = IDs[i];
mTouchedIndex = i;
// requesting name on tapping the face
final EditText input = new EditText(mContext);
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(“Enter person’s name”)
.setView(input)
.setPositiveButton(“Ok”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int j) {
FSDK.LockID(mTracker, mTouchedID);
String userName = input.getText().toString();
FSDK.SetName(mTracker, mTouchedID, userName);
if (userName.length() <= 0)
FSDK.PurgeID(mTracker, mTouchedID);
FSDK.UnlockID(mTracker, mTouchedID);
mTouchedIndex = -1;
}
})
.setNegativeButton(“Cancel”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int j) {
mTouchedIndex = -1;
}
})
.setCancelable(false) // cancel with button only
.show();
break;
}
}
}
return true;
}
static public void decodeYUV420SP(byte[] rgb, byte[] yuv420sp, int width, int height) {
final int frameSize = width * height;
int yp = 0;
for (int j = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0) y = 0;
if ((i & 1) == 0) {
最后
上面这些公司都是时下最受欢迎的互联网大厂,他们的职级、薪资、福利也都讲的差不多了,相信大家都是有梦想和野心的人,心里多少应该都有些想法。
也相信很多人也都在为即将到来的金九银十做准备,也有不少人的目标都是这些公司。
我这边有不少朋友都在这些厂工作,其中也有很多人担任过面试官,上面的资料也差不多都是从朋友那边打探来的。除了上面的信息,我这边还有这些大厂近年来的面试真题及解析,以及一些朋友出于兴趣和热爱一起整理的Android时下热门知识点的学习资料。
部分文件:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
- width, u = 0, v = 0;
for (int i = 0; i < width; i++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0) y = 0;
if ((i & 1) == 0) {
最后
上面这些公司都是时下最受欢迎的互联网大厂,他们的职级、薪资、福利也都讲的差不多了,相信大家都是有梦想和野心的人,心里多少应该都有些想法。
也相信很多人也都在为即将到来的金九银十做准备,也有不少人的目标都是这些公司。
我这边有不少朋友都在这些厂工作,其中也有很多人担任过面试官,上面的资料也差不多都是从朋友那边打探来的。除了上面的信息,我这边还有这些大厂近年来的面试真题及解析,以及一些朋友出于兴趣和热爱一起整理的Android时下热门知识点的学习资料。
部分文件:
[外链图片转存中…(img-CadcsP3r-1714302930964)]
[外链图片转存中…(img-KFpPdAoZ-1714302930965)]
[外链图片转存中…(img-MLzSy1uH-1714302930966)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!