最近也在寫(xiě)關(guān)于圖像識(shí)別的算法,主要是自己在做增強(qiáng)現(xiàn)實(shí)的項(xiàng)目,和圖形圖像都一直打交道.然后有個(gè)朋友剛好人臉識(shí)別那塊遇到瓶頸,剛好我項(xiàng)目當(dāng)中也碰到一個(gè)相關(guān)的問(wèn)題,就順便一起解決
用Unity3d的處理圖像,或多或少都會(huì)接觸OpenCV這個(gè)庫(kù),百度文庫(kù)上也有一篇是關(guān)于基于SIFT關(guān)鍵點(diǎn)的增強(qiáng)現(xiàn)實(shí)初始化算法
http://wenku.baidu.com/view/10589dc108a1284ac8504390.html
具體是處理增強(qiáng)現(xiàn)實(shí)技術(shù)那一塊的東西的,我們所謂的AR,其實(shí)本質(zhì)上也是掃描圖像的特征點(diǎn),然后識(shí)別出一個(gè)特征數(shù)組,然后和預(yù)先存好的數(shù)據(jù)進(jìn)行比較,如果相識(shí)的就認(rèn)為它們是同一個(gè)物體.其實(shí)這個(gè)在淘寶的拍立淘項(xiàng)目也有用上
本質(zhì)上做人臉識(shí)別\商品識(shí)別\LOGO識(shí)別都一樣的,OpenCV大法的確很好,現(xiàn)在第三方實(shí)現(xiàn)OpenCV庫(kù)的資料很多,python和node.js實(shí)現(xiàn)云識(shí)別的項(xiàng)目也在Github也能找到,那我這次實(shí)現(xiàn)的也依賴于這些第三方庫(kù),以及Unity3D這個(gè)引擎.
先上個(gè)Unity工程的截圖,黑一下鐘漢良.
然后公開(kāi)Unity3D的源代碼
using UnityEngine;
using System.Collections;
public class Demo : MonoBehaviour {
//人臉識(shí)別結(jié)果的數(shù)據(jù)結(jié)構(gòu)
public class face{
public Facemodels[] faces; //人臉數(shù)組,最大返回的臉為10張
}
//每張人臉識(shí)別結(jié)果的數(shù)據(jù)結(jié)構(gòu)
public class Facemodels{
public int facerectanglex; //人臉矩形框x坐標(biāo)
public int facerectangley; //人臉矩形框y坐標(biāo)
public int facerectanglewidth; //人臉矩形框?qū)? public int facerectangleheigh; //人臉矩形框高
public string base64feature; //人臉的特征值
public int lefteyex; //人臉左眼特征坐標(biāo)
public int lefteyey; //人臉左眼特征坐標(biāo)
public int righteyex; //人臉右眼特征坐標(biāo)
public int righteyey; //人臉右眼特征坐標(biāo)
public int mouthx; //人臉口型特征坐標(biāo)
public int mouthy; //人臉口型特征坐標(biāo)
}
public Facemodels people = new Facemodels();
Texture2D _tex = null;
string _message = null;
IEnumerator Start(){
//加載本地的一張美女圖片
//string filePath = "file://" + Application.dataPath + @"/lady.jpg";
string filePath = "file://" + Application.dataPath + @"/man.jpg";
WWW www = new WWW(filePath);
yield return www ;
_tex = www.texture;
//進(jìn)行人臉識(shí)別算法
CV2FaceDectect cv2 = new CV2FaceDectect();
StartCoroutine (cv2.IRequestJPG(_tex,Result));
}
//接收識(shí)別到的結(jié)果
void Result(string message){
Debug.Log (message);
LitJson.JsonData _data= LitJson.JsonMapper.ToObject(message);
LitJson.JsonData _person = _data ["facemodels"];
Debug.Log ("識(shí)別到的人數(shù)"+_person.Count);
for(int i= 0;i<_person.Count;i++){
people.facerectanglex= (int)_person[i]["facerectanglex"];
people.facerectangley= (int)_person[i]["facerectangley"];
people.facerectanglewidth= (int)_person[i]["facerectanglewidth"];
people.facerectangleheigh= (int)_person[i]["facerectangleheight"];
people.lefteyex= (int)_person[i]["lefteye"]["x"];
people.lefteyey= (int)_person[i]["lefteye"]["y"];
people.righteyex= (int)_person[i]["righteye"]["x"];
people.righteyey= (int)_person[i]["righteye"]["y"];
people.mouthx= (int)_person[i]["mouth"]["x"];
people.mouthy= (int)_person[i]["mouth"]["y"];
_message = "識(shí)別第"+i+"個(gè)人,"
+ "他的臉框坐標(biāo)x,y是"+(int)_person[i]["facerectanglex"] +"和"+ (int)_person[i]["facerectangley"]
+ "他的臉框坐標(biāo)寬,高是"+(int)_person[i]["facerectanglewidth"] +"和"+ (int)_person[i]["facerectangleheight"]
+ "他的左眼坐標(biāo)x,y是"+(int)_person[i]["lefteye"]["x"] +"和"+ (int)_person[i]["lefteye"]["y"]
+ "他的右眼坐標(biāo)x,y是"+(int)_person[i]["righteye"]["x"] +"和"+ (int)_person[i]["righteye"]["y"]
+ "他的嘴巴坐標(biāo)x,y是"+(int)_person[i]["mouth"]["x"] +"和"+ (int)_person[i]["mouth"]["y"]
;
Debug.Log("信息:"+_message);
}
}
//打印加載的圖片到屏幕上
void OnGUI(){
if(_tex != null){
GUI.Box(new Rect(0,0,_tex.width,_tex.height),_tex);
}
if(_message != null){
GUILayout.TextArea(_message);
//框住臉
GUI.Box(new Rect(people.facerectanglex,people.facerectangley,people.facerectanglewidth,people.facerectangleheigh),"臉");
//框住眼
GUI.Box(new Rect(people.lefteyex-20,people.lefteyey-20,40,40),"左");
GUI.Box(new Rect(people.righteyex-20,people.righteyey-20,40,40),"右");
//框住口
GUI.Box(new Rect(people.mouthx-20,people.mouthy-20,40,40),"口");
}
}
}