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) 方法里:

  1. //找到并替换已有if语句:
  2. if (bmpValid && mCacheBitmap != null) {
  3. Canvas canvas = getHolder().lockCanvas();
  4. if (canvas != null) {
  5. canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
  6. int rotation = windowManager.getDefaultDisplay().getRotation();
  7. int degrees = 0;
  8. // config degrees as you need
  9. switch (rotation) {
  10. case Surface.ROTATION_0:
  11. degrees = -90;
  12. break;
  13. case Surface.ROTATION_90:
  14. break;
  15. case Surface.ROTATION_180:
  16. break;
  17. case Surface.ROTATION_270:
  18. degrees = 180;
  19. break;
  20. }
  21. Matrix matrix = new Matrix();
  22. matrix.postRotate(degrees);
  23. Bitmap outputBitmap = Bitmap.createBitmap(mCacheBitmap, 0, 0, mCacheBitmap.getWidth(), mCacheBitmap.getHeight(), matrix, true);
  24. if (outputBitmap.getWidth() <= canvas.getWidth()) {
  25. mScale = getRatio(outputBitmap.getWidth(), outputBitmap.getHeight(), canvas.getWidth(), canvas.getHeight());
  26. } else {
  27. mScale = getRatio(canvas.getWidth(), canvas.getHeight(), outputBitmap.getWidth(), outputBitmap.getHeight());
  28. }
  29. if (mScale != 0) {
  30. canvas.scale(mScale, mScale, 0, 0);
  31. }
  32. Log.d(TAG, "mStretch value: " + mScale);
  33. canvas.drawBitmap(outputBitmap, 0, 0, null);
  34. if (mFpsMeter != null) {
  35. mFpsMeter.measure();
  36. mFpsMeter.draw(canvas, 20, 30);
  37. }
  38. getHolder().unlockCanvasAndPost(canvas);
  39. }
  40. }


步骤3: 增加下面这个方法(得到屏幕宽高比例)

  1. private float getRatio(int widthSource, int heightSource, int widthTarget, int heightTarget) {
  2. if (widthTarget <= heightTarget) { //
  3. return (float) heightTarget / (float) heightSource;
  4. } else {
  5. return (float) widthTarget / (float) widthSource;
  6. }
  7. }


结果可以看到,在竖屏状态下也可以全屏了,但处理速度有所下降。


方法二

deliverAndDrawFrame()函数中,修改以下部分


  1. if (canvas != null) {
  2. canvas.rotate(90,0,0);
  3. float scale = canvas.getWidth() / (float)mCacheBitmap.getHeight();
  4. float scale2 = canvas.getHeight() / (float)mCacheBitmap.getWidth();
  5. if(scale2 > scale){
  6. scale = scale2;
  7. }
  8. if (scale != 0) {
  9. canvas.scale(scale, scale,0,0);
  10. }
  11. canvas.drawBitmap(mCacheBitmap, 0, -mCacheBitmap.getHeight(), null);
  12. // canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
  13. Log.d(TAG, "mStretch value: " + mScale);
  14. /* if (mScale != 0) {
  15. canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
  16. new Rect((int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2),
  17. (int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2),
  18. (int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2 + mScale*mCacheBitmap.getWidth()),
  19. (int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2 + mScale*mCacheBitmap.getHeight())), null);
  20. } else {
  21. canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
  22. new Rect((canvas.getWidth() - mCacheBitmap.getWidth()) / 2,
  23. (canvas.getHeight() - mCacheBitmap.getHeight()) / 2,
  24. (canvas.getWidth() - mCacheBitmap.getWidth()) / 2 + mCacheBitmap.getWidth(),
  25. (canvas.getHeight() - mCacheBitmap.getHeight()) / 2 + mCacheBitmap.getHeight()), null);
  26. }*/

方法三:


方法一和方法二经过实测,存在一定的问题,且会影响颜色跟踪处理速度。
方法三则采用了OPENCV自带的函数实现了相应的全屏,且处理速度也跟上了。

CameraBridgeViewBase.java 文件修改

以下以官方的颜色检测例程为例修改

旋转函数

  1. //Imgproc.drawContours(mRgba,contours, -1, CONTOUR_COLOR); //在这个位置下添加
  2. Core.transpose(this.mRgba,this.mRgbaT); //转置函数,可以水平的图像变为垂直
  3. Imgproc.resize(this.mRgbaT,this.mRgbaF, this.mRgbaF.size(), 0.0D, 0.0D, 0); //将转置后的图像缩放为mRgbaF的大小
  4. Core.flip(this.mRgbaF, this.mRgba,1); //flipCode>0将mRgbaF水平翻转(沿Y轴翻转)得到mRgba

修改坐标转换算法(在涉及到坐标转换的函数里修改,如onTouch函数为例)
改为 
  1. int cols = mRgba.cols();
  2. int rows = mRgba.rows();
  3. // int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
  4. //int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;
  5. int x =(int)(event.getX()/mOpenCvCameraView.getWidth()*cols);
  6. int y =(int)(event.getY()/mOpenCvCameraView.getHeight()*rows);
05/13 项目地址 链接















 
                    
            
                

相关文章:

  • 2021-05-16
  • 2021-08-18
  • 2022-12-23
  • 2022-12-23
  • 2021-10-09
  • 2022-12-23
  • 2022-02-12
  • 2021-05-27
猜你喜欢
  • 2021-09-03
  • 2022-12-23
  • 2021-05-30
  • 2021-06-26
  • 2022-01-02
  • 2021-08-11
相关资源
相似解决方案