核心流程:
- 收集人脸图片
- 处理图片,并按脸型打标(长型脸、圆形脸、椭圆脸、方形脸、心形脸)
- 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;
有需要源码的同学可以私信我!!!!!!!
如果能帮到您,您又刚好方便,又刚好打开了微信,那就鼓励下咔嚓小豪哥我吖