【发布时间】:2021-06-25 07:18:58
【问题描述】:
我目前正在使用android-demo-app/ObjectDetection/ 在Temi Robot 上,预加载的图像到目前为止工作正常,但是当我按“实时”进入实时对象检测屏幕时,它向右旋转了 90 度。
Temi 机器人在屏幕的同一侧只有一个前置摄像头。
我尝试更改textureView.setTransform() imageAnalysisConfig.Builder().setTargetRotation() imageAnalysis.setTargetRotation() 但无济于事
还尝试将activity标签下的AndroidManifest.xmlscreenOrientation更改为fullSenor或Landscape,但没有任何改变。
我一直在 Android Developer CameraX 页面上上下寻找答案 first link second link 但我找不到任何答案。也许我不够聪明,无法在这里找到解决方案。
非常感谢任何帮助!
AbstactCameraXActivity.java
private void setupCameraX() {
final TextureView textureView = getCameraPreviewTextureView();
final PreviewConfig previewConfig = new PreviewConfig.Builder().build();
final Preview preview = new Preview(previewConfig);
// Matrix m = new Matrix();
// m.postRotate(180);
// textureView.setTransform(m); //not working
preview.setOnPreviewOutputUpdateListener(output -> textureView.setSurfaceTexture(output.getSurfaceTexture()));
final var imageAnalysisConfig =
new ImageAnalysisConfig.Builder()
.setTargetResolution(new Size(500, 500))
.setCallbackHandler(mBackgroundHandler)
.setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
//.setTargetRotation(Surface.ROTATION_0) // not working
.build();
imageAnalysis = new ImageAnalysis(imageAnalysisConfig);
imageAnalysis.setAnalyzer((image, rotationDegrees) -> {
if (SystemClock.elapsedRealtime() - mLastAnalysisResultTime < 500) {
return;
}
final R2 result = analyzeImage(image, rotationDegrees);
if (result != null) {
mLastAnalysisResultTime = SystemClock.elapsedRealtime();
runOnUiThread(() -> applyToUiAnalyzeImageResult(result));
}
});
//imageAnalysis.setTargetRotation(Surface.ROTATION_180); // not working
CameraX.bindToLifecycle(this, preview, imageAnalysis);
}
ObjectDetectionActivity.java
@Override
@WorkerThread
@Nullable
protected AnalysisResult analyzeImage(ImageProxy image, int rotationDegrees) {
try {
if (mModule == null) {
mModule = LiteModuleLoader.load(MainActivity.assetFilePath(getApplicationContext(), "yolov5s.torchscript.ptl"));
}
} catch (IOException e) {
Log.e("Object Detection", "Error reading assets", e);
return null;
}
Bitmap bitmap = imgToBitmap(Objects.requireNonNull(image.getImage()));
Matrix matrix = new Matrix();
matrix.postRotate(90.0f);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, PrePostProcessor.mInputWidth, PrePostProcessor.mInputHeight, true);
final Tensor inputTensor = TensorImageUtils.bitmapToFloat32Tensor(resizedBitmap, PrePostProcessor.NO_MEAN_RGB, PrePostProcessor.NO_STD_RGB);
IValue[] outputTuple = mModule.forward(IValue.from(inputTensor)).toTuple();
final Tensor outputTensor = outputTuple[0].toTensor();
final float[] outputs = outputTensor.getDataAsFloatArray();
float imgScaleX = (float)bitmap.getWidth() / PrePostProcessor.mInputWidth;
float imgScaleY = (float)bitmap.getHeight() / PrePostProcessor.mInputHeight;
float ivScaleX = (float)mResultView.getWidth() / bitmap.getWidth();
float ivScaleY = (float)mResultView.getHeight() / bitmap.getHeight();
final ArrayList<Result> results = PrePostProcessor.outputsToNMSPredictions(outputs, imgScaleX, imgScaleY, ivScaleX, ivScaleY, 0, 0);
return new AnalysisResult(results);
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.pytorch.demo.objectdetection">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:configChanges="orientation"
android:screenOrientation="fullSensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ObjectDetectionActivity"
android:configChanges="orientation"
android:screenOrientation="fullSensor">
</activity>
</application>
</manifest>
更新
我想我现在可能知道问题所在了。在 ObjectDetectionActivity 的 setupCameraX() 方法中,我应该操纵 textureView 并操纵矩阵变换的枢轴是我需要的。我开始在屏幕上看到一些cameraView。但是我不知道这个参数中需要的 x 和 y 是什么...
final TextureView textureView = getCameraPreviewTextureView();
final PreviewConfig previewConfig = new PreviewConfig.Builder().build();
final Preview preview = new Preview(previewConfig);
Matrix m = new Matrix();
m.postRotate(180,x,y);//potential solution here.
textureView.setTransform(m); //not working
preview.setOnPreviewOutputUpdateListener(output -> textureView.setSurfaceTexture(output.getSurfaceTexture()));
【问题讨论】:
-
问题在于预览表面(来自 SurfaceTexture),需要对其进行配置以正确转换相机提供的图像(帧)。 CameraX's docs 稍微解释一下。或者,CameraX 提供了一个取景器来处理这些问题,PreviewView。你不使用它有什么原因吗?
-
我找不到 PreviewView,让我猜是因为我的 CameraX 版本 1.0.0-alpha05... 我只是在关注一个我在 CameraX 中没有经验的 pytorch 示例
标签: java android-manifest robot android-camerax