OpenCV -3 -年齡性別預測
使用語言:Java 1.8
操作系統:windows x64
OpenCV:4.1.1
OpenCV關於預測模型介紹
自2012年深度學習火起來後,AlexNet,vgg16,vgg19,gooGleNet,caffeNet,faster RCNN等,各種模型層出不羣,頗有文藝復興時的形態。
在各種頂會論文中,對年齡和性別的檢測的論文還是比較少的。而本文將要講解的是2015年的一篇cvpr,Age and Gender Classification using Convolutional Neural Networks。官方鏈接爲http://www.openu.ac.il/home/hassner/projects/cnn_agegender/ 【很明顯這段是小抄,是接下來使用的模型的理論基礎,反正我看不懂╮(╯_╰)╭】
基於 CNN模型的年齡和性別檢測
關於CNN模型的算法等等的,全部略過。。。。
首先,先下載模型的文件:age_net.caffemodel、deploy_age.prototxt、gender_net.caffemodel、deploy_gender.prototxt;
然後,使用OpenCV的readNetFromCaffe方法加載預測模型。【該方法可以讀取以Caffe框架格式存儲的網絡模型】
結果,把圖片預處理一下,丟進去執行分析預測方法,就會返回結果了。
用現成的模型還是很簡單的,而對於預測的準確性啥的,一般般能就行了,肯定比不了那些商用模型的。
實際實現代碼分析
年齡預測
/**
* 年齡預測 這個就是上一篇文章裏面調用的方法
* 參數爲人臉識別之後,截取人臉的圖片
*/
static String age_model = "D:/OpenCV/opencv/sources/samples/data/dnn/age_gender/age_net.caffemodel";
static String age_text = "D:/OpenCV/opencv/sources/samples/data/dnn/age_gender/deploy_age.prototxt";
static Net ageNet = readNetFromCaffe(age_text, age_model);
public static String predict_age(Mat image){
if (OpenCVTools.ageNet.empty()){
System.out.println("could not load net...\n");
}
// 輸入圖片,這裏的大小是依據模型訓練的時候設定的
// 在之後自己訓練的時候可以看到地點點原因
Mat blob = blobFromImage(image, 1.0, new Size(227,227));
ageNet.setInput(blob,"data");
// mat reshape 在不復制數據的情況下更改二維矩陣的形狀和/或通道數。
Mat prob = ageNet.forward("prob");
Mat probMat = prob.reshape(1, 1);
// 這裏是對預測值做處理
Core.MinMaxLocResult mmr = Core.minMaxLoc(probMat);
org.opencv.core.Point matchLoc = mmr.maxLoc;
double classidx = matchLoc.x;
System.out.println("年齡"+"???"+matchLoc.x);
// 預測對應的年齡數據
List ages = new ArrayList();
ages.add("0-2");
ages.add("4 - 6");
ages.add("8 - 12");
ages.add("15 - 20");
ages.add("25 - 32");
ages.add("38 - 43");
ages.add("48 - 53");
ages.add("60 - 100");
return ages.get(((int)classidx))+"";
}
性別預測
/**
* 性別預測
* 參數爲人臉識別之後,截取人臉的圖片
*/
static String gender_model = "D:/OpenCV/opencv/sources/samples/data/dnn/age_gender/gender_net.caffemodel";
static String gender_text = "D:/OpenCV/opencv/sources/samples/data/dnn/age_gender/deploy_gender.prototxt";
static Net sexNet = readNetFromCaffe(gender_text, gender_model);
public static String predict_gender(Mat image){
if (sexNet.empty()){
System.out.println("could not load net...\n");
}
// 輸入
Mat blob = blobFromImage(image, 1.0, new Size(227,227));
sexNet.setInput(blob,"data");
// 預測分類 運行forward pass以計算名爲output name的層的輸出。
Mat prob = sexNet.forward("prob");
Mat probMat = prob.reshape(1, 1);
double[] sexData0 = probMat.get(0,0);
double[] sexData1 = probMat.get(0,1);
// 試一下其他的寫法 依據標籤的寫法
// Core.MinMaxLocResult mmr = Core.minMaxLoc(probMat);
// org.opencv.core.Point matchLoc = mmr.maxLoc;
// System.out.println("性別"+"???"+sexData0[0]+sexData1[0]);
// System.out.println("性別"+"???"+matchLoc);
// List ages = new ArrayList();
// ages.add("male");
// ages.add("female");
// System.out.println("性別"+":::"+ages.get(((int)matchLoc.x))+"");
return sexData0[0] > sexData1[0] ? "Man" : "Woman";
}
小結一下
這裏需要一個結果的圖片:
到這裏,其實基本的圖像識別就已經完成,普通的玩一下的話,可以收工了。
如果需要提升識別精度,或者更多的識別物體,就需要:換一個大佬訓練好的模型,或者自己訓練一個。
因爲,打算學習OpenCV是需要做分享的,所有還要繼續換gooGleNet模型試一下,據說能識別1000+的物件。
然後,還有自己訓練一個人臉對應名稱的模型玩一下,理解一下基本訓練模型的流程的簡單入參。
2019-11-04 小杭 ε=(´ο`*)))唉 學習使我快樂【學習真累。。。。。。
參考
- https://blog.csdn.net/hunzhangzui9837/article/details/82840072
- 模型地址:https://talhassner.github.io/home/publication/2015_CVPR
- OpenCV文檔:https://docs.opencv.org/4.1.1/ 【一些代碼中的方法可以在這裏才具體定義】