百度人脸识别---横屏,竖屏的实现

前言

新的项目用了百度的人脸识别,然后开开心心的集成了百度的人脸识别sdk,非常perfect,so easy.然而项目的应用场景需要横屏使用,但是百度这个坑爹的货,只给了一个竖屏demo,去百度提工单,然而说你们自己适配,我去你大爷的。骂归骂,可咱也得解决不是,好在我们的平板是固定的,只需要适配一个就行,下面我来放大招了。先看效果图,
在这里插入图片描述
在这里插入图片描述

正文

其实呢,想适配横屏也非常简单,只需要修改一下几个方向参数即可,这几个方向含义,我也不细说了,主要就是1,相机的预览方向,Camera.DisplayOrientation,2 图像的预览方向,Camera.getParameters.setRotation, 3,相机的传感器方向,这个咱不能修改,因为这是固件安装固定的,前面两个,我们可以自由修改,只要能跟相机传感器方向匹配,就能获得完美的效果,我修改的地方,我做了注释,看代码吧

//1,修改这个类的这个方法
CameraImageSource.java

 //TODO--输入源
    public CameraImageSource(Context context) {
        this.context = context;
//        Log.e("camera","orientation:="+context.getResources().getConfiguration().orientation);
        cameraControl = new Camera1Control(getContext());
        cameraControl.setCameraFacing(cameraFaceType);
        //TODO---横屏90,竖屏0
        cameraControl.setDisplayOrientation((context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) ? CameraView.ORIENTATION_HORIZONTAL : CameraView.ORIENTATION_PORTRAIT);
        cameraControl.setOnFrameListener(new ICameraControl.OnFrameListener<byte[]>() {
            @Override
            public void onPreviewFrame(byte[] data, int rotation, int width, int height) {

                Log.e("camera", "setOnFrameListener onPreviewFrame: rotation:" + rotation + ",width:" + width + ",height:" + height);

                int[] argb = argbPool.acquire(width, height);

                if (argb == null || argb.length != width * height) {
                    argb = new int[width * height];
                }

                rotation = rotation < 0 ? 360 + rotation : rotation;
                FaceDetector.yuvToARGB(data, width, height, argb, rotation, 0);

                // liujinhui modify

                // TODO--旋转了90或270度。高宽需要替换
                if (rotation % 180 == 90) {
                    int temp = width;
                    width = height;
                    height = temp;
                }

                ImageFrame frame = new ImageFrame();
                frame.setArgb(argb);
                frame.setWidth(width);
                frame.setHeight(height);
                frame.setPool(argbPool);
                ArrayList<OnFrameAvailableListener> listeners = getListeners();
                for (OnFrameAvailableListener listener : listeners) {
                    listener.onFrameAvailable(frame);
                }
            }
        });
    }

