我正在制作一个应用程序,用于使用摄像头处理来自 USB 摄像头的 Orange pi5 上的帧,并在冷启动期间遇到了长时间初始化的问题。
这是我的相机初始化代码:
private fun startCameraPreview() {
cameraProviderFuture = ProcessCameraProvider.getInstance( requireContext() )
cameraProviderFuture.addListener({
val cameraProvider = cameraProviderFuture.get()
bindPreview(cameraProvider) },
ContextCompat.getMainExecutor(requireContext()) )
}
@SuppressLint("RestrictedApi")
private fun bindPreview(cameraProvider : ProcessCameraProvider) {
previewView = viewBinding.previewView
previewView.implementationMode = PreviewView.ImplementationMode.COMPATIBLE
previewView.scaleX = -1f
val preview : Preview = Preview.Builder()
.setResolutionSelector(
ResolutionSelector.Builder().setResolutionStrategy(
ResolutionStrategy(Size(1080, 768),
ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER)
).build())
.build()
val selector = selectExternalOrBestCamera(cameraProvider) //For Usb camera Access
preview.setSurfaceProvider( previewView.surfaceProvider )
val strategy = ResolutionStrategy(Size(640, 480),
ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER)
val imageFrameAnalysis = ImageAnalysis.Builder()
.setResolutionSelector(ResolutionSelector.Builder().setResolutionStrategy(strategy).build())
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
.build()
imageFrameAnalysis.setAnalyzer(Executors.newSingleThreadExecutor(), frameAnalyser )
cameraProvider.bindToLifecycle(this as LifecycleOwner, selector!!, preview , imageFrameAnalysis )
}
我还使用官方文档中的代码来访问 USB 相机选择器
fun selectExternalOrBestCamera(provider: ProcessCameraProvider):CameraSelector? {
val cam2Infos = provider.availableCameraInfos.map {
Camera2CameraInfo.from(it)
}.sortedByDescending {
// HARDWARE_LEVEL is Int type, with the order of:
// LEGACY < LIMITED < FULL < LEVEL_3 < EXTERNAL
it.getCameraCharacteristic(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
}
return when {
cam2Infos.isNotEmpty() -> {
CameraSelector.Builder()
.addCameraFilter {
it.filter { camInfo ->
// cam2Infos[0] is either EXTERNAL or best built-in camera
val thisCamId = Camera2CameraInfo.from(camInfo).cameraId
thisCamId == cam2Infos[0].cameraId
}
}.build()
}
else -> null
}
}
2024-03-05 15:58:14.010 14845-14906 CameraRepository D Added camera: 0
2024-03-05 15:58:14.012 14845-14906 Camera2CameraInfo I Device Level: INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL
2024-03-05 15:58:14.012 14845-14906 CameraValidator D Verifying camera lens facing on rk3588s_s, lensFacingInteger: null
2024-03-05 15:58:14.013 14845-14906 CameraValidator E Camera LensFacing verification failed, existing cameras: [Camera@e0778e4[id=0]]
2024-03-05 15:58:14.014 14845-14906 CameraX W Retry init. Start time 9251708 current time 9253283
androidx.camera.core.impl.CameraValidator$CameraIdListIncorrectException: Expected camera missing from device.
at androidx.camera.core.impl.CameraValidator.validateCameras(CameraValidator.java:97)
at androidx.camera.core.CameraX.lambda$initAndRetryRecursively$2$androidx-camera-core-CameraX(CameraX.java:334)
at androidx.camera.core.CameraX$$ExternalSyntheticLambda3.run(Unknown Source:10)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
Caused by: java.lang.IllegalArgumentException: No available camera can be found
at androidx.camera.core.CameraSelector.select(CameraSelector.java:94)
at androidx.camera.core.impl.CameraValidator.validateCameras(CameraValidator.java:83)
at androidx.camera.core.CameraX.lambda$initAndRetryRecursively$2$androidx-camera-core-CameraX(CameraX.java:334)
at androidx.camera.core.CameraX$$ExternalSyntheticLambda3.run(Unknown Source:10)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
此相机初始化并显示以下消息后:
设备可能会少报摄像头数量。完成初始化任务,因为我们已经达到了最大重试次数。
对此有什么帮助吗?
Added camera: 0
2024-03-05 15:58:15.030 14845-14906 Camera2CameraInfo I Device Level: INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL
2024-03-05 15:58:15.031 14845-14906 CameraValidator D Verifying camera lens facing on rk3588s_s, lensFacingInteger: null
2024-03-05 15:58:15.032 14845-14906 CameraValidator E Camera LensFacing verification failed, existing cameras: [Camera@10741b2[id=0]]
2024-03-05 15:58:15.032 14845-14906 CameraX E The device might underreport the amount of the cameras. Finish the initialize task since we are already reaching the maximum number of retries.
2024-03-05 15:58:15.083 14845-14845 CameraOrientationUtil D getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=false, result=90
2024-03-05 15:58:15.085 14845-14845 CameraOrientationUtil D getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=false, result=90
2024-03-05 15:58:15.094 14845-14845 DynamicRangeResolver D Resolved dynamic range for use case androidx.camera.core.Preview-1b649f9e-f19f-43f5-8882-7ace2058df35 to no compatible HDR dynamic ranges.
DynamicRange@d8ad747{encoding=UNSPECIFIED, bitDepth=0}
->
DynamicRange@c2bc286{encoding=SDR, bitDepth=8}
2024-03-05 15:58:15.099 14845-14845 CameraOrientationUtil D getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=false, result=90
2024-03-05 15:58:15.101 14845-14845 DeferrableSurface D Surface created[total_surfaces=1, used_surfaces=0](androidx.camera.core.processing.SurfaceEdge$SettableSurface@df18112}
2024-03-05 15:58:15.103 14845-14845 DeferrableSurface D Surface created[total_surfaces=2, used_surfaces=0](androidx.camera.core.SurfaceRequest$2@4e29c5e}
2024-03-05 15:58:15.104 14845-14845 DeferrableSurface D New surface in use[total_surfaces=2, used_surfaces=1](androidx.camera.core.SurfaceRequest$2@4e29c5e}
2024-03-05 15:58:15.104 14845-14845 DeferrableSurface D use count+1, useCount=1 androidx.camera.core.SurfaceRequest$2@4e29c5e
我的 CameraX gradle 依赖项:
// CameraX
def camerax_version = "1.3.1"
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
implementation "androidx.camera:camera-video:${camerax_version}"
implementation "androidx.camera:camera-view:${camerax_version}"
implementation "androidx.camera:camera-extensions:${camerax_version}"
我尝试添加
@OptIn(ExperimentalCamera2Interop::class)
对实验方法的注释,我尝试明确指定CameraSelector的镜头类型.requireLensFacing(LENS_FACING_FRONT/BACK/EXTERNAL)
- 没有结果,只有崩溃。
我对这种情况的看法:CameraValidator 无法接受来自 USB 摄像头的镜头值。
有什么帮助吗?
您的设备报告的系统属性与其实际相机硬件之间似乎不匹配。这导致 CameraX 尝试初始化根本不存在的相机。
具体来说,听起来您的设备可能指示存在前置摄像头和/或主摄像头,即使您只连接了外部摄像头。对于正确配置的设备,在这种情况下,PackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) 和 PackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA) 都应返回 false。
此类问题在开发设备上更为常见,这些设备不一定经过与 CTS 认证设备相同的严格配置和测试。
最直接的解决方案是调整设备上的系统属性以匹配物理相机设置。这将确保 CameraX 仅尝试初始化实际存在的相机。