1

我的代码设置了所有的曝光特征。
两个问题:

  1. 当我在 Pixel 3 (Android 10) 上运行代码时,生成的图像看起来比在 OnePlus 6T (Android 9.0) 上捕获的相同场景要亮近2级。检查生成的EXIF 数据显示两张图像中的曝光设置相同。

  2. 我试图通过设置色调映射曲线来强制伽玛曲线,认为这可能是差异的根源,但这似乎在任何一种设备上都不起作用(基于将伽玛设置为 1,这应该会导致非常平坦的图像)。

欢迎任何/所有建议!我被难住了。

    set(requestBuilder,CaptureRequest.CONTROL_MODE,CONTROL_MODE_AUTO );
set(requestBuilder,CaptureRequest.CONTROL_CAPTURE_INTENT, CONTROL_CAPTURE_INTENT_MANUAL);
set(requestBuilder,CaptureRequest.CONTROL_AE_MODE,CONTROL_AE_MODE_OFF);
set(requestBuilder,CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
set(requestBuilder,CaptureRequest.SENSOR_EXPOSURE_TIME, (long) (exposureSettings.shutterSpeed * nanosPerSecond));
set(requestBuilder,CaptureRequest.LENS_APERTURE, exposureSettings.fStop);
set(requestBuilder,CaptureRequest.SENSOR_SENSITIVITY, Math.round(exposureSettings.iso));
setGamma(requestBuilder, 1.0f); //fixme:
set(requestBuilder,CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,0);
set(requestBuilder,CaptureRequest.CONTROL_AF_MODE,CONTROL_AF_MODE_OFF);
set(requestBuilder,CaptureRequest.LENS_FOCUS_DISTANCE,0.0f);// infinity
set(requestBuilder,CaptureRequest.CONTROL_AWB_MODE,CONTROL_AWB_MODE_DAYLIGHT);
set(requestBuilder,CaptureRequest.LENS_FOCAL_LENGTH, availableFocalLengths[0]);//todo:support multiple focal lengths.
requestBuilder.addTarget(imageCaptureSurface);
imageCaptureRequest = requestBuilder.build();
//
//
public <T> void set(@NonNull CaptureRequest.Builder requestBuilder,
                                        @NonNull CaptureRequest.Key<T> key,
                                        T value)
{ Log.d(TAG,String.format("requestBuilder.set(key:%s = %s)",key.getName(),value));
    requestBuilder.set(key, value);
}
//
static CaptureRequest.Builder setGamma(CaptureRequest.Builder builder,
                                                                             float gamma)
{ int curveSize = 16;
    builder.set(CaptureRequest.TONEMAP_MODE,
                            CaptureRequest.TONEMAP_MODE_CONTRAST_CURVE);
    setToneMapCurves(builder,
                                     gammaCurve(gamma,curveSize), //red
                                     gammaCurve(gamma,curveSize), //green
                                     gammaCurve(gamma,curveSize)); //blue all same.
    return builder;
}
//
static CaptureRequest.Builder setToneMapCurves(CaptureRequest.Builder builder,
                                                                                            float[] redCurve,
                                                                                            float[] greenCurve,
                                                                                            float[] blueCurve)
{ TonemapCurve toneMapCurve = new TonemapCurve(redCurve,greenCurve,blueCurve);
    builder.set(CaptureRequest.TONEMAP_CURVE,toneMapCurve);
    return builder;
}
//
private static float[] gammaCurve(float gamma, int numPoints)
{ int idx = 0;
    Log.i(TAG, String.format("Using gamma of %f to build tone map curve.",gamma));
    if (gamma > 0)
        {   float curve[] = new float[numPoints*2];//
            for (float inValue = 0f; inValue <= 1.0f; inValue += 1.0f / (numPoints - 1))
                {
                    curve[idx++] = inValue;
                    curve[idx++] = (float) Math.pow(inValue, gamma);
                    if (debug)
                        Log.d(TAG, String.format("Added tone curve point [%d]:(%f, %f)",
                                                                         idx - 2, inValue, curve[idx - 1]));
                }
            return curve;
        }

    // sRGB curve approximates gamma = 1/2.2, with small linear front.
    if (gamma == -1.0f) //sRGB
        {   float curve[] =
                { 0.0000f, 0.0000f, //stick the small linear section in here
                    0.0667f, 0.2864f,
                    0.1333f, 0.4007f,
                    0.2000f, 0.4845f,
                    0.2667f, 0.5532f,
                    0.3333f, 0.6125f,
                    0.4000f, 0.6652f,
                    0.4667f, 0.7130f,
                    0.5333f, 0.7569f,
                    0.6000f, 0.7977f,
                    0.6667f, 0.8360f,
                    0.7333f, 0.8721f,
                    0.8000f, 0.9063f,
                    0.8667f, 0.9389f,
                    0.9333f, 0.9701f,
                    1.0000f, 1.0000f
                };
            return curve;
        }
    return null;
}
4

1 回答 1

0

您没有设置ISO 感光度值,因此两台设备上的默认值可能不同。此外,一加 6T 的相机光圈为 f/1.7,而 Pixel 3 的光圈为 f/1.8。

这些都是固定光圈设备,因此即使曝光和灵敏度设置相同,它们也会在两张图像之间引入 1.8^2/1.7^2 = 1.12x 的亮度差异。

后期处理也可能是一个因素,因此最好的比较是与 RAW 输出。如果设备实现自动 HDR 或类似处理,这主要是一个问题,但通过手动控制,这不太可能。

于 2020-10-27T20:04:25.697 回答