golang微信公众平台之人脸识别
golang微信公众平台之人脸识别
好吧,其实整个都是建立在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 Response resp.ToUserName = msg.FromUserName resp.FromUserName = msg.ToUserName resp.MsgType = " text " resp.Content = msg.Content resp.FuncFlag = 0 respData,err: = encodeResponse(resp) fmt.Fprintf(w, string (respData))
人脸识别
这个怎么说,就是用户通过微信发送照片,照片是存到微信服务器的,微信给我发一个图片url,我再把这个url转给face++,face++将分析结果给我发回来,我再把这些数据简单处理下,反馈给微信用户(当然,中间还隔了层微信服务器)。
整个过程中,我所做的就是简单的json数据处理,什么高端的图像处理什么的都跟我不沾边,哈哈~
首先当然是到 http://cn.faceplusplus测试数据/ 注册,获取API_SECRET、API_KEY。
而后推荐看文档, http://cn.faceplusplus测试数据/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测试数据 " 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 } func DecodeCompare(data [] byte )Compare{ var c Compare json.Unmarshal(data, & c) return c }
func RecognitionCompare(face1id,face2id string )recognition.Compare{ url: =apiurl+ " /v2/recognition/compare?api_secret= " +apisecret+ " &api_key= " + apikey+ " &face_id2= " +face2id+ " &face_id1= " + face1id tmp,_: = get (url) return recognition.DecodeCompare(tmp) }
判定图片里有几个人,一个人输出性别、年龄,两个人输出相似度,三个及以上,暂未判定:
if msg.MsgType== " image " { var faceslice detection.Faceslice faceslice = facepp.DetectionDetect(msg.PicUrl) switch len(faceslice.Face){ case 0 : resp.Content = " 请上传有脸的人物照片! " case 1 : attribute: =faceslice.Face[ 0 ].Attribute age: = attribute.Age gender: = attribute.Gender var faceGender string if gender.Value== " Male " { faceGender = " 男 " } else { faceGender = " 女 " } faceAgeValue: =fmt.Sprintf( " %d " , int (age.Value)) faceAgeRange: =fmt.Sprintf( " %d " , int (age.Range)) resp.Content = " 性别: " +faceGender+ " \n " + " 年龄: " +faceAgeValue+ " (± " +faceAgeRange+ " ) " case 2 : face1id: =faceslice.Face[ 0 ].Face_id face2id: =faceslice.Face[ 1 ].Face_id var compare recognition.Compare compare = facepp.RecognitionCompare(face1id,face2id) resp.Content = " 眼睛相似度: " +fmt.Sprintf( " %f " ,compare.Component_similarity.Eye)+ " \n " + " 嘴巴相似度: " +fmt.Sprintf( " %f " ,compare.Component_similarity.Mouth)+ " \n " + " 鼻子相似度: " +fmt.Sprintf( " %f " ,compare.Component_similarity.Nos e)+ " \n " + " 眉毛相似度: " +fmt.Sprintf( " %f " ,compare.Component_similarity.Eyebrow)+ " \n " + " 整体相似度: " +fmt.Sprintf( " %f " ,compare.Similarity) default : resp.Content = " 照片里人物太多了,暂不分析! " } }
标签: Golang , 微信
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于golang微信公众平台之人脸识别的详细内容...