這裡分類和彙總了欣宸的全部原創(含配套原始碼):https://github.com/zq2599/blog_demos
package com.bolingcavalry.grabpush.extend;
import com.bolingcavalry.grabpush.Constants;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.MatVector;
import org.bytedeco.opencv.opencv_core.Size;
import org.bytedeco.opencv.opencv_face.FaceRecognizer;
import org.bytedeco.opencv.opencv_face.FisherFaceRecognizer;
import java.io.File;
import java.io.IOException;
import java.nio.IntBuffer;
import java.util.LinkedList;
import java.util.List;
import static org.bytedeco.opencv.global.opencv_core.CV_32SC1;
import static org.bytedeco.opencv.global.opencv_imgcodecs.IMREAD_GRAYSCALE;
import static org.bytedeco.opencv.global.opencv_imgproc.resize;
/**
* @author willzhao
* @version 1.0
* @description 訓練
* @date 2021/12/12 18:26
*/
public class TrainFromDirectory {
/**
* 從指定目錄下
* @param dirs
* @param outputPath
* @throws IOException
*/
private void train(String[] dirs, String outputPath) throws IOException {
int totalImageNums = 0;
// 統計每個路徑下的照片數,加在一起就是照片總數
for(String dir : dirs) {
List<String> files = getAllFilePath(dir);
totalImageNums += files.size();
}
System.out.println("total : " + totalImageNums);
// 這裡用來儲存每一張照片的序號,和照片的Mat物件
MatVector imageIndexMatMap = new MatVector(totalImageNums);
Mat lables = new Mat(totalImageNums, 1, CV_32SC1);
// 這裡用來儲存每一張照片的序號,和照片的類別
IntBuffer lablesBuf = lables.createBuffer();
// 類別序號,從1開始,dirs中的每個目錄就是一個類別
int kindIndex = 1;
// 照片序號,從0開始
int imageIndex = 0;
// 每個目錄下的照片都遍歷
for(String dir : dirs) {
// 得到當前目錄下所有照片的絕對路徑
List<String> files = getAllFilePath(dir);
// 處理一個目錄下的每張照片,它們的序號不同,類別相同
for(String file : files) {
// imageIndexMatMap放的是照片的序號和Mat物件
imageIndexMatMap.put(imageIndex, read(file));
// bablesBuf放的是照片序號和類別
lablesBuf.put(imageIndex, kindIndex);
// 照片序號加一
imageIndex++;
}
// 每當遍歷完一個目錄,才會將類別加一
kindIndex++;
}
// 範例化臉部辨識類
FaceRecognizer faceRecognizer = FisherFaceRecognizer.create();
// 訓練,入參就是圖片集合和分類集合
faceRecognizer.train(imageIndexMatMap, lables);
// 訓練完成後,模型儲存在指定位置
faceRecognizer.save(outputPath);
//釋放資源
faceRecognizer.close();
}
/**
* 讀取指定圖片的灰度圖,調整為指定大小
* @param path
* @return
*/
private static Mat read(String path) {
Mat faceMat = opencv_imgcodecs.imread(path,IMREAD_GRAYSCALE);
resize(faceMat, faceMat, new Size(Constants.RESIZE_WIDTH, Constants.RESIZE_HEIGHT));
return faceMat;
}
/**
* 把指定路徑下所有檔案的絕對路徑放入list集合中返回
* @param path
* @return
*/
public static List<String> getAllFilePath(String path) {
List<String> paths = new LinkedList<>();
File file = new File(path);
if (file.exists()) {
// 列出該目錄下的所有檔案
File[] files = file.listFiles();
for (File f : files) {
if (!f.isDirectory()) {
// 把每個檔案的絕對路徑都放在list中
paths.add(f.getAbsolutePath());
}
}
}
return paths;
}
public static void main(String[] args) throws IOException {
String base = "E:\\temp\\202112\\18\\001\\";
// 儲存圖片的兩個目錄
// man目錄下儲存了群眾演員A的所有人臉照片,
// woman目錄下儲存了群眾演員B的所有人臉照片
String[] dirs = {base + "man", base + "woman"};
// 開始訓練,並指定模型輸出位置
new TrainFromDirectory().train(dirs, base + "faceRecognizer.xml");
}
}
名稱 | 連結 | 備註 |
---|---|---|
專案主頁 | https://github.com/zq2599/blog_demos | 該專案在GitHub上的主頁 |
git倉庫地址(https) | https://github.com/zq2599/blog_demos.git | 該專案原始碼的倉庫地址,https協定 |
git倉庫地址(ssh) | [email protected]:zq2599/blog_demos.git | 該專案原始碼的倉庫地址,ssh協定 |