// TODO---2,修改这个类
/**
 * 5.0以下相机API的封装。
 */
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class Camera1Control implements ICameraControl {

    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
    private static final int MAX_PREVIEW_SIZE = 2048;

    static {
        ORIENTATIONS.append(Surface.ROTATION_0, 90);
        ORIENTATIONS.append(Surface.ROTATION_90, 0);
        ORIENTATIONS.append(Surface.ROTATION_180, 270);
        ORIENTATIONS.append(Surface.ROTATION_270, 180);
    }


    private int displayOrientation = CameraView.ORIENTATION_HORIZONTAL;//TODO--这里修改为90,原来是0
    private int cameraId = 0;
    private int flashMode;
    private AtomicBoolean takingPicture = new AtomicBoolean(false);

    private Context context;
    private Camera camera;

    private Camera.Parameters parameters;
    private PermissionCallback permissionCallback;
    private Rect previewFrame = new Rect();

    private int preferredWidth = 1280;
    private int preferredHeight = 720;

    @ICameraControl.CameraFacing
    private int cameraFacing = CAMERA_FACING_FRONT;

    private boolean usbCamera = false;

    @Override
    public void setDisplayOrientation(int displayOrientation) {
        this.displayOrientation = displayOrientation;
        Log.e("camera","setDisplayOrientation:"+displayOrientation);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void refreshPermission() {
        startPreview(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setFlashMode(@FlashMode int flashMode) {
        if (this.flashMode == flashMode) {
            return;
        }
        this.flashMode = flashMode;
        updateFlashMode(flashMode);
    }

    @Override
    public int getFlashMode() {
        return flashMode;
    }

    @Override
    public void setCameraFacing(@CameraFacing int cameraFacing) {
        this.cameraFacing = cameraFacing;
    }

    @Override
    public void setUsbCamera(boolean usbCamera) {
        this.usbCamera = usbCamera;
    }

    @Override
    public void start() {
        startCamera();
    }

    public void isUsbCamera() {

    }

    private SurfaceTexture surfaceTexture;

    private void startCamera() {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            if (permissionCallback != null) {
                permissionCallback.onRequestPermission();
            }
            return;
        }
        if (camera == null) {
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
                Camera.getCameraInfo(i, cameraInfo);
                if (cameraInfo.facing == cameraFacing) {
                    cameraId = i;
                }
            }
            camera = Camera.open(cameraId);
        }
        if (parameters == null) {
            parameters = camera.getParameters();
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }

        surfaceTexture = new SurfaceTexture(11);
        parameters.setRotation((displayOrientation == CameraView.ORIENTATION_HORIZONTAL) ? 0 : 90); // TODO--图片的预览方向,原来是90,我设置为0
        int rotation = ORIENTATIONS.get(displayOrientation);
        Log.e("camera", "camera rotation:" + rotation+",displayOrientation:"+displayOrientation);
        camera.setDisplayOrientation(rotation);//TODO---相机的预览反向
        //TODO---设备方向,

        try {
            camera.setPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {//TODO--相机预览回调
//                    Log.e("onPreviewFrame", "onPreviewFrame");
                    Camera.Size size = camera.getParameters().getPreviewSize();
                    Log.e("camera", "camera.getParameters().getPreviewSize() :height:" + size.height + ",width:" + size.width);
                    int rotation = getSurfaceOrientation();//TODO--这里原来是{# getSurfaceOrientation()},改成0

                    Log.e("camera", "getSurfaceOrientation :" + rotation + ",displayorientation:" + displayOrientation);

                    if (cameraFacing == ICameraControl.CAMERA_FACING_FRONT) {
                        //TODO--镜像--180旋转 android自带的摄像头和接usb摄像头,图片有180旋转,用usb摄像头注释下面的代码,
                        if (!usbCamera) {
                            if (rotation == 90 || rotation == 270) {
                                rotation = (rotation + 180) % 360;
                            }
                        }
                    }

                    Log.e("camera", "getSurfaceOrientation :" + rotation + ",rotation % 180 == 90:" + (rotation % 180 == 90));

                    if (rotation % 180 == 90) {
                        previewView.setPreviewSize(size.height, size.width);//,TODO--这里回调的是旋转的图片
                    } else {
                        previewView.setPreviewSize(size.width, size.height);
                    }

                    onFrameListener.onPreviewFrame(data, rotation, size.width, size.height);
                }
            });
            camera.setPreviewTexture(surfaceTexture);
            if (textureView != null) {
                surfaceTexture.detachFromGLContext();
                textureView.setSurfaceTexture(surfaceTexture);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        opPreviewSize(preferredWidth, preferredHeight);
    }

    private TextureView textureView;

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void setTextureView(TextureView textureView) {
        this.textureView = textureView;
        if (surfaceTexture != null) {
            surfaceTexture.detachFromGLContext();
            textureView.setSurfaceTexture(surfaceTexture);
        }
    }

    @Override
    public void stop() {
        if (camera != null) {
            camera.stopPreview();
            camera.setPreviewCallback(null);
            camera.release();
            camera = null;
        }
    }

    @Override
    public void pause() {
        if (camera != null) {
            camera.stopPreview();
        }
        setFlashMode(FLASH_MODE_OFF);
    }

    @Override
    public void resume() {
        takingPicture.set(false);
        if (camera == null) {
            startCamera();
        }
    }

    private OnFrameListener onFrameListener;

    @Override
    public void setOnFrameListener(OnFrameListener listener) {
        this.onFrameListener = listener;
    }

    @Override
    public void setPreferredPreviewSize(int width, int height) {
        this.preferredWidth = Math.max(width, height);
        this.preferredHeight = Math.min(width, height);
    }

    @Override
    public View getDisplayView() {
        return null;
    }


    private PreviewView previewView;

    @Override
    public void setPreviewView(PreviewView previewView) {
        this.previewView = previewView;
        setTextureView(previewView.getTextureView());
    }

    @Override
    public PreviewView getPreviewView() {
        return previewView;
    }

    @Override
    public void takePicture(final OnTakePictureCallback onTakePictureCallback) {
        if (takingPicture.get()) {
            return;
        }

        switch (displayOrientation) {
            case CameraView.ORIENTATION_PORTRAIT:
                parameters.setRotation(90);
                break;
            case CameraView.ORIENTATION_HORIZONTAL:
                parameters.setRotation(0);
                break;
            case CameraView.ORIENTATION_INVERT:
                parameters.setRotation(180);
                break;
            default:
                parameters.setRotation(90);
                break;
        }
        Camera.Size picSize =
                getOptimalSize(preferredWidth, preferredHeight, camera.getParameters().getSupportedPictureSizes());
        parameters.setPictureSize(picSize.width, picSize.height);
        camera.setParameters(parameters);
        takingPicture.set(true);
        camera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                camera.cancelAutoFocus();
                try {
                    camera.takePicture(null, null, new Camera.PictureCallback() {
                        @Override
                        public void onPictureTaken(byte[] data, Camera camera) {
                            camera.startPreview();
                            takingPicture.set(false);
                            if (onTakePictureCallback != null) {
                                onTakePictureCallback.onPictureTaken(data);
                            }
                        }
                    });
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    camera.startPreview();
                    takingPicture.set(false);
                }
            }
        });
    }

    @Override
    public void setPermissionCallback(PermissionCallback callback) {
        this.permissionCallback = callback;
    }

    public Camera1Control(Context context) {
        this.context = context;
        Log.e("camera", "Camera1Control------------");
    }

    // 开启预览
    private void startPreview(boolean checkPermission) {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            if (checkPermission && permissionCallback != null) {
                permissionCallback.onRequestPermission();
            }
            return;
        }
        camera.startPreview();
    }

    private void opPreviewSize(int width, @SuppressWarnings("unused") int height) {
        Camera.Size optSize;
        if (parameters != null && camera != null && width > 0) {
            optSize = getOptimalSize(width, height, camera.getParameters().getSupportedPreviewSizes());

            Log.e("camera", "getOptimalSize:width:" + optSize.width + ",height:" + optSize.height);//TODO--设置最佳预览尺寸

            parameters.setPreviewSize(optSize.width, optSize.height);

//            camera.setDisplayOrientation(getSurfaceOrientation());
            //            camera.stopPreview();
            try {
                camera.setParameters(parameters);
            } catch (RuntimeException e) {
                e.printStackTrace();

            }
            camera.startPreview();
        }
    }

    private Camera.Size getOptimalSize(int width, int height, List<Camera.Size> sizes) {

        Camera.Size pictureSize = sizes.get(0);

        List<Camera.Size> candidates = new ArrayList<>();

        for (Camera.Size size : sizes) {
            if (size.width >= width && size.height >= height && size.width * height == size.height * width) {
                // 比例相同
                candidates.add(size);
            } else if (size.height >= width && size.width >= height && size.width * width == size.height * height) {
                // 反比例
                candidates.add(size);
            }
        }
        if (!candidates.isEmpty()) {
            return Collections.min(candidates, sizeComparator);
        }

        for (Camera.Size size : sizes) {
            if (size.width > width && size.height > height) {
                return size;
            }
        }

        return pictureSize;
    }

    private Comparator<Camera.Size> sizeComparator = new Comparator<Camera.Size>() {
        @Override
        public int compare(Camera.Size lhs, Camera.Size rhs) {
            return Long.signum((long) lhs.width * lhs.height - (long) rhs.width * rhs.height);
        }
    };

    private void updateFlashMode(int flashMode) {
        switch (flashMode) {
            case FLASH_MODE_TORCH:
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                break;
            case FLASH_MODE_OFF:
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                break;
            case ICameraControl.FLASH_MODE_AUTO:
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                break;
            default:
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                break;
        }
        camera.setParameters(parameters);
    }

    protected int getSurfaceOrientation() {

        switch (displayOrientation) {
            case CameraView.ORIENTATION_HORIZONTAL:
                return 0;
            case CameraView.ORIENTATION_INVERT:
                return 180;
            default:
                return 90;
        }
    }

    @Override
    public Rect getPreviewFrame() {
        return previewFrame;
    }
}

