這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
轉自:http://www.cnblogs.com/wlts/archive/2013/06/02/3113526.html
好吧,其實整個都是建立在face++的基礎上的,沒有任何技術含量,我只是個勤勞的搬運工。
所能實現的就是簡單的,你發送一個圖片過來,如果裡面是一個人,則告訴你分析出來的年齡、性別;如果是兩個人,就告訴你,這兩個人眉毛、眼睛、鼻子、嘴巴及整體的相似性。
公眾平台,怎麼說呢,還是傳統的一問一答的形式,你發個資訊過來,我收到了處理下,再給你回饋一條資訊,就是這麼簡單。
簡單的你來我往
先說資訊互傳的問題,公眾平台是post過來一個xml,伺服器端打包一個xml發回去。
從最簡單的,直接把使用者資訊返回去搞起吧。
簡訊
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> <MsgId>1234567890123456</MsgId> </xml>
參數 |
描述 |
ToUserName |
開發人員號 |
FromUserName |
發送方帳號(一個OpenID) |
CreateTime |
訊息建立時間 (整型) |
MsgType |
text |
Content |
簡訊內容 |
MsgId |
訊息id,64位整型 |
相應的資料結構也就自然出來了:
type Request struct{ ToUserName string FromUserName string CreateTime time.Duration MsgType string Content string MsgId int }
將輸入的xml解碼:
func decodeRequest(data []byte)(req *Request,err error){ req=&Request{} err=xml.Unmarshal(data,req) return }
雖然伺服器是用post方式傳遞的資料,不過實際還通過url傳遞過來了三個參數:signature,timestamp,nonce.
這三個參數可以驗證訊息是否伺服器發送過來的。
取post過來的資料:
func Action(w http.ResponseWriter,r *http.Request){ postedMsg,err:=ioutil.ReadAll(r.Body) if err!=nil{ log.Fatal(err) } r.Body.Close() msg,err:=decodeRequest(postedMsg) ...}
接下來就是回複資訊
回複簡訊
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[content]]></Content> <FuncFlag>0</FuncFlag> </xml>
參數 |
描述 |
ToUserName |
接收方帳號(收到的OpenID) |
FromUserName |
開發人員號 |
CreateTime |
訊息建立時間 |
MsgType |
text |
Content |
回複的訊息內容,長度不超過2048位元組 |
FuncFlag |
位0x0001被標誌時,星標剛收到的訊息 |
簡單封裝下:
type Response struct{ XMLName xml.Name `xml:"xml"` ToUserName string FromUserName string CreateTime time.Duration MsgType string Content string FuncFlag int }func encodeResponse(resp Response)(data []byte,err error){ resp.CreateTime=time.Second data,err=xml.Marshal(resp) return }
將資料發送回去的代碼:
var resp Responseresp.ToUserName=msg.FromUserNameresp.FromUserName=msg.ToUserNameresp.MsgType="text"resp.Content=msg.Contentresp.FuncFlag=0respData,err:=encodeResponse(resp)fmt.Fprintf(w,string(respData))
Face Service
這個怎麼說,就是使用者通過發送照片,照片是存到伺服器的,給我發一個圖片url,我再把這個url轉給face++,face++將分析結果給我發回來,我再把這些資料簡單處理下,反饋給使用者(當然,中間還隔了層伺服器)。
整個過程中,我所做的就是簡單的json資料處理,什麼高端的影像處理什麼的都跟我不沾邊,哈哈~
首先當然是到http://cn.faceplusplus.com/註冊,擷取API_SECRET、API_KEY。
而後推薦看文檔,http://cn.faceplusplus.com/dev/getting-started/api2info/,當然直接跟著我來一遍也行。
先來個臉部偵測吧,檢測出性別、年齡、種族。
看了範例文件後,發現detect調用後返回的json的結構表示出來大概是這樣:
type Faceslice struct{ Face []struct{ Attribute struct{ Age struct{ Range float64 Value float64 } Gender struct{ Confidence float64 Value string } Race struct{ Confidence float64 Vaule string } } Face_id string Position struct{ Center struct{ X float64 Y float64 } Eye_left struct{ X float64 Y float64 } Eye_right struct{ X float64 Y float64 } Height float64 Mouth_left struct{ X float64 Y float64 } Mouth_right struct{ X float64 Y float64 } Nose struct{ X float64 Y float64 } Width float64 } Tag string } Img_height int Img_id string Img_width int Session_id string url string }
解析json資料:
func DecodeDetect(data []byte) Faceslice{ var f Faceslice json.Unmarshal(data,&f) return f}
接著還是來寫個get函數吧:
func get(url string)(b []byte,err error){ res,e:=http.Get(url) if e!=nil{ err=e return } data,e:=ioutil.ReadAll(res.Body) if e!=nil{ err=e return } res.Body.Close() return data,nil}
調用face++介面並返回相應的資料:
const apiurl="https://apicn.faceplusplus.com"func DetectionDetect(picurl string)detection.Faceslice{ url:=apiurl+"/v2/detection/detect?url="+picurl+"&api_secret="+apisecret+"&api_key="+apikey tmp,_:=get(url) return detection.DecodeDetect(tmp)}
剛剛上面的樣本只是簡單考慮了文本資訊,現在要傳遞的是圖片資訊,所以做個簡單的修改:
type Request struct{ ToUserName string FromUserName string CreateTime time.Duration MsgType string Content string PicUrl string MsgId int}
Action函數裡也該有所修改,判定下msg.MsgType,如果是text,則跟剛才一樣處理,如果是image,則有新的處理方法。
我一個就做了兩個簡單的處理,一個是年齡、性別、種族,還有就是如果照片裡是兩個人,則給出五官及整體的相似性值。
相似性的代碼直接放下面吧:
package recognition import( "encoding/json" ) type Compare struct{ Component_similarity struct{ Eye float64 Mouth float64 Nose float64 Eyebrow float64 } Session_id string Similarity float64}