openCv CameraBridgeViewBase 竖屏显示对应的修改

为了处理手机摄像头的图像,试图用openCv解决问题。尝试了openCv的demo,都是横屏显示,在手机上使用并不方便。
经过一些尝试,对org.opencv.android(v4.1.0)做了少量修改,实现了竖屏显示。

  1. Manifest
    毫无疑问,为了实现竖屏显示,必须设置屏幕方向
       android:screenOrientation="portrait"
  1. CameraBridgeViewBase.CvCameraViewListener2
    这是必须在应用程序中实现的接口,包括三个监听器。
	private var rgbaMat: Mat? = null
	override fun onCameraViewStarted(width: Int, height: Int) {
        rgbaMat = Mat(width, height, CvType.CV_8UC4)
    }
    override fun onCameraViewStopped() {
        rgbaMat?.release()
    }
    override fun onCameraFrame(inputFrame: CameraBridgeViewBase.CvCameraViewFrame?): Mat? {
        rgbaMat = inputFrame?.rgba()
        Core.rotate(rgbaMat, rgbaMat, Core.ROTATE_90_CLOCKWISE)
        return rgbaMat
    }

  监听器用kotlin实现,在onCameraFrame取得相机帧数据后,顺时针旋转90°,返回到屏幕上。此时预览图像与竖屏一致,但不是全屏。

  1. CameraBridgeViewBase
    看来仅仅在自家APP上动手脚,不能完全解决问题,只好对SDK源代码下手。
    // NOTE: On Android 4.1.x the function must be called before SurfaceTexture constructor!
   protected void AllocateCache()
   {
//        mCacheBitmap = Bitmap.createBitmap(mFrameWidth, mFrameHeight, Bitmap.Config.ARGB_8888);
       mCacheBitmap = Bitmap.createBitmap(mFrameHeight, mFrameWidth, Bitmap.Config.ARGB_8888);
   }
    protected Size calculateCameraFrameSize(List<?> supportedSizes, ListItemAccessor accessor, int surfaceWidth, int surfaceHeight) {
        int calcWidth = 0;
        int calcHeight = 0;

        int maxAllowedWidth = (mMaxWidth != MAX_UNSPECIFIED && mMaxWidth < surfaceWidth)? mMaxWidth : surfaceWidth;
        int maxAllowedHeight = (mMaxHeight != MAX_UNSPECIFIED && mMaxHeight < surfaceHeight)? mMaxHeight : surfaceHeight;

        for (Object size : supportedSizes) {
            int width = accessor.getWidth(size);
            int height = accessor.getHeight(size);

//            if (width <= maxAllowedWidth && height <= maxAllowedHeight) {
            if (height <= maxAllowedWidth && width <= maxAllowedHeight) {
                if (width >= calcWidth && height >= calcHeight) {
                    calcWidth = (int) width;
                    calcHeight = (int) height;
                }
            }
        }
        return new Size(calcWidth, calcHeight);
    }

  修改处已经标出,但仍然得不到全屏显示。
4. JavaCameraView
  原来这里也需要修改。

    protected boolean initializeCamera(int width, int height) {
    ...
//		mScale = Math.min(((float)height)/mFrameHeight, ((float)width)/mFrameWidth); 
   		mScale = Math.min(((float)width)/mFrameHeight, ((float)height)/mFrameWidth); 
    ...
    }

  至此,以org.opencv.android.JavaCameraView为基类的视频View可以得到全竖屏显示。
5. JavaCamera2View
  对于以org.opencv.android.JavaCamera2View为基类的View来说,修改有所不同。

    @Override
    protected boolean connectCamera(int width, int height) {
    ...
       if ((getLayoutParams().width == LayoutParams.MATCH_PARENT) && (getLayoutParams().height == LayoutParams.MATCH_PARENT))
//           mScale = Math.min(((float)height)/mFrameHeight, ((float)width)/mFrameWidth);
           mScale = Math.min(((float)width)/mFrameHeight, ((float)height)/mFrameWidth);
       else
           mScale = 0;
    ...
    {

  如果不修改这里,图像会显示怪异的颜色。

    private class JavaCamera2Frame implements CvCameraViewFrame {
    	...
        @Override
        public Mat rgba() {
        	...
        	else if (mPreviewFormat == ImageFormat.YUV_420_888) {
                assert (mUVFrameData != null);
//                Imgproc.cvtColorTwoPlane(mYuvFrameData, mUVFrameData, mRgba, Imgproc.COLOR_YUV2RGBA_NV21);
                Imgproc.cvtColorTwoPlane(mYuvFrameData, mUVFrameData, mRgba, Imgproc.COLOR_YUV2BGRA_NV21);
		...
    {

  经过上述修改,虽然能够实现竖屏的全屏显示,但是由于图像数据90°旋转处理的资源占用较多,使得预览帧率下降严重,视频有迟滞现象,最终没有采用这个方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值