结尾

好了,很简单就能改好了,为了方便大家测试,我把我申请的测试 FaceLogin-Sample-Android-demo上传上来,给大家用,不用谢我。让人无语的百度,连个人工客服都没有,差评

后续

CSDN是真的操蛋,我上传的资源明明没有标分,特么后面自动给我标上积分,我本来是免费共享的,你特么拿我的资源去赚钱,要点脸不,我上传的资源,所有权应该在我吧,你特么有什么权利瞎搞我的资源,再也不在CSDN上传资源了,操。

好的,关于人脸识别的问题,以下是使用OpenCV-Java实现人脸识别的代码示例: 1. 引入OpenCV-Java库 在项目中引入OpenCV-Java库,可以从官网下载对应的版本,引入后,我们就可以调用OpenCV-Java提供的API来实现人脸识别。 2. 加载人脸识别器 在使用OpenCV-Java实现人脸识别前,我们需要加载一个训练好的分类器,可以使用官方提供的人脸识别模型,或自己训练。加载过程如下: ``` CascadeClassifier faceDetector = new CascadeClassifier("haarcascade_frontalface_alt.xml"); ``` 3. 读取图片并识别人脸 加载分类器后,我们可以读取一张图片并进行人脸识别,具体实现代码如下: ``` Mat image = Imgcodecs.imread("test.jpg"); // 读取图片 Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2GRAY); // 转为灰度图 Imgproc.equalizeHist(image, image); // 直方图均衡化,提高图像质量 Rect[] faces = faceDetector.detectMultiScale(image); // 识别人脸 for (Rect rect : faces) { Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0)); // 绘制人脸框 } Imgcodecs.imwrite("result.jpg", image); // 保存结果 ``` 其中,`detectMultiScale` 方法用于检测出图像中的人脸,返回一个`Rect`类型的数组,每个元素代表一个人脸的位置和大小。 4. 运行程序 将以上代码放入一个Java类中,运行程序即可实现人脸识别。注意,需要引入`org.opencv.core.Mat`、`org.opencv.core.Rect`、`org.opencv.core.Point`、`org.opencv.core.Scalar`、`org.opencv.imgcodecs.Imgcodecs`、`org.opencv.imgproc.Imgproc`等OpenCV-Java的类。 希望能够对您有所帮助!
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值