核心流程:
- 收集人脸图片
- 处理图片,并按脸型打标(长型脸、圆形脸、椭圆脸、方形脸、心形脸)
- PC端使用Python + Tensorflow进行脸型模型训练
- 转换为Android可用模型
- 手机端使用OpenCV + Tensorflow Lite进行人脸检测和脸型分析
Tensorflow模型训练核心代码:
model = tf.keras.models.Sequential([
# Note the input shape is the desired size of the image 190x250 with 1 bytes color
# This is the first convolution
tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(250, 190, 1)),
tf.keras.layers.MaxPooling2D(2, 2),
# The second convolution
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
# The third convolution
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
# The fourth convolution
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
# Flatten the results to feed into a DNN
tf.keras.layers.Flatten(),
tf.keras.layers.Dropout(0.3),
# 512 neuron hidden layer
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(5, activation='softmax')
])
# Print the model summary
model.summary()
# Set the training parameters
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
TRAINING_DIR = '''../dataset/train'''
training_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1. / 255)
VALIDATION_DIR = '''../dataset/test'''
validation_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1. / 255)
Android端核心代码:
public int predictImage(Bitmap bitmap) {
// 将图像转换为TensorFlow Lite期望的格式
ByteBuffer inputBuffer = preprocessImage(bitmap);
// 进行推理
float[][] output = new float[1][NUM_CLASSES];
interpreter.run(inputBuffer, output);
// 获取预测类别
return argmax(output[0]);
}
// 初始化脸型检测模型
imageClassifier = new ImageClassifier(FaceShapeWithTensorflowActivity.this, "model/model01.tflite", MODEL_WIDTH, MODEL_HEIGHT, 1, 5);
//开始识别
if(lastFaceNo == -1 && imageClassifier != null)
lastFaceNo = imageClassifier.predictImage(bitmap);
int thisFaceNo = imageClassifier.predictImage(bitmap);
if(imageClassifier != null && lastFaceNo == thisFaceNo) { //检测同一个脸型
failGetCnt = 0;
successGetCnt++;
if(successGetCnt > FaceConstant.FACE_INFO_RECOGNIZE_CNT) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//显示裁切出来的人脸图片
imgGetFace.setImageBitmap(bitmap);
imgFaceTipsBg.setVisibility(View.VISIBLE);
imgFaceTipsBg.setImageResource(R.mipmap.ic_tips_gate_success);
tvFaceTips.setText(faceShapeMap.get(thisFaceNo));
speechText(faceShapeMap.get(thisFaceNo));
}
});
}
} else {
failGetCnt++;
if(failGetCnt > FaceConstant.FACE_INFO_ALLOW_RECOGNIZE_FAIL_CNT) {
successGetCnt = 0;
runOnUiThread(new Runnable() {
@Override
public void run() {
imgFaceTipsBg.setVisibility(View.VISIBLE);
imgFaceTipsBg.setImageResource(R.mipmap.ic_tips_gate_fail);
tvFaceTips.setText("识别失败");
}
});
}
}
lastFaceNo = thisFaceNo;
有需要源码的同学可以私信我!!!!!!!
如果能帮到您,您又刚好方便,又刚好打开了微信,那就鼓励下咔嚓小豪哥我吖
