Camera2 API 设置自定义白平衡和色温
Camera2 API Set Custom White Balance & Temperature Color
我正在尝试为我的相机应用程序中的白平衡和温度颜色设置自定义值。我正在使用 camera2 API 并且正在尝试不同的方法来设置此值。我从 excel 文件中找到了一种方法,可以从 100 到 100.000 之间的白平衡值中获取正确的 RGB 温度矩阵 [红色、绿色、蓝色]。
我将此方法附加到 Seekbar 并且它工作正常,当我尝试聚焦白色的东西时出现我的问题,然后它变成粉红色。任何一种光在屏幕上看起来都像粉红色的手电筒。
我是这样设置值的:
mPreviewRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
RggbChannelVector rggb = getTemperatureVector(seekBackSelectedTemperature);
mPreviewRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_GAINS, myRggbChannelVector);
换句话说,我得到矩阵的方法是这个:
public static RggbChannelVector getTemperatureVector (int WhiteBalanceValue){
float InsertTemperature = WhiteBalanceValue;
float temperature = InsertTemperature / 100;
float red;
float green;
float blue;
//Calculate red
if (temperature <= 66)
red = 255;
else {
red = temperature - 60;
red = (float) (329.698727446 * (Math.pow((double) red, -0.1332047592)));
if (red < 0)
red = 0;
if (red > 255)
red = 255;
}
//Calculate green
if (temperature <= 66) {
green = temperature;
green = (float) (99.4708025861 * Math.log(green) - 161.1195681661);
if (green < 0)
green = 0;
if (green > 255)
green = 255;
} else
green = temperature - 60;
green = (float) (288.1221695283 * (Math.pow((double) red, -0.0755148492)));
if (green < 0)
green = 0;
if (green > 255)
green = 255;
//calculate blue
if (temperature >= 66)
blue = 255;
else if (temperature <= 19)
blue = 0;
else {
blue = temperature - 10;
blue = (float) (138.5177312231 * Math.log(blue) - 305.0447927307);
if (blue < 0)
blue = 0;
if (blue > 255)
blue = 255;
}
RggbChannelVector finalTemperatureValue = new RggbChannelVector(red/255,(green/255)/2,(green/255)/2,blue/255);
return finalTemperatureValue;
}
可能是我的CaptureRequest方法不对,没找到解决办法
将模板更改为 Still_capture 或手动模板并使用下一个方法后它起作用了:
captureBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
// adjust color correction using seekbar's params
captureBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
captureBuilder.set(CaptureRequest.COLOR_CORRECTION_GAINS, CameraCapabilities.colorTemperature(Integer.parseInt(awbMode)));
public static RggbChannelVector colorTemperature(int whiteBalance) {
float temperature = whiteBalance / 100;
float red;
float green;
float blue;
//Calculate red
if (temperature <= 66)
red = 255;
else {
red = temperature - 60;
red = (float) (329.698727446 * (Math.pow((double) red, -0.1332047592)));
if (red < 0)
red = 0;
if (red > 255)
red = 255;
}
//Calculate green
if (temperature <= 66) {
green = temperature;
green = (float) (99.4708025861 * Math.log(green) - 161.1195681661);
if (green < 0)
green = 0;
if (green > 255)
green = 255;
} else {
green = temperature - 60;
green = (float) (288.1221695283 * (Math.pow((double) green, -0.0755148492)));
if (green < 0)
green = 0;
if (green > 255)
green = 255;
}
//calculate blue
if (temperature >= 66)
blue = 255;
else if (temperature <= 19)
blue = 0;
else {
blue = temperature - 10;
blue = (float) (138.5177312231 * Math.log(blue) - 305.0447927307);
if (blue < 0)
blue = 0;
if (blue > 255)
blue = 255;
}
Log.v(TAG, "red=" + red + ", green=" + green + ", blue=" + blue);
return new RggbChannelVector((red / 255) * 2, (green / 255), (green / 255), (blue / 255) * 2);
}
另一种可能且更简单的解决方案; 因子 必须介于 0 和 100 之间:
private static RggbChannelVector computeTemperature(final int factor)
{
return new RggbChannelVector(0.635f + (0.0208333f * factor), 1.0f, 1.0f, 3.7420394f + (-0.0287829f * factor));
}
我正在尝试为我的相机应用程序中的白平衡和温度颜色设置自定义值。我正在使用 camera2 API 并且正在尝试不同的方法来设置此值。我从 excel 文件中找到了一种方法,可以从 100 到 100.000 之间的白平衡值中获取正确的 RGB 温度矩阵 [红色、绿色、蓝色]。
我将此方法附加到 Seekbar 并且它工作正常,当我尝试聚焦白色的东西时出现我的问题,然后它变成粉红色。任何一种光在屏幕上看起来都像粉红色的手电筒。
我是这样设置值的:
mPreviewRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
RggbChannelVector rggb = getTemperatureVector(seekBackSelectedTemperature);
mPreviewRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_GAINS, myRggbChannelVector);
换句话说,我得到矩阵的方法是这个:
public static RggbChannelVector getTemperatureVector (int WhiteBalanceValue){
float InsertTemperature = WhiteBalanceValue;
float temperature = InsertTemperature / 100;
float red;
float green;
float blue;
//Calculate red
if (temperature <= 66)
red = 255;
else {
red = temperature - 60;
red = (float) (329.698727446 * (Math.pow((double) red, -0.1332047592)));
if (red < 0)
red = 0;
if (red > 255)
red = 255;
}
//Calculate green
if (temperature <= 66) {
green = temperature;
green = (float) (99.4708025861 * Math.log(green) - 161.1195681661);
if (green < 0)
green = 0;
if (green > 255)
green = 255;
} else
green = temperature - 60;
green = (float) (288.1221695283 * (Math.pow((double) red, -0.0755148492)));
if (green < 0)
green = 0;
if (green > 255)
green = 255;
//calculate blue
if (temperature >= 66)
blue = 255;
else if (temperature <= 19)
blue = 0;
else {
blue = temperature - 10;
blue = (float) (138.5177312231 * Math.log(blue) - 305.0447927307);
if (blue < 0)
blue = 0;
if (blue > 255)
blue = 255;
}
RggbChannelVector finalTemperatureValue = new RggbChannelVector(red/255,(green/255)/2,(green/255)/2,blue/255);
return finalTemperatureValue;
}
可能是我的CaptureRequest方法不对,没找到解决办法
将模板更改为 Still_capture 或手动模板并使用下一个方法后它起作用了:
captureBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
// adjust color correction using seekbar's params
captureBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
captureBuilder.set(CaptureRequest.COLOR_CORRECTION_GAINS, CameraCapabilities.colorTemperature(Integer.parseInt(awbMode)));
public static RggbChannelVector colorTemperature(int whiteBalance) {
float temperature = whiteBalance / 100;
float red;
float green;
float blue;
//Calculate red
if (temperature <= 66)
red = 255;
else {
red = temperature - 60;
red = (float) (329.698727446 * (Math.pow((double) red, -0.1332047592)));
if (red < 0)
red = 0;
if (red > 255)
red = 255;
}
//Calculate green
if (temperature <= 66) {
green = temperature;
green = (float) (99.4708025861 * Math.log(green) - 161.1195681661);
if (green < 0)
green = 0;
if (green > 255)
green = 255;
} else {
green = temperature - 60;
green = (float) (288.1221695283 * (Math.pow((double) green, -0.0755148492)));
if (green < 0)
green = 0;
if (green > 255)
green = 255;
}
//calculate blue
if (temperature >= 66)
blue = 255;
else if (temperature <= 19)
blue = 0;
else {
blue = temperature - 10;
blue = (float) (138.5177312231 * Math.log(blue) - 305.0447927307);
if (blue < 0)
blue = 0;
if (blue > 255)
blue = 255;
}
Log.v(TAG, "red=" + red + ", green=" + green + ", blue=" + blue);
return new RggbChannelVector((red / 255) * 2, (green / 255), (green / 255), (blue / 255) * 2);
}
另一种可能且更简单的解决方案; 因子 必须介于 0 和 100 之间:
private static RggbChannelVector computeTemperature(final int factor)
{
return new RggbChannelVector(0.635f + (0.0208333f * factor), 1.0f, 1.0f, 3.7420394f + (-0.0287829f * factor));
}