Camera_API2_notes

本文是Camera API 2的学习记录,介绍了CameraManager、CameraDevices等主要部分。还讲述添加额外预览的方法,包括复制主摄预览和添加不同格式预览数据。此外,提到水平镜像翻转前置摄像头预览的实现,最后指出使用中在回调和多线程方面需注意的问题。

Camera API 2 学习记录

本文是学习camera API 2 过程一些的记录。文档大部分来自官网,代码基本上来自Google Camera2Basic
在这里插入图片描述

1. 几个主要部分

CameraManager - 枚举,查询camera 数量,open camera 设备

CameraDevices - 代表单个相机,创建会话或请求

CameraCaptureSession - 要从摄像头拍照或是预览图像,应用程序必须首先使用createCaptureSession(List outputs, CameraCaptureSession.StateCallback callback, Handler handler) 创建一个带有一组输出Surface 的camera capture session。
@param outputs The new set of Surfaces that should be made available as targets for captured image data.
mCameraDevice.createCaptureSession()

CaptureRequest - 应用需要构建一个CaptureRequest, 它定义了所有拍照参数,同时这个Request 还列出了哪些配置的输出Surface 应该用作此capture 的目标。
@param outputTarget Surface to use as an output target for this request
每个Surface必须预先配置适当的大小和格式(如果适用),以匹配摄像机设备可用的大小和格式。 目标Surface可以从各种类中获得,包括SurfaceView,SurfaceTexture via Surface(SurfaceTexture),MediaCodec,MediaRecorder,Allocation和ImageReader。
(后面单独写一篇介绍Surface 的)。

CaptureResult - 包含capture 的部分配置信息,sensor 焦距闪光灯信息和最终的输出buffer。

2. 添加额外的预览

2.1 复制一个主摄的预览

在createCaptureSession(List outputs, CameraCaptureSession.StateCallback callback, Handler handler) 的第一个参数,添加一个surface 到list,这个surface 直接由view 上的TextureView 而来,同时这个surface 需要通过到CaptureRequest.Builder 的addTarget 方法添加到preview 的request 中去,之后预览内容将会直接显示到该控件上。
在这里插入图片描述
参考代码: https://github.com/hcz017/android-Camera2Basic/tree/add_another_main_preview

2.2 添加另一个格式的预览数据并显示

上一种情况我们直接从view 种拿到surface,并没有对这一路预览数据的格式做设置(默认为PRIVATE 格式),如果我们有格式的要求,就需要通过ImagerReader 来设置。

mSecImageReader = ImageReader.newInstance(secLargest.getWidth(),
                            secLargest.getHeight(), imageFormat, /*maxImages*/2);
                    mSecImageReader.setOnImageAvailableListener(
                            mOnSecImageAvailableListener, mBackgroundHandler);

之后要把这个ImagerReader 的surface 添加到preview 的request.builder 和createCaptureSession 的surface list 中去 mPreviewRequestBuilder.addTarget(mSecImageReader.getSurface()); 之后通过onImageAvailable 的回调就可以取得实时预览的数据,通过格式转换把数据转换成bitmap 就可以draw 到TextureView 上(从性能上考虑这不是最优方案)。
在这里插入图片描述
如果添加到拍照的request 中去,则会在拍照时候回调onImageAvailable,同时拍两种格式的照片就是这样做到的。
参考代码: https://github.com/hcz017/android-Camera2Basic/tree/sec_format_preview

3. 水平镜像翻转前置摄像头预览

在API 1 上,调用setFlip() 防范传入想翻转的方向就可以了,在API 上没有对应的方法,在系统源码中系统会根据摄像头的朝向决定在屏幕上渲染时是否翻转图像内容
SurfaceTextureRenderer.java

