Camerax Analyzer ImageProxy - 图像已关闭
Camerax Analyzer ImageProxy - Image Already Closed
我正在使用 CameraX(测试版)并使用带有执行程序的 Analyzer 来分析图像并在其上绘制 bounds/overlay。根据文档,我需要关闭图像代理才能继续将图像获取到分析功能中。当我添加 imageProxy.close() 调用时,它失败并出现 Image Already closed 错误。我在这里错过了什么?
分析器代码:
private val successListener = OnSuccessListener<List<DetectedObject>> { papers ->
isAnalyzing.set(false)
val rectPoints= mutableListOf<Rect>()
Log.d(TAG," overlayRef Info: ${overlayRef.get()}")
for (paper in papers) {
val bounds = paper.boundingBox
val paperId = paper.trackingId
rectPoints+=bounds
Log.d(TAG, "Successful Paper Analysis - Bounds of the paper: $bounds")
Log.d(TAG," Labels found on the paper: ${paper.labels}")
}
Log.d(TAG, "Invoking pointsRectListener for : $rectPoints")
pointsRectListener?.invoke(rectPoints)
}
private val failureListener = OnFailureListener { e ->
isAnalyzing.set(false)
Log.e(TAG, "Paper analysis failure.", e)
}
@SuppressLint("UnsafeExperimentalUsageError")
override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy?.image ?: return
Log.d(TAG,"entered analysis..analysis in progress?$isAnalyzing.get()")
if (!isAnalyzing.get()){
isAnalyzing.set(true)
Log.d(TAG,"No other analysis in progress..so starting analysis now")
val currentTimestamp = System.currentTimeMillis()
if (currentTimestamp - lastAnalyzedTimestamp >= TimeUnit.SECONDS.toMillis(1)) {
currentTimestamp - lastAnalyzedTimestamp
analysisSizeListener?.invoke(Size(imageProxy.width, imageProxy.height))
val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
objectDetector.process(image)
.addOnSuccessListener(successListener)
.addOnFailureListener(failureListener)
}
}
imageProxy.close()
}
我实例化并绑定到生命周期的代码
paperAnalyzer=ImageAnalysis.Builder()
.setTargetAspectRatio(screenAspectRatio)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.setTargetRotation(rotation)
.build()
.also {
it.setAnalyzer(cameraExecutor, PaperAnalyzer( WeakReference(overlayView)).apply {
pointsRectListener = { rectPoints ->
overlayView.rectPoints = rectPoints
}
analysisSizeListener = {
updateOverlayTransform(overlayView, it)
}
}
)
}
cameraProvider.unbindAll()
try {
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture, paperAnalyzer)
// Attach the viewfinder's surface provider to preview use case
preview?.setSurfaceProvider(viewFinder.createSurfaceProvider())
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
您要实现的逻辑似乎是这样的。
fun analyze(imageProxy) {
if (isAnalyzing) {
imageProxy.close() // 1
} else {
val image = imageInput.fromMediaImage(...)
objectDetector.process(image)
.addOnSuccessListener(OnSuccessListener { result ->
// Do something with the result
imageProxy.close() // 2
isAnalyzing.set(false)
})
.addOnFailureListener(OnFailureListener { exception ->
// Do something with the exception
imageProxy.close() // 3
isAnalyzing.set(false)
})
}
}
我可能错了,但看起来你在做 1,而不是 2 和 3。你能更新你的代码以遵循这个模式,看看你是否仍然遇到这个问题。
我正在使用 CameraX(测试版)并使用带有执行程序的 Analyzer 来分析图像并在其上绘制 bounds/overlay。根据文档,我需要关闭图像代理才能继续将图像获取到分析功能中。当我添加 imageProxy.close() 调用时,它失败并出现 Image Already closed 错误。我在这里错过了什么? 分析器代码:
private val successListener = OnSuccessListener<List<DetectedObject>> { papers ->
isAnalyzing.set(false)
val rectPoints= mutableListOf<Rect>()
Log.d(TAG," overlayRef Info: ${overlayRef.get()}")
for (paper in papers) {
val bounds = paper.boundingBox
val paperId = paper.trackingId
rectPoints+=bounds
Log.d(TAG, "Successful Paper Analysis - Bounds of the paper: $bounds")
Log.d(TAG," Labels found on the paper: ${paper.labels}")
}
Log.d(TAG, "Invoking pointsRectListener for : $rectPoints")
pointsRectListener?.invoke(rectPoints)
}
private val failureListener = OnFailureListener { e ->
isAnalyzing.set(false)
Log.e(TAG, "Paper analysis failure.", e)
}
@SuppressLint("UnsafeExperimentalUsageError")
override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy?.image ?: return
Log.d(TAG,"entered analysis..analysis in progress?$isAnalyzing.get()")
if (!isAnalyzing.get()){
isAnalyzing.set(true)
Log.d(TAG,"No other analysis in progress..so starting analysis now")
val currentTimestamp = System.currentTimeMillis()
if (currentTimestamp - lastAnalyzedTimestamp >= TimeUnit.SECONDS.toMillis(1)) {
currentTimestamp - lastAnalyzedTimestamp
analysisSizeListener?.invoke(Size(imageProxy.width, imageProxy.height))
val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
objectDetector.process(image)
.addOnSuccessListener(successListener)
.addOnFailureListener(failureListener)
}
}
imageProxy.close()
}
我实例化并绑定到生命周期的代码
paperAnalyzer=ImageAnalysis.Builder()
.setTargetAspectRatio(screenAspectRatio)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.setTargetRotation(rotation)
.build()
.also {
it.setAnalyzer(cameraExecutor, PaperAnalyzer( WeakReference(overlayView)).apply {
pointsRectListener = { rectPoints ->
overlayView.rectPoints = rectPoints
}
analysisSizeListener = {
updateOverlayTransform(overlayView, it)
}
}
)
}
cameraProvider.unbindAll()
try {
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture, paperAnalyzer)
// Attach the viewfinder's surface provider to preview use case
preview?.setSurfaceProvider(viewFinder.createSurfaceProvider())
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
您要实现的逻辑似乎是这样的。
fun analyze(imageProxy) {
if (isAnalyzing) {
imageProxy.close() // 1
} else {
val image = imageInput.fromMediaImage(...)
objectDetector.process(image)
.addOnSuccessListener(OnSuccessListener { result ->
// Do something with the result
imageProxy.close() // 2
isAnalyzing.set(false)
})
.addOnFailureListener(OnFailureListener { exception ->
// Do something with the exception
imageProxy.close() // 3
isAnalyzing.set(false)
})
}
}
我可能错了,但看起来你在做 1,而不是 2 和 3。你能更新你的代码以遵循这个模式,看看你是否仍然遇到这个问题。