最近在做人脸识别项目。在抓取人脸时,发现了很多问题。其中旋转角度和光线问题最令人抓狂。
Camera拍摄照片可能存在0度/90度/180度/270度的(右侧)旋转,不同设备不同。例如,小米3w,0度;小米8,270度。所以需要获取照片后不能立即使用,需要根据旋转角度,对照片进行处理,以方便人脸位置的获取。关于如何实现,是另一话题,改天再论。
光线问题,其实是非常感官的因素。同样的处理代码,同样的画面,光线是否充足,影响抓取结果。
尝试了三个方案,仅有最终的光线传感器奏效。现将成功和不成功的方案都记录下来。
(1)方案一(失败):Camera接口
起初,对于Camer接口一通查找,发现曝光补偿和白平衡带有auto设置,调试后发现,不起作用。
(2)方案二(失败):屏幕亮度
后将焦点放在屏幕的亮度调节上,通过设置SCREEN_BRIGHTNESS_MODE_AUTOMATIC,达到自动调节屏幕亮度的效果。调试后,仍无效。测试代码,如下
public static boolean autoBrightness(Context activity, boolean flag) {int value = 0;if (flag) {value = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;} else {value = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;}return Settings.System.putInt(activity.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS_MODE,value);}
(3)方案三(成功):光线传感器
最后才发现,其实真正起作用的是光线传感器。
下方为编写的适配器demo
package com.breakloop.common;import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.Window;
import android.view.WindowManager;import static android.content.Context.SENSOR_SERVICE;public class BrightnessAdapter implements SensorEventListener {private Context mContext;private SensorManager sensorManager;private Window mWindow;public BrightnessAdapter(Context fContext, Window fWindow) {this.mContext = fContext;this.mWindow=fWindow;this.sensorManager=(SensorManager)mContext.getSystemService(SENSOR_SERVICE);}public void regist(){if(sensorManager!=null){sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),SensorManager.SENSOR_DELAY_GAME);}}public void unRegist(){if(sensorManager!=null){sensorManager.unregisterListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT));}}@Overridepublic void onSensorChanged(SensorEvent event) {float[] values = event.values;//传感器类型int sensorType = event.sensor.getType();switch (sensorType){case Sensor.TYPE_LIGHT://获取窗口管理属性WindowManager.LayoutParams lp =mWindow.getAttributes();//计算屏幕亮度lp.screenBrightness = Float.valueOf(values[0])*(1f/255f);//参数设置mWindow.setAttributes(lp);break;default:break;}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}
}
调用时,仅需要创建对象,并在Activity中适时registor和unregistor即可。