drawFrame(mSurfaceTexture, holder.width, holder.height,
                            (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
                                    FLIP_TYPE_HORIZONTAL : FLIP_TYPE_NONE);

那么在API 2 上我想到的一个方法便是,在渲染到屏幕上之前截取预览数据,把图像内容变换后再渲染显示。

这里就用到了自定义的 GLSurfaceView,把GLSurfaceView 作为显示预览的控件,GLSV 的surface 添加到builder 和createCaptureSession 的surface list,之后通过修改映射点的位置,把左右调换顺序实现预览图象的水平翻转。这里没有用到ImageReader,如果需要其他格式或者二次处理需求可以使用ImageReader 获得数据后再绘制到GLSurfaceView 上。
在这里插入图片描述
参考代码: https://github.com/hcz017/android-Camera2Basic/tree/mirror_flip_front_camera_preview

4. 问题

在onImageAvailable 回调中,用完image 后及时close image。另外如果时多线程的话,注意view destory 和停止渲染预览的先后关系。有可能会出现view 已经销毁了但是还在试图渲染新的图像,此时会报错。

参考链接

android.hardware.camera2

CameraCaptureSession

CameraDevice

(gaussian_splatting) D:\gaussian-splatting>python train.py -s data Optimizing A module that was compiled using NumPy 1.x cannot be run in NumPy 2.0.2 as it may crash. To support both 1.x and 2.x versions of NumPy, modules must be compiled with NumPy 2.0. Some module may need to rebuild instead e.g. with 'pybind11>=2.12'. If you are a user of the module, the easiest solution will be to downgrade to 'numpy<2' or try to upgrade the affected module. We expect that some modules will need time to support NumPy 2. Traceback (most recent call last): File "D:\gaussian-splatting\train.py", line 276, in <module> safe_state(args.quiet) File "D:\gaussian-splatting\utils\general_utils.py", line 132, in safe_state torch.manual_seed(0) File "C:\Users\26346\anaconda3\envs\gaussian_splatting\lib\site-packages\torch\random.py", line 46, in manual_seed return default_generator.manual_seed(seed) C:\Users\26346\anaconda3\envs\gaussian_splatting\lib\site-packages\torch\random.py:46: UserWarning: Failed to initialize NumPy: _ARRAY_API not found (Triggered internally at C:\cb\pytorch_1000000000000\work\torch\csrc\utils\tensor_numpy.cpp:84.) return default_generator.manual_seed(seed) Output folder: ./output/d2338681-1 [08/11 19:28:25] Tensorboard not available: not logging progress [08/11 19:28:25] Reading camera 2/2 [08/11 19:28:25] Converting point3d.bin to .ply, will happen only the first time you open the scene. [08/11 19:28:25] Loading Training Cameras [08/11 19:28:25] Traceback (most recent call last): File "D:\gaussian-splatting\train.py", line 282, in <module> training(lp.extract(args), op.extract(args), pp.extract(args), args.test_iterations, args.save_iterations, args.checkpoint_iterations, args.start_checkpoint, args.debug_from) File "D:\gaussian-splatting\train.py", line 51, in training scene = Scene(dataset, gaussians) File "D:\gaussian-splatting\scene\__init__.py", line 73, in __init__ self.train_cameras[resolution_scale] = cameraList_from_camInfos(scene_info.train_cameras, resolution_scale, args, scene_info.is_nerf_synthetic, False) File "D:\gaussian-splatting\utils\camera_utils.py", line 73, in cameraList_from_camInfos camera_list.append(loadCam(args, id, c, resolution_scale, is_nerf_synthetic, is_test_dataset)) File "D:\gaussian-splatting\utils\camera_utils.py", line 63, in loadCam return Camera(resolution, colmap_id=cam_info.uid, R=cam_info.R, T=cam_info.T, File "D:\gaussian-splatting\scene\cameras.py", line 42, in __init__ resized_image_rgb = PILtoTorch(image, resolution) File "D:\gaussian-splatting\utils\general_utils.py", line 23, in PILtoTorch resized_image = torch.from_numpy(np.array(resized_image_PIL)) / 255.0 RuntimeError: Numpy is not available
最新发布
11-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值