Android通过OpenCV获取摄像头帧数据并在悬浮框显示

来源:互联网 发布:正规购买淘宝小号平台 编辑:程序博客网 时间:2024/05/02 00:55

Android通过OpenCV获取摄像头帧数据并在悬浮框显示

由于Android手机摄像头采集的原始帧默认是横屏格式的,所以我们需要都原始帧进行旋转等操作。有上一篇博文中的需求我们需要获取的帧数据格式为Mat类型,使用AndroidSDK自带的camera类采集我们还需要自己再转化为Mat类型,所以在这里就直接使用opencv4android 中的CameraBridgeViewBase与AndroidSDK中CameraView类结合起来采集图片帧。

图片帧旋转

图片帧旋转主要是获取手机当前的姿态,然后根据当前角度,选择旋转角度从而达到正常的显示效果。

class MyOrientationDetector extends OrientationEventListener {        public MyOrientationDetector(Context context) {            super(context);        }        @Override        public void onOrientationChanged(int orientation) {            if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {                return; // 手机平放时,检测不到有效的角度            }            // 只检测是否有四个角度的改变            if (orientation > 350 || orientation < 10) { // 0度                orientation = 0;                angle = 0f;                orient = 0f;            } else if (orientation > 80 && orientation < 100) { // 90度                orientation = 90;                angle = 270f;                // angle = 90f;                orient = 90f;            } else if (orientation > 170 && orientation < 190) { // 180度                orientation = 180;                angle = 180f;                // angle = 270f;                orient = 180f;            } else if (orientation > 260 && orientation < 280) { // 270度                orientation = 270;                angle = 90f;                // angle = 90f;                orient = 270f;            } else {                return;            }            Log.d("CameraService", orientation + "," + angle + "," + orient);        }    }       frameMat = inputFrame.rgba();   // 获取摄像头前景图像    if (orient == 0) {// 竖放        org.opencv.core.Core.flip(frameMat.t(), frameMat, 0);    } else if (orient == 90) {        org.opencv.core.Core.flip(frameMat, frameMat, -1);    } else if (orient == 180) {        org.opencv.core.Core.flip(frameMat.t(), frameMat, 1);    } else if (orient == 270) {    }                                   mOpenCvCameraView.setRotate(angle);

悬浮窗显示

将经过旋转后的图片通过缩放尺寸大小后显示到悬浮窗中。

Size dsize = new Size(frameMat.width() * 0.25, frameMat.height() * 0.25); // 设置新图片的大小       Imgproc.resize(frameMat, frameMat,dsize);//调用Imgproc的Resize方法,进行图片缩放  

创建悬浮窗

private void createFloatView(){    wmParams = new WindowManager.LayoutParams();    //获取WindowManagerImpl.CompatModeWrapper    mWindowManager = (WindowManager)getApplication().getSystemService(getApplication().WINDOW_SERVICE);    //设置window type    wmParams.type = LayoutParams.TYPE_PHONE;     //设置图片格式,效果为背景透明    wmParams.format = PixelFormat.RGBA_8888;     //设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)    wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE;    //调整悬浮窗显示的停靠位置为左侧置顶    wmParams.gravity = Gravity.LEFT | Gravity.TOP;     // 以屏幕左上角为原点,设置xy初始值    wmParams.x = 300;    wmParams.y = 500;    // 设置悬浮窗口长宽数据    wmParams.width = 120;    wmParams.height = 160;    LayoutInflater inflater = LayoutInflater.from(getApplication());    //获取浮动窗口视图所在布局    mFloatLayout = (FrameLayout) inflater.inflate(R.layout.float_layout, null);    //添加mFloatLayout    mWindowManager.addView(mFloatLayout, wmParams);               mOpenCvCameraView = (BaseView) mFloatLayout.findViewById(R.id.CameraView);    mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0,                View.MeasureSpec.UNSPECIFIED), View.MeasureSpec                .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));    //设置监听浮动窗口的触摸移动    mFloatLayout.setOnTouchListener(new OnTouchListener() {                 @Override        public boolean onTouch(View v, MotionEvent event) {            // TODO Auto-generated method stub            wmParams.x = (int) event.getRawX() - mFloatLayout.getMeasuredWidth()/2;            wmParams.y = (int) event.getRawY() - mFloatLayout.getMeasuredHeight()/2;            mWindowManager.updateViewLayout(mFloatLayout, wmParams);            return false;        }    });      }

Demo(OpencvCamera)下载

原创粉丝点击