7

golang微信公众平台之人脸识别

 3 years ago
source link: https://studygolang.com/articles/306?fr=sidebar
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

golang微信公众平台之人脸识别

likai198981 · 2014-10-04 19:26:11 · 3237 次点击 · 预计阅读时间 12 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2014-10-04 19:26:11 的文章,其中的信息可能已经有所发展或是发生改变。

转自: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 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.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
}

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK