| | |
| | | package cn.com.basic.face.base; |
| | | |
| | | import android.app.AlertDialog; |
| | | import android.content.Context; |
| | | import android.content.Intent; |
| | | import android.content.DialogInterface; |
| | | import android.content.pm.ActivityInfo; |
| | | import android.content.res.Configuration; |
| | | import android.database.sqlite.SQLiteDatabase; |
| | | import android.graphics.Bitmap; |
| | | import android.graphics.BitmapFactory; |
| | | import android.graphics.Canvas; |
| | | import android.graphics.Color; |
| | | import android.graphics.Paint; |
| | | import android.graphics.Paint.Align; |
| | | import android.graphics.drawable.ColorDrawable; |
| | | import android.hardware.Camera; |
| | | import android.hardware.Camera.PreviewCallback; |
| | | import android.hardware.Camera.Size; |
| | | import android.os.Bundle; |
| | | import android.os.Handler; |
| | | import android.support.design.widget.TabLayout; |
| | | import android.support.v4.app.Fragment; |
| | | import android.support.v4.app.FragmentManager; |
| | | import android.support.v4.app.FragmentPagerAdapter; |
| | | import android.support.v4.view.ViewPager; |
| | | import android.os.Bundle; |
| | | import android.view.LayoutInflater; |
| | | import android.view.MotionEvent; |
| | | import android.view.SurfaceHolder; |
| | | import android.view.SurfaceView; |
| | | import android.view.View; |
| | | import android.view.Window; |
| | | import android.view.ViewGroup.LayoutParams; |
| | | import android.view.WindowManager; |
| | | import android.widget.EditText; |
| | | import android.widget.ImageView; |
| | | import android.widget.LinearLayout; |
| | | import android.widget.TextView; |
| | | import android.widget.Toast; |
| | | |
| | | import com.awsle.aibatis.client.SqlMapClientBuilder; |
| | | import com.bsk.zhangbo.demoforbsk.R; |
| | | import cn.com.basic.face.fragment.SurveillanceFragment; |
| | | import cn.com.basic.face.util.TabNameUtil; |
| | | import com.luxand.FSDK; |
| | | import com.luxand.FSDK.HTracker; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileNotFoundException; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.concurrent.locks.Lock; |
| | | import java.util.concurrent.locks.ReentrantLock; |
| | | |
| | | import cn.com.basic.face.dialog.AttenderRegisterSelectPhotoDialog; |
| | | import cn.com.basic.face.dialog.AttenderRegisterUploadPhotoDialog; |
| | | import cn.com.basic.face.dialog.VisitorRegisterSelectPhotoDialog; |
| | | import cn.com.basic.face.dialog.VisitorRegisterUploadPhotoDialog; |
| | | import cn.com.basic.face.discern.common.CommonVariables; |
| | | import cn.com.basic.face.discern.query.item.SurveillanceQueryItem; |
| | | import cn.com.basic.face.fragment.AttendanceFragment; |
| | | import cn.com.basic.face.fragment.CheckInFragment; |
| | | import cn.com.basic.face.fragment.DeviceFragment; |
| | | import cn.com.basic.face.fragment.PhoneCallFragment; |
| | | import cn.com.basic.face.fragment.RegisterFragment; |
| | | import cn.com.basic.face.fragment.SurveillanceFragment; |
| | | import cn.com.basic.face.fragment.VisitFragment; |
| | | import cn.com.basic.face.fragment.VisitorRegisterFragment; |
| | | import cn.com.basic.face.service.DeviceMng; |
| | | import cn.com.basic.face.service.InternetAccessThread; |
| | | import cn.com.basic.face.service.SurveillanceMng; |
| | | import cn.com.basic.face.service.sqlite.SurveillanceDao; |
| | | import cn.com.basic.face.service.sqlite.TestDao; |
| | | import cn.com.basic.face.service.sync.up.BaseSync; |
| | | import cn.com.basic.face.util.FileUtil; |
| | | import cn.com.basic.face.util.NativeImg; |
| | | import cn.com.basic.face.util.TabNameUtil; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | | import java.io.InputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | public class MainActivity extends BaseActivity { |
| | | public class MainActivity extends BaseActivity implements View.OnClickListener{ |
| | | |
| | | private static MainActivity instance; |
| | | |
| | | private static TabLayout mTabLayout; |
| | | private static ViewPager mViewPager; |
| | | public static ViewPager mViewPager; |
| | | public SQLiteDatabase db; |
| | | private int internetAccessible = CommonVariables.InternetAccess.INTERNET_NOT_INITIALIZE; |
| | | |
| | | public int getInternetAccessible() { |
| | | return internetAccessible; |
| | | } |
| | | |
| | | public void setInternetAccessible(int internetAccessible) { |
| | | this.internetAccessible = internetAccessible; |
| | | } |
| | | |
| | | public static void selectPage(int pageNum) { |
| | | mTabLayout.getTabAt(pageNum).select(); |
| | |
| | | mViewPager = (ViewPager) findViewById(R.id.viewpager); |
| | | mTabLayout.setTabGravity(TabLayout.GRAVITY_FILL); |
| | | instance = this; |
| | | internetAccessThread.start(); |
| | | } |
| | | |
| | | public MyFragmentPagerAdapter myFragmentPagerAdapter; |
| | | |
| | | @Override |
| | | public void initData() { |
| | | List<String> tabNamesList = Arrays.asList(TabNameUtil.tabNames); |
| | | int[] tabIcons = TabNameUtil.tabIcons; |
| | | MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),MainActivity.this); |
| | | myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),MainActivity.this); |
| | | myFragmentPagerAdapter.addFragment(SurveillanceFragment.getInstance(), tabNamesList.get(0),tabIcons[0]); |
| | | myFragmentPagerAdapter.addFragment(RegisterFragment.getInstance(), tabNamesList.get(1),tabIcons[1]); |
| | | myFragmentPagerAdapter.addFragment(VisitorRegisterFragment.getInstance(), tabNamesList.get(1),tabIcons[1]); |
| | | // myFragmentPagerAdapter.addFragment(AttenderRegisterFragment.getInstance(), tabNamesList.get(1),tabIcons[1]); |
| | | // myFragmentPagerAdapter.addFragment(RegisterFragment.getInstance(), tabNamesList.get(1),tabIcons[1]); |
| | | myFragmentPagerAdapter.addFragment(CheckInFragment.getInstance(), tabNamesList.get(2),tabIcons[2]); |
| | | myFragmentPagerAdapter.addFragment(PhoneCallFragment.getInstance(), tabNamesList.get(3),tabIcons[3]); |
| | | myFragmentPagerAdapter.addFragment(VisitFragment.getInstance(), tabNamesList.get(4),tabIcons[4]); |
| | |
| | | tab.getCustomView().setSelected(true); |
| | | } |
| | | } |
| | | myThread = new MyThread(); |
| | | myThread.start(); |
| | | |
| | | if (CommonVariables.ID_CARD) { |
| | | myThread = new MyThread(); |
| | | myThread.start(); |
| | | } |
| | | // initSqlMap(); |
| | | } |
| | | |
| | | public static MainActivity getInstance() { |
| | |
| | | mFragments.add(fragment); |
| | | mFragmentTitles.add(title); |
| | | mFragmentIcons.add(drawable); |
| | | } |
| | | |
| | | public void setFragment(int index, Fragment fragment) { |
| | | mFragments.remove(index); |
| | | mFragments.add(index, fragment); |
| | | notifyDataSetChanged(); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | return true; |
| | | } |
| | | ///////////////////////////// |
| | | |
| | | /** |
| | | * 初始化sqlMap |
| | | */ |
| | | private void initSqlMap() { |
| | | Config.sqlMap = SqlMapClientBuilder.buildSqlMapClient(this.getClass().getResourceAsStream("/assets/config/SqlMapConfig.xml")).init(this); |
| | | } |
| | | /** |
| | | * 初始化数据 |
| | | */ |
| | | private void initDb() { |
| | | InputStream dbIn = getClass().getResourceAsStream(Config.DB); |
| | | FileOutputStream out = null; |
| | | File z = null; |
| | | try { |
| | | byte[] bytes = new byte[1024]; |
| | | z = new File(Config.APPDBPATH); |
| | | if(!z.exists()){ |
| | | z.mkdirs(); |
| | | } |
| | | //判断数据库是否存在 |
| | | z = new File(Config.APPDB); |
| | | if (!z.exists()) { |
| | | out = new FileOutputStream(z); |
| | | int len = 0; |
| | | while((len = dbIn.read(bytes))!= -1){ |
| | | out.write(bytes,0,len); |
| | | } |
| | | } |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | try { |
| | | if (out != null) |
| | | out.close(); |
| | | if (dbIn != null) |
| | | dbIn.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | try { |
| | | //对数据库文件权限 |
| | | Runtime.getRuntime().exec("chmod 7755 " + z.toString()); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | //Log.d(Config.APPTAG, "初始化数据完成!"); |
| | | } |
| | | |
| | | //////////////////////////////////////////////////////// |
| | | private boolean mIsFailed = false; |
| | | public Preview mPreview; |
| | | public ProcessImageAndDrawResults mDraw; |
| | | private final String database = "Memory50.dat"; |
| | | private final String help_text = "help"; |
| | | |
| | | public static float sDensity = 1.0f; |
| | | |
| | | InternetAccessThread internetAccessThread = new InternetAccessThread(); |
| | | |
| | | @Override |
| | | public void onCreate(Bundle savedInstanceState) { |
| | | super.onCreate(savedInstanceState); |
| | | initDb(); |
| | | db=openOrCreateDatabase("/data/data/com.bsk.zhangbo.demoforbsk/databases/aibatis_test_db", Context.MODE_PRIVATE, null); |
| | | TestDao.getInstance().test(); |
| | | DeviceMng.getInstance().findDevice(); |
| | | if (CommonVariables.FACE_SERVER) { |
| | | sDensity = getResources().getDisplayMetrics().scaledDensity; |
| | | |
| | | String s = FileUtil.getStringFromFile("/system/a"); |
| | | int res = FSDK.ActivateLibrary(s); |
| | | if (res != FSDK.FSDKE_OK) { |
| | | mIsFailed = true; |
| | | showErrorAndClose("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)); |
| | | |
| | | |
| | | // FSDK.Initialize(); |
| | | // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); |
| | | // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); |
| | | // mDraw = new ProcessImageAndDrawResults(this); |
| | | // mPreview = new Preview(this, mDraw); |
| | | // mDraw.mTracker = new FSDK.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(); |
| | | // |
| | | // 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(CommonVariables.FACE_SERVER) { |
| | | 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) |
| | | .show(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | protected void onPause() { |
| | | super.onPause(); |
| | | if(CommonVariables.FACE_SERVER) { |
| | | pauseProcessingFrames(); |
| | | String templatePath = this.getApplicationInfo().dataDir + "/" + database; |
| | | FSDK.SaveTrackerMemoryToFile(mDraw.mTracker, templatePath); |
| | | } |
| | | VisitorRegisterUploadPhotoDialog.getInstance().hide(); |
| | | VisitorRegisterSelectPhotoDialog.getInstance().hide(); |
| | | AttenderRegisterSelectPhotoDialog.getInstance().hide(); |
| | | AttenderRegisterUploadPhotoDialog.getInstance().hide(); |
| | | } |
| | | |
| | | @Override |
| | | protected void onResume() { |
| | | super.onResume(); |
| | | if(CommonVariables.FACE_SERVER) { |
| | | if (mIsFailed) |
| | | return; |
| | | resumeProcessingFrames(); |
| | | } |
| | | } |
| | | |
| | | public void showErrorAndClose(String error, int code) { |
| | | AlertDialog.Builder builder = new AlertDialog.Builder(this); |
| | | builder.setMessage(error + ": " + code) |
| | | .setPositiveButton("Ok", new DialogInterface.OnClickListener() { |
| | | @Override |
| | | public void onClick(DialogInterface dialogInterface, int i) { |
| | | android.os.Process.killProcess(android.os.Process.myPid()); |
| | | } |
| | | }) |
| | | .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) |
| | | .show(); |
| | | } |
| | | |
| | | private void resetTrackerParameters() { |
| | | int errpos[] = new int[1]; |
| | | FSDK.SetTrackerMultipleParameters(mDraw.mTracker, "ContinuousVideoFeed=true;FacialFeatureJitterSuppression=0;RecognitionPrecision=0;Threshold=0.996;Threshold2=0.9995;ThresholdFeed=0.97;MemoryLimit=1000;HandleArbitraryRotations=false;DetermineFaceRotationAngle=false;InternalResizeWidth=70;FaceDetectionThreshold=5;", errpos); |
| | | if (errpos[0] != 0) { |
| | | showErrorAndClose("Error setting tracker parameters, position", errpos[0]); |
| | | } |
| | | } |
| | | |
| | | private void pauseProcessingFrames() { |
| | | mDraw.mStopping = 1; |
| | | |
| | | 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; |
| | | } |
| | | |
| | | @Override |
| | | protected void onStop() { |
| | | super.onStop(); |
| | | VisitorRegisterUploadPhotoDialog.getInstance().hide(); |
| | | VisitorRegisterSelectPhotoDialog.getInstance().hide(); |
| | | AttenderRegisterSelectPhotoDialog.getInstance().hide(); |
| | | AttenderRegisterUploadPhotoDialog.getInstance().hide(); |
| | | //Config.sqlMap.getDb().close(); |
| | | // db.close(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | 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; |
| | | } |
| | | |
| | | int canvasWidth = canvas.getWidth(); |
| | | |
| | | decodeYUV420SP(mRGBData, mYUVData, mImageWidth, mImageHeight); |
| | | |
| | | 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); |
| | | |
| | | int ImageWidth = mImageWidth; |
| | | if (rotated) { |
| | | ImageWidth = mImageHeight; |
| | | FSDK.RotateImage90(Image, -1, RotatedImage); |
| | | } else { |
| | | FSDK.CopyImage(Image, RotatedImage); |
| | | } |
| | | |
| | | // FSDK.TFacePosition fp11 = new FSDK.TFacePosition(); |
| | | // FSDK.DetectFace(RotatedImage, fp11); |
| | | FSDK.FSDK_FaceTemplate face = new FSDK.FSDK_FaceTemplate(); |
| | | int result = FSDK.GetFaceTemplate(RotatedImage, face); |
| | | if (result == FSDK.FSDKE_OK) { |
| | | |
| | | } |
| | | |
| | | String surveillancePhotoName11 = "/storage/sdcard1/"+System.currentTimeMillis()+".jpg"; |
| | | FSDK.SaveImageToFile(Image, surveillancePhotoName11); |
| | | |
| | | |
| | | FSDK.FreeImage(Image); |
| | | |
| | | long IDs[] = new long[MAX_FACES]; |
| | | long face_count[] = new long[1]; |
| | | |
| | | |
| | | |
| | | FSDK.FeedFrame(mTracker, 0, RotatedImage, face_count, IDs); |
| | | |
| | | System.out.println("face_count="+face_count[0]+", mImageWidth="+mImageWidth+", mImageHeight="+mImageHeight); |
| | | |
| | | 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; |
| | | } |
| | | if ((int)face_count[0] > 0) { |
| | | |
| | | FSDK.HImage img2 = new FSDK.HImage(); |
| | | FSDK.CreateEmptyImage(img2); |
| | | FSDK.TFacePosition fp = new FSDK.TFacePosition(); |
| | | FSDK.DetectFace(RotatedImage, fp); |
| | | |
| | | int x1 = (int)(fp.xc - 1.2*fp.w/2); |
| | | int y1 = (int)(fp.yc - 1.4*fp.w/2); |
| | | int x2 = (int)(fp.xc + 1.2*fp.w/2); |
| | | int y2 = (int)(fp.yc + 1.4*fp.w/2); |
| | | |
| | | FSDK.CopyRect(RotatedImage, x1, y1, x2, y2, img2); |
| | | |
| | | int maxWidth = 337; |
| | | int maxHeight = 450; |
| | | |
| | | FSDK.ResizeImage(img2, Math.max((maxWidth+0.4)/(x2-x1+1), (maxHeight+0.4)/(y2-y1+1)), RotatedImage); |
| | | |
| | | System.out.println("face_count="+face_count[0]); |
| | | String surveillancePhotoName = MainActivity.getInstance().getFilesDir().getAbsolutePath()+System.currentTimeMillis()+".jpg"; |
| | | FSDK.SaveImageToFile(img2, surveillancePhotoName); |
| | | |
| | | List bitmapList = new ArrayList(); |
| | | for (int i = 0; i < 1; i++) { |
| | | NativeImg nativeImg = new NativeImg(); |
| | | nativeImg.image = FileUtil.readFile(new File(surveillancePhotoName)); |
| | | nativeImg.size = nativeImg.image.length; |
| | | SurveillanceQueryItem surveillanceQueryItem = new SurveillanceQueryItem(); |
| | | surveillanceQueryItem.setNativeImg(nativeImg); |
| | | nativeImg.st_track_id = 1; |
| | | surveillanceQueryItem.setStTrackId(nativeImg.st_track_id); |
| | | BitmapFactory.Options options = new BitmapFactory.Options(); |
| | | options.inMutable = true; |
| | | Bitmap bmp = BitmapFactory.decodeByteArray(nativeImg.image, 0, nativeImg.image.length, options); |
| | | Canvas canvas1 = new Canvas(bmp); |
| | | |
| | | surveillanceQueryItem.setBitmap(bmp); |
| | | surveillanceQueryItem.setWidth("100"); |
| | | surveillanceQueryItem.setHeight("100"); |
| | | surveillanceQueryItem.setRegisterOrCheckIn(CommonVariables.Surveillance.OFFLINE_SURVEILLANCE_ITEM_TYPE); |
| | | surveillanceQueryItem.setCreateTime(new Date()); |
| | | bitmapList.add(surveillanceQueryItem); |
| | | |
| | | if (BaseApplication.getInstance().networkAvailable()) { |
| | | SurveillanceMng.getInstance().addBitmap(bitmapList, nativeImg.image, 0, CommonVariables.Camera.IN+"", nativeImg.image); |
| | | } else { |
| | | SurveillanceMng.getInstance().addOfflineBitmap(bitmapList, nativeImg.image, CommonVariables.Camera.IN+""); |
| | | } |
| | | } |
| | | |
| | | } |
| | | FSDK.FreeImage(RotatedImage); |
| | | faceLock.unlock(); |
| | | |
| | | int shift = (int)(22 * MainActivity.sDensity); |
| | | |
| | | 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(); |
| | | if(rects[i] == null) { |
| | | faceLock.unlock(); |
| | | return true; |
| | | } |
| | | 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); |
| | | FSDK.SetName(mTracker, mTouchedID, input.getText().toString()); |
| | | 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) { |
| | | v = (0xff & yuv420sp[uvp++]) - 128; |
| | | u = (0xff & yuv420sp[uvp++]) - 128; |
| | | } |
| | | int y1192 = 1192 * y; |
| | | int r = (y1192 + 1634 * v); |
| | | int g = (y1192 - 833 * v - 400 * u); |
| | | int b = (y1192 + 2066 * u); |
| | | if (r < 0) r = 0; else if (r > 262143) r = 262143; |
| | | if (g < 0) g = 0; else if (g > 262143) g = 262143; |
| | | if (b < 0) b = 0; else if (b > 262143) b = 262143; |
| | | |
| | | rgb[3*yp] = (byte) ((r >> 10) & 0xff); |
| | | rgb[3*yp+1] = (byte) ((g >> 10) & 0xff); |
| | | rgb[3*yp+2] = (byte) ((b >> 10) & 0xff); |
| | | ++yp; |
| | | } |
| | | } |
| | | } |
| | | } // end of ProcessImageAndDrawResults class |
| | | |
| | | |
| | | |
| | | |
| | | // Show video from camera and pass frames to ProcessImageAndDraw class |
| | | class Preview extends SurfaceView implements SurfaceHolder.Callback { |
| | | Context mContext; |
| | | SurfaceHolder mHolder; |
| | | Camera mCamera; |
| | | ProcessImageAndDrawResults mDraw; |
| | | boolean mFinished; |
| | | |
| | | Preview(Context context, ProcessImageAndDrawResults draw) { |
| | | super(context); |
| | | mContext = context; |
| | | mDraw = draw; |
| | | |
| | | //Install a SurfaceHolder.Callback so we get notified when the underlying surface is created and destroyed. |
| | | mHolder = getHolder(); |
| | | mHolder.addCallback(this); |
| | | mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); |
| | | } |
| | | |
| | | //SurfaceView callback |
| | | public void surfaceCreated(SurfaceHolder holder) { |
| | | mFinished = false; |
| | | |
| | | // Find the ID of the camera |
| | | int cameraId = 0; |
| | | boolean frontCameraFound = false; |
| | | Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); |
| | | for (int i = 0; i < Camera.getNumberOfCameras(); i++) { |
| | | Camera.getCameraInfo(i, cameraInfo); |
| | | //if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) |
| | | if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { |
| | | cameraId = i; |
| | | frontCameraFound = true; |
| | | } |
| | | } |
| | | |
| | | if (frontCameraFound) { |
| | | mCamera = Camera.open(cameraId); |
| | | } else { |
| | | mCamera = Camera.open(); |
| | | } |
| | | |
| | | try { |
| | | mCamera.setPreviewDisplay(holder); |
| | | |
| | | // Preview callback used whenever new viewfinder frame is available |
| | | mCamera.setPreviewCallback(new PreviewCallback() { |
| | | public void onPreviewFrame(byte[] data, Camera camera) { |
| | | if ( (mDraw == null) || mFinished ) |
| | | return; |
| | | |
| | | if (mDraw.mYUVData == null) { |
| | | // Initialize the draw-on-top companion |
| | | Camera.Parameters params = camera.getParameters(); |
| | | mDraw.mImageWidth = params.getPreviewSize().width; |
| | | mDraw.mImageHeight = params.getPreviewSize().height; |
| | | mDraw.mRGBData = new byte[3 * mDraw.mImageWidth * mDraw.mImageHeight]; |
| | | mDraw.mYUVData = new byte[data.length]; |
| | | } |
| | | |
| | | // Pass YUV data to draw-on-top companion |
| | | System.arraycopy(data, 0, mDraw.mYUVData, 0, data.length); |
| | | mDraw.invalidate(); |
| | | } |
| | | }); |
| | | } |
| | | catch (Exception exception) { |
| | | AlertDialog.Builder builder = new AlertDialog.Builder(mContext); |
| | | builder.setMessage("Cannot open camera" ) |
| | | .setPositiveButton("Ok", new DialogInterface.OnClickListener() { |
| | | @Override |
| | | public void onClick(DialogInterface dialogInterface, int i) { |
| | | android.os.Process.killProcess(android.os.Process.myPid()); |
| | | } |
| | | }) |
| | | .show(); |
| | | if (mCamera != null) { |
| | | mCamera.release(); |
| | | mCamera = null; |
| | | } |
| | | } |
| | | } |
| | | |
| | | //SurfaceView callback |
| | | public void surfaceDestroyed(SurfaceHolder holder) { |
| | | // Surface will be destroyed when we return, so stop the preview. |
| | | // Because the CameraDevice object is not a shared resource, it's very |
| | | // important to release it when the activity is paused. |
| | | mFinished = true; |
| | | if (mCamera != null) { |
| | | mCamera.setPreviewCallback(null); |
| | | mCamera.stopPreview(); |
| | | mCamera.release(); |
| | | mCamera = null; |
| | | } |
| | | } |
| | | |
| | | //SurfaceView callback, configuring camera |
| | | public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { |
| | | if (mCamera == null) return; |
| | | |
| | | // Now that the size is known, set up the camera parameters and begin |
| | | // the preview. |
| | | Camera.Parameters parameters = mCamera.getParameters(); |
| | | |
| | | //Keep uncommented to work correctly on phones: |
| | | //This is an undocumented although widely known feature |
| | | /**/ |
| | | if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { |
| | | parameters.set("orientation", "portrait"); |
| | | mCamera.setDisplayOrientation(90); // For Android 2.2 and above |
| | | mDraw.rotated = true; |
| | | } else { |
| | | parameters.set("orientation", "landscape"); |
| | | mCamera.setDisplayOrientation(0); // For Android 2.2 and above |
| | | } |
| | | /**/ |
| | | |
| | | // choose preview size closer to 640x480 for optimal performance |
| | | List<Size> supportedSizes = parameters.getSupportedPreviewSizes(); |
| | | int width = 0; |
| | | int height = 0; |
| | | for (Size s: supportedSizes) { |
| | | if ((width - 640)*(width - 640) + (height - 480)*(height - 480) > |
| | | (s.width - 640)*(s.width - 640) + (s.height - 480)*(s.height - 480)) { |
| | | width = s.width; |
| | | height = s.height; |
| | | } |
| | | } |
| | | |
| | | //try to set preferred parameters |
| | | try { |
| | | if (width*height > 0) { |
| | | parameters.setPreviewSize(width, height); |
| | | } |
| | | //parameters.setPreviewFrameRate(10); |
| | | parameters.setSceneMode(Camera.Parameters.SCENE_MODE_PORTRAIT); |
| | | parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); |
| | | mCamera.setParameters(parameters); |
| | | } catch (Exception ex) { |
| | | } |
| | | mCamera.startPreview(); |
| | | |
| | | parameters = mCamera.getParameters(); |
| | | Camera.Size previewSize = parameters.getPreviewSize(); |
| | | makeResizeForCameraAspect(1.0f / ((1.0f * previewSize.width) / previewSize.height)); |
| | | } |
| | | |
| | | private void makeResizeForCameraAspect(float cameraAspectRatio){ |
| | | LayoutParams layoutParams = this.getLayoutParams(); |
| | | int matchParentWidth = this.getWidth(); |
| | | int newHeight = (int)(matchParentWidth/cameraAspectRatio); |
| | | if (newHeight != layoutParams.height) { |
| | | layoutParams.height = newHeight; |
| | | layoutParams.width = matchParentWidth; |
| | | this.setLayoutParams(layoutParams); |
| | | this.invalidate(); |
| | | } |
| | | } |
| | | } // end of Preview class |