所以,鑽入問題後,我已經找到了問題的根源。
讓我們來看看OpenCV JavaCameraView
類和它的CameraBridgeViewBase
基類。 問題在於,在onPreviewFrame
方法中收到的byte[]
數組中的相機幀被錯誤地解碼。
的代碼的確切地方,解碼過程發生是Mat rgba()
法在內部JavaCameraFrame
類JavaCameraView
的實現:
public Mat rgba() {
Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4);
return mRgba;
}
正如我們看到的,Imgproc.cvtColor(...)方法用於將幀從YUV轉換爲RGBA。 NV21 YUV -> RGBA
轉換髮生在那裏。在初始化過程中,我們將格式設置爲NV21,所以這應該是正確的。此外,every Android device should support NV21。另外,我們可以檢查設備是否接受使用調試器的格式爲:
protected boolean initializeCamera(int width, int height) {
...
params.setPreviewFormat(ImageFormat.NV21);
...
mCamera.setParameters(params);
...
params = mCamera.getParameters();
Log.d(TAG, String.format("Actual preview format is 0x%X", params.getPreviewFormat()));
}
兩個手機(HTC感覺)和模擬器報道爲使用確實NV21。但是,如果我們將COLOR_YUV2RGBA_NV21
更改爲COLOR_YUV2RGB_I420
(YV12和I420是相同的東西,只需將Y和V倒置;),我們將看到仿真器最終將獲得適當的顏色空間。在params.setPreviewFormat(ImageFormat.NV21);
中將NV21更改爲YV12我們會得到類似的結果。看起來像是在Imgproc.cvtColor或Android中有bug。
這是解決方案。 更改public Mat rgba()
方式如下:
public Mat rgba() {
if (previewFormat == ImageFormat.NV21) {
Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4);
}
else if (previewFormat == ImageFormat.YV12) {
Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2RGB_I420, 4); // COLOR_YUV2RGBA_YV12 produces inverted colors
}
return mRgba;
}
previewFormat
是一個新的int
變量,它是這樣聲明:
private int previewFormat = ImageFormat.NV21;
添加以下更改初始化:
protected boolean initializeCamera(int width, int height) {
...
params.setPreviewFormat(ImageFormat.NV21);
// "generic" = android emulator
if (Build.BRAND.equalsIgnoreCase("generic")) {
params.setPreviewFormat(ImageFormat.YV12);
}
...
mCamera.setParameters(params);
params = mCamera.getParameters();
previewFormat = params.getPreviewFormat();
...
}
重要:
請注意:這只是一個臨時解決方案,以使OpenCV在我的情況下可以與仿真器一起使用。應該進一步研究。檢查設備是否在onPreviewFrame中使用正確的圖像格式很容易。當我有一些時間時,我會回到這個。
使用Android Studio 1.5.1並模擬API 23時,上述僅在''generic''被交換到'「android」'時才起作用。儘管如此,改變之後的工作仍然完美無瑕。 – 2016-01-26 19:55:20
我只是試過這個,它工作正常。雖然,我不確定這是否是首選的方法,或者應該以不同的方式修復。我在OpenCV存儲庫中創建了一個問題,如果接受它,可以將其作爲請求提交。 – 2017-02-09 23:24:10
爲了可追溯性:https://github.com/opencv/opencv/issues/8166 – 2017-02-14 01:26:16