Android OpenCV 实例笔记3 -- 三种方法 摄像头竖屏全屏的设置
2016/08/28整理编辑,方法三已整理完毕
2017/03/25整理编辑
这里面的教程自己只在官方的颜色跟踪案例修改过。由于很久不搞安卓了,其他案例可能就没法去一一验证了。
文章只提供可行的思路,建议要修改的朋友先看下修改的原理再去改动。
2017/05/13 之前的代码,Github项目地址见文尾
Android终端下,OPENCV打开摄像头后,默认为横屏输入流,当设置为竖屏时,相机预览的图像可以看到如下图所示,并不能全屏。
下面介绍使得摄像头竖屏全屏的方法 ,方法一与方法二来自stackoverflow,方法三为笔者总结

实现后效果如下

方法一:
步骤1:
在CameraBridgeViewBase.JAVA文件的所有构造函数里,声明初始化一个 windowManager
具体如下。
先声明public WindowManager windowManager;
在public CameraBridgeViewBase 里增加以下语句
windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
步骤2:
在CameraBridgeViewBase.deliverAndDrawFrame(CvCameraViewFrame frame) 方法里:
//找到并替换已有if语句:
if (bmpValid && mCacheBitmap != null) {
Canvas canvas = getHolder().lockCanvas();
if (canvas != null) {
canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
int rotation = windowManager.getDefaultDisplay().getRotation();
int degrees = 0;
// config degrees as you need
switch (rotation) {
case Surface.ROTATION_0:
degrees = -90;
break;
case Surface.ROTATION_90:
break;
case Surface.ROTATION_180:
break;
case Surface.ROTATION_270:
degrees = 180;
break;
}
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
Bitmap outputBitmap = Bitmap.createBitmap(mCacheBitmap, 0, 0, mCacheBitmap.getWidth(), mCacheBitmap.getHeight(), matrix, true);
if (outputBitmap.getWidth() <= canvas.getWidth()) {
mScale = getRatio(outputBitmap.getWidth(), outputBitmap.getHeight(), canvas.getWidth(), canvas.getHeight());
} else {
mScale = getRatio(canvas.getWidth(), canvas.getHeight(), outputBitmap.getWidth(), outputBitmap.getHeight());
}
if (mScale != 0) {
canvas.scale(mScale, mScale, 0, 0);
}
Log.d(TAG, "mStretch value: " + mScale);
canvas.drawBitmap(outputBitmap, 0, 0, null);
if (mFpsMeter != null) {
mFpsMeter.measure();
mFpsMeter.draw(canvas, 20, 30);
}
getHolder().unlockCanvasAndPost(canvas);
}
}步骤3: 增加下面这个方法(得到屏幕宽高比例)
private float getRatio(int widthSource, int heightSource, int widthTarget, int heightTarget) { if (widthTarget <= heightTarget) { // return (float) heightTarget / (float) heightSource; } else { return (float) widthTarget / (float) widthSource; } }
结果可以看到,在竖屏状态下也可以全屏了,但处理速度有所下降。
方法二
在deliverAndDrawFrame()函数中,修改以下部分
if (canvas != null) { canvas.rotate(90,0,0); float scale = canvas.getWidth() / (float)mCacheBitmap.getHeight(); float scale2 = canvas.getHeight() / (float)mCacheBitmap.getWidth(); if(scale2 > scale){ scale = scale2; } if (scale != 0) { canvas.scale(scale, scale,0,0); } canvas.drawBitmap(mCacheBitmap, 0, -mCacheBitmap.getHeight(), null); // canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR); Log.d(TAG, "mStretch value: " + mScale); /* if (mScale != 0) { canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()), new Rect((int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2), (int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2), (int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2 + mScale*mCacheBitmap.getWidth()), (int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2 + mScale*mCacheBitmap.getHeight())), null); } else { canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()), new Rect((canvas.getWidth() - mCacheBitmap.getWidth()) / 2, (canvas.getHeight() - mCacheBitmap.getHeight()) / 2, (canvas.getWidth() - mCacheBitmap.getWidth()) / 2 + mCacheBitmap.getWidth(), (canvas.getHeight() - mCacheBitmap.getHeight()) / 2 + mCacheBitmap.getHeight()), null); }*/方法三:
方法一和方法二经过实测,存在一定的问题,且会影响颜色跟踪处理速度。
方法三则采用了OPENCV自带的函数实现了相应的全屏,且处理速度也跟上了。
CameraBridgeViewBase.java 文件修改
以下以官方的颜色检测例程为例修改
旋转函数
//Imgproc.drawContours(mRgba,contours, -1, CONTOUR_COLOR); //在这个位置下添加
Core.transpose(this.mRgba,this.mRgbaT); //转置函数,可以水平的图像变为垂直
Imgproc.resize(this.mRgbaT,this.mRgbaF, this.mRgbaF.size(), 0.0D, 0.0D, 0); //将转置后的图像缩放为mRgbaF的大小
Core.flip(this.mRgbaF, this.mRgba,1); //flipCode>0将mRgbaF水平翻转(沿Y轴翻转)得到mRgba修改坐标转换算法(在涉及到坐标转换的函数里修改,如onTouch函数为例)改为 int cols = mRgba.cols(); int rows = mRgba.rows(); // int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2; //int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2; int x =(int)(event.getX()/mOpenCvCameraView.getWidth()*cols); int y =(int)(event.getY()/mOpenCvCameraView.getHeight()*rows);05/13 项目地址 链接
版权声明:本文为qq_17121501原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。