• Android+openCV 动态人脸检测


    动态人脸检测前提是需要打开摄像头。

    网上看了很多教程,我知道的有两种方式打开摄像头:

    JavaCameraView mCameraView = new JavaCameraView(this, -1);
    setContentView(mCameraView);
    mCameraView.setCvCameraViewListener(this);
    
    mCameraView.enableView();

    第2种:在布局文件中添加 CameraBridgeViewBase

    mCameraView = (CameraBridgeViewBase) findViewById(R.id.java_surface_view);
    mCameraView.setCvCameraViewListener(this);
    mCameraView.enableView();

    以上两种获取摄像头实时视频流方式需要 implements  CameraBridgeViewBase.CvCameraViewListener

    public class FaceTrackingActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener {
      @Overrid
      protected void onCreate(Bundle savedInstanceState) { ... } @Override public void onCameraViewStarted(int width, int height) { } @Override public void onCameraViewStopped() { } @Override public Mat onCameraFrame(Mat inputFrame) { return null; } }
    onCameraFrame 函数中将捕获视频每一帧。
    这样我在预览视频的时候,发现很难控制大小,以及摄像头的方向。
    后来我直接采用以往的camera类去操作视频流。
    以上参考:http://blog.csdn.net/tobacco5648/article/details/51615632

    实时处理摄像头预览帧视频参考:http://blog.csdn.net/yanzi1225627/article/details/8605061

    定义 SurfaceView

        <SurfaceView
            android:id="@+id/java_surface_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
            mSurfaceView = (SurfaceView) findViewById(R.id.java_surface_view);
            mSurfaceHolder = mSurfaceView.getHolder();
    
            // mSurfaceView 不需要自己的缓冲区
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            // mSurfaceView添加回调
            mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
                @Override
                public void surfaceCreated(SurfaceHolder holder) { //SurfaceView创建
                    try {
                        cameraManager = new CameraManager(FaceTrackingActivity.this, mObjectDetects, cimbt, mSurfaceHolder);
                        cameraManager.openDriver();
                        cameraManager.startPreview();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
                }
    
                @Override
                public void surfaceDestroyed(SurfaceHolder holder) { //SurfaceView销毁
                    holder.removeCallback(this); // Camera is being used after Camera.release() was called
                    cameraManager.stopPreview();
                    cameraManager.closeDriver();
    
                }
            });
    

    我这里独立出来了一个 CameraManager 类,本来我想把检测的代码写在 CameraManager 类之外,然而并没有实现:

     CameraManager 类中  implements Camera.PreviewCallback 可以实现 onPreviewFrame 对实时数据处理:

        @Override
        public void onPreviewFrame(byte[] bytes, Camera camera) {
            Camera.Size previewSize = camera.getParameters().getPreviewSize();
    
            Bitmap bitmap = ByteToBitmap(bytes, previewSize);
            //Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);//将data byte型数组转换成bitmap文件
    
            final Matrix matrix = new Matrix();//转换成矩阵旋转90度
            if (cameraPosition == 1) {
                matrix.setRotate(90);
            } else {
                matrix.setRotate(-90);
            }
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);//旋转图片
    
    
            Mat grayscaleImage = new Mat(previewSize.height, previewSize.width, CvType.CV_8UC4);
            int absoluteFaceSize = (int) (previewSize.height * 0.2);
    
            if (bitmap != null) {
                Mat inputFrame = new Mat();
                Utils.bitmapToMat(bitmap, inputFrame);
    
                if (!bitmap.isRecycled()) {
                    bitmap.recycle();
                }
    
                // Create a grayscale image
                Imgproc.cvtColor(inputFrame, grayscaleImage, Imgproc.COLOR_RGBA2RGB);
    
                MatOfRect mRect = new MatOfRect();
    
    
                int maxRectArea = 0 * 0;
                Rect maxRect = null;
    
                int facenum = 0;
    
                for (ObjectDetector detector : mObjectDetects) {
                    // 检测目标
                    Rect[] object = detector.detectObjectImage(inputFrame, mRect);
                    Log.e(TAG, object.length + "");
    
                    for (Rect rect : object) {
                        ++facenum;
                        // 找出最大的面积
                        int tmp = rect.width * rect.height;
                        if (tmp >= maxRectArea) {
                            maxRectArea = tmp;
                            maxRect = rect;
                        }
                    }
                }
    
                Bitmap rectBitmap = null;
                if (facenum != 0) {
                    // 剪切最大的头像
                    //Log.e("剪切的长宽", String.format("高:%s,宽:%s", maxRect.width, maxRect.height));
                    Rect rect = new Rect(maxRect.x, maxRect.y, maxRect.width, maxRect.height);
                    Mat rectMat = new Mat(inputFrame, rect);  // 从原始图像拿
                    rectBitmap = Bitmap.createBitmap(rectMat.cols(), rectMat.rows(), Bitmap.Config.ARGB_8888);
                    Utils.matToBitmap(rectMat, rectBitmap);
    
                    Bitmap resizeBmp = cimbt.resizeBitmap(rectBitmap, cimbt.getWidth(), cimbt.getHeight());
                    cimbt.setBitmap(resizeBmp);
                } else {
                    cimbt.clearnImage();
                    cimbt.setText("没有检测到人脸");
                }
            }
    
        }

    补充:在初始化相机时激活onPreviewFrame

    camera.setPreviewCallback(this);
    //camera.setOneShotPreviewCallback(this); // 激活 onPreviewFrame 执行一次

    整个人脸静态动态检测源代码: https://github.com/haoxr/faceDetection

    动态检测截图:

  • 相关阅读:
    【云速建站】购买前的指导
    【云速建站】域名配置指导
    Python爬虫批量下载糗事百科段子,怀念的天王盖地虎,小鸡炖蘑菇...
    舌尖上的安全
    【云速建站】视频播放专题
    Python装饰器总结,带你几步跨越此坑!
    让你提前认识软件开发(15):程序调试的利器—日志
    Win8下IIS的安装和站点的公布
    [2011山东ACM省赛] Mathman Bank(模拟题)
    Android UI开发神兵利器之Android Action Bar Style Generator
  • 原文地址:https://www.cnblogs.com/haoxr/p/7698481.html
Copyright © 2020-2023  润新知