android设备调用usb外置摄像头方法及案例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/piaoxuezhong/article/details/84564980

android调用内置摄像头的方法相对比较简单,参考实例也比较多,但是针对调用外置摄像头的方法介绍比较少,本篇对现有的 资料进行汇总,并给出相关案例如下:

https://blog.csdn.net/fengshiguang2012/article/details/79569280

https://blog.csdn.net/andrexpert/article/details/78324181

https://blog.csdn.net/CrazyMo_/article/details/58139934

开源项目:

https://github.com/saki4510t/UVCCamera

https://github.com/rhllasag/FLIR-App

https://github.com/jiangdongguo/AndroidUSBCamera

https://github.com/search?q=mUVCCameraView+opencv&type=Code

重点总结:

查找资料过程中,可以发现目前调用外置usb摄像头的方法基本上都是基于UVCCamera这个开源项目,原理是android设备具备otg功能,通过检测android设备是否有usb设备连接,进一步采集usb摄像头所采集到的图像数据。

    // ********** 显示摄像头采集的图像结果 *************
    private void startPreview() {
		synchronized (mSync) {
			if (mCameraHandler != null) {
                final SurfaceTexture st = mUVCCameraView.getSurfaceTexture();
				mCameraHandler.setPreviewCallback(mIFrameCallback);
                mCameraHandler.startPreview(new Surface(st));
			}
		}
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
            }
        });
        updateItems();
    }

这里对图像的显示方法进行总结,图像显示主要有两种方法,一种是:

final SurfaceTexture st = mUVCCameraView.getSurfaceTexture();
mCameraHandler.startPreview(new Surface(st));

另外一种是:

    mCameraHandler.setPreviewCallback(mIFrameCallback);
    //*************** IFrameCallback ***************
    private final IFrameCallback mIFrameCallback = new IFrameCallback() {
        @Override
        public void onFrame(final ByteBuffer frame) {
            frame.clear();
            if(!isActive() || isInCapturing){
                return;
            }
            if(bitmap == null){
                Toast.makeText(MainActivity.this, "错误:Bitmap为空", Toast.LENGTH_SHORT).show();
                return;
            }
            synchronized (bitmap) {
                srcBitmap.copyPixelsFromBuffer(frame);
                WarnText = "";

                if(bitmap.getWidth() != srcBitmap.getWidth() || bitmap.getHeight() !=  srcBitmap.getHeight()){
                    bitmap = Bitmap.createBitmap(srcBitmap.getWidth(),  srcBitmap.getHeight(), Bitmap.Config.RGB_565);
                }
                Mat src = new Mat ();
                Utils.bitmapToMat(srcBitmap,src);
                calculate(srcBitmap.getNativeObjAddr(), mLeft, mTop,  mWidth,  mHeight);
                Utils.matToBitmap(srcBitmap,bitmap);                   
            }
            mImageView.post(mUpdateImageTask);
        }
    };

第二种方法我将 ByteBuffer 类型的数据转化为opencv的Mat类型,但是,这种方法采集到的图像相比于第一种图像质量要差一些,具体原因不是很清楚,如果有研究明白的还希望告知一下,谢谢。

调用opencv时,需注意在程序中加入:

   private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    Log.i(TAG, "OpenCV loaded successfully");
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };

其他,像usb 设备的连接,断开等,没有详细研究,可以参见程序部分:

   private final OnDeviceConnectListener mOnDeviceConnectListener = new OnDeviceConnectListener() {
        @Override
        public void onAttach(final UsbDevice device) {
            Toast.makeText(MainActivity.this, "USB_DEVICE_ATTACHED", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onConnect(final UsbDevice device, final UsbControlBlock ctrlBlock, final boolean createNew) {
            if (DEBUG) Log.v(TAG, "onConnect:");
            synchronized (mSync) {
                if (mCameraHandler != null) {
	                mCameraHandler.open(ctrlBlock);
	                startPreview();
	                updateItems();
				}
            }
        }

        @Override
        public void onDisconnect(final UsbDevice device, final UsbControlBlock ctrlBlock) {
            if (DEBUG) Log.v(TAG, "onDisconnect:");
            synchronized (mSync) {
                if (mCameraHandler != null) {
                    queueEvent(new Runnable() {
                        @Override
                        public void run() {
                            try{
                                // maybe throw java.lang.IllegalStateException: already released
                                mCameraHandler.setPreviewCallback(null);
                            }
                            catch(Exception e){
                                e.printStackTrace();
                            }
                            mCameraHandler.close();
                        }
                    }, 0);
				}
            }
			setCameraButton(false);
        }
        @Override
        public void onDettach(final UsbDevice device) {
            Toast.makeText(MainActivity.this, "USB_DEVICE_DETACHED", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancel(final UsbDevice device) {
            setCameraButton(false);
        }
    };

后续会补充,把项目整理提交到github上。

猜你喜欢

转载自blog.csdn.net/piaoxuezhong/article/details/84564980