我正在尝试实现this答案中描述的长时间曝光Android Camera2解决方案。
基本上,它试图通过连拍 100 张图像来解决我的 Samsung Galaxy S20+ Camera2 设备报告的“短”最大曝光时间(100 毫秒)的限制,其中 100 x 100 毫秒 = 10 000 毫秒 = 10 秒。曝光时间为 10 秒的照片应该足以在最终图像上看到夜空的星星。 到目前为止,我所做的是在 ISO 800 和 100 ms 设置的手动模式连拍捕获中以
YUV格式硬编码 100 张图像。 当 YUV 图像被捕获并且
可用时,我将使用 RenderScript Intrinsics Replacement Toolkit 通过其 Toolkit.yuvToRgbBitmap 方法将其转换为临时位图图像。此步骤非常有效(而且速度超级快),并且转换后的单个图像在我的房间内拍摄时可以正确显示! 一旦我有了第二个 YUV => 位图图像,我将使用
Toolkit.blend方法和混合模式 Add 将这些图像组合成单个位图图像。一旦下一个新图像从连拍捕获中到达,我就会重复上述步骤,意味着将其与之前组合的图像混合,依此类推... 问题是,当我在夜空下测试上述解决方案时,最终图像仍然是全黑/黑暗,并且我在上面看不到星星,这显然是错误的,因为 ISO 800 的总曝光时间应该是 10 秒绰绰有余!具有 ISO800/10s 的内置三星相机应用程序给了我一个非常漂亮和明亮的结果。
我还尝试了另一种混合模式,如“乘法”等,但结果是相同的:在夜空下拍摄时,最终位图图像是全黑的。
有什么想法,为什么它没有给出预期的结果?
我的代码的相关部分(C#语言):
public void OnImageAvailable(ImageReader? reader) {
var img = reader?.AcquireLatestImage();
if (img == null) return;
switch (img.Format) {
case ImageFormatType.Yuv420888:
// converting the incoming YUV image to byte array
var planes = img.GetPlanes();
var yBuffer = planes[0].Buffer;
var vuBuffer = planes[2].Buffer;
var ySize = yBuffer.Remaining();
var vuSize = vuBuffer.Remaining();
var nv21 = new byte[ySize + vuSize];
_ = yBuffer.Get(nv21, 0, ySize);
_ = vuBuffer.Get(nv21, ySize, vuSize);
// convering the byte array to an RGBA Bitmap image
var TempBmp = Toolkit.Instance.YuvToRgbBitmap(nv21, img.Width, img.Height, YuvFormat.Nv21);
// combining the incoming images to a single Bitmap image,
// in case of the very first incoming image use it as a base
if (FinalBitmap == null) FinalBitmap = TempBmp;
else Toolkit.Instance.Blend(BlendingMode.Add, FinalBitmap, TempBmp);
img.Close();
break;
default:
// format not supported!!!
break;
}
}
首先,通过使用“混合”,您可以将图像平均在一起。每个图像都有您想要的信号级别的 1/100,因此无论您将多少张图像混合在一起,平均值仍然仅为信号的 1/100。
您需要将图像
添加在一起 - 然后将它们的曝光时间加在一起(理想情况下),您就可以获得所需的 10 秒曝光。我不知道是否有标准模式,但它也只是一个 for 循环。 第二,信号强度很低!假设您拍摄的东西在 10 秒曝光中显示为中灰色 - RGB 值
(128,128,128)
。每个单独的图像的值只有该值的 1/100,所以类似于
(1,1,1) +- 1
。相机设备在生成 YUV 数据时进行的 8 位转换和降噪很可能会消除最小量级的信号。所以你至少应该关闭所有降噪功能。但理想情况下,您需要使用 RAW 图像缓冲区来执行此操作。那么你至少有 10 位可以使用(因此每个图像至少有 (5,5,5)
左右的值)。当然,这需要您做更多的工作,因为从 RAW 转换为 RBG 更加乏味。