liuxiaolong
2019-07-25 f88a44f58396fb36a979cfe5640a36d6ac2d7289
controllers/fileController.go
@@ -2,22 +2,33 @@
import (
   "basic.com/pubsub/protomsg.git"
   "basic.com/fileServer/WeedFSClient.git"
   "basic.com/valib/deliver.git"
   "bytes"
   "encoding/base64"
   "encoding/json"
   "errors"
   "fmt"
   "github.com/gin-gonic/gin"
   "github.com/gogo/protobuf/proto"
   "github.com/satori/go.uuid"
   "image"
   "image/jpeg"
   "io/ioutil"
   "log"
   "mime/multipart"
   "net/http"
   "path"
   "strconv"
   "strings"
   "time"
   "webserver/extend/code"
   "webserver/extend/config"
   "webserver/extend/esutil"
   "webserver/extend/util"
   "webserver/models"
   "webserver/service"
   esApi "basic.com/pubsub/esutil.git"
)
type FileController struct {
@@ -31,9 +42,8 @@
//var picUrlField = "fid"
/**上传方法**/
//var weedfsUri = "http://192.168.1.182:6333/submit"
var weedfsUri = "http://192.168.1.182:9500/submit"
//var weedfsUri = "http://192.168.1.182:9500/submit"
// @Summary 依据图片添加底库人员
// @Description  依据图片添加底库返回数据人员
@@ -68,7 +78,7 @@
      // fastdfs 上传  暂废弃
      //field := fdfsclient.UploadFileByBuffer(data, fileSuffix)
   }
   field, result, err := uploadFileReturnAddr(file, filename, tableId)
   fileNameOnly, result, err := uploadFileReturnAddr(file, filename, tableId)
   if err != nil {
      if err.Error() == "NotFeatureFindError" {
         util.ResponseFormat(c, code.NotFeatureFindError, filename)
@@ -84,42 +94,163 @@
         util.ResponseFormat(c, code.ServiceInsideError, result["data"])
      }
   } else {
      util.ResponseFormat(c, code.Success, field)
      util.ResponseFormat(c, code.Success, fileNameOnly)
   }
}
type FaceExtract struct {
   Url string `json:"url"`
   FaceBytes []byte `json:"faceBytes"`
}
var faceExtractedMap = make(map[string]FaceExtract,0)
// @Summary 人脸提取
// @Description  人脸提取
// @Produce json
// @Tags 以图搜图
// @Param file formData file true "人员图片"
// @Success 200 {string} json "{"code":200, msg:"", data:"", success:true}"
// @Failure 500 {string} json "{"code":500, msg:"", data:"", success:false}"
// @Router /data/api-v/dbperson/faceExtract [POST]
func (controller FileController) FaceExtract(c *gin.Context) {
   file, _, err := c.Request.FormFile("file") //image这个是uplaodify参数定义中的   'fileObjName':'image'
   if err != nil {
      util.ResponseFormat(c, code.RequestParamError, "参数有误")
      return
   }
   var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
   resultMap :=make(map[string]interface{},0)
   //将上传的图片交人脸检测和人脸提取,获得特征
   fileBytes, _ := ioutil.ReadAll(file)
   faceArr, err, pI := service.GetFaceFeaFromSdk(fileBytes, time.Second*60)
   if err ==nil && len(faceArr) >0 {
      //1.提取每一张人脸小图
      urlArr := make([]string,0)
      for _,r := range faceArr {
         rcFace := r.Pos.RcFace
         cutFaceImgData := util.SubImg(*pI, int(rcFace.Left), int(rcFace.Top), int(rcFace.Right), int(rcFace.Bottom))
         weedFilePath, e := WeedFSClient.UploadFile(weedfsUri, "FaceUrl", cutFaceImgData)
         if e == nil{
            faceExtractedMap[weedFilePath] = FaceExtract{
               Url:weedFilePath,
               FaceBytes:r.Feats,
            }
            urlArr = append(urlArr, weedFilePath)
         }
      }
      //2.大图画框,标识人脸位置
      originFilePath, _ := WeedFSClient.UploadFile(weedfsUri, "FaceUrl", fileBytes)
      resultMap["uploadImage"] = originFilePath
      resultMap["smImage"] = urlArr
      util.ResponseFormat(c,code.Success, resultMap)
   } else {
      util.ResponseFormat(c,code.ComError,"未提取到人脸")
   }
}
// @Summary 以图搜图
// @Description  以图搜图
// @Produce json
// @Tags 以图搜图
// @Param url formData string true "url"
// @Param tableId formData string true "底库id"
// @Param compThreshold formData string true "比对阈值"
// @Success 200 {string} json "{"code":200, msg:"", data:"", success:true}"
// @Failure 500 {string} json "{"code":500, msg:"", data:"", success:false}"
// @Router /data/api-v/dbperson/searchByPhoto [POST]
func (controller FileController) SearchByPhoto(c *gin.Context) {
   photoUrl := c.Request.FormValue("url")
   tableId := c.Request.FormValue("tableId")//底库id
   compThresholdStr := c.Request.FormValue("compThreshold")//比对阈值
   compThreshold, err := strconv.ParseFloat(compThresholdStr,32)
   if photoUrl == "" || err != nil {
      util.ResponseFormat(c, code.RequestParamError, "参数有误")
      return
   }
   if face,ok := faceExtractedMap[photoUrl];!ok{
      util.ResponseFormat(c, code.RequestParamError, "参数有误")
      return
   } else {
      arg := protomsg.CompareArgs{
         FaceFeature:face.FaceBytes,
         CompareThreshold:float32(compThreshold),
      }
      if tableId !=""{
         arg.TableIds = []string{ tableId }
      }
      b, err := proto.Marshal(&arg)
      if err !=nil{
         util.ResponseFormat(c, code.ComError, "请求marshal失败")
         return
      }
      compServerList := config.CompServerInfo.Url
      fmt.Println("compServerList:", compServerList)
      resultList :=make([]protomsg.Dbperson,0)
      for _,str :=range compServerList{
         reqUrl := "tcp://"+str
         reqClient := deliver.NewClient(deliver.ReqRep, reqUrl)
         err = reqClient.Send(b)
         if err !=nil{
            continue
         }
         resultB, err := reqClient.Recv()
         if err !=nil{
            continue
         }
         m :=make(map[string]float32,0)
         err = json.Unmarshal(resultB, &m)
         if err !=nil{
            continue
         }
         personIds := make([]string,len(m))
         for k,_ :=range m{
            personIds = append(personIds,k)
         }
         esServerIp := config.EsInfo.Masterip
         esServerPort := config.EsInfo.Httpport
         index := config.EsInfo.EsIndex.Dbtablepersons.IndexName
         dbpeople, e := esApi.Dbpersoninfosbyid(personIds, index, esServerIp, esServerPort)
         if e ==nil{
            resultList = append(resultList,dbpeople...)
         }
      }
      util.ResponseFormat(c,code.Success,resultList)
   }
}
// @Description 人员照片上传并获取特征值
// @Router /data/api-v/dbperson/fileUploadTest [POST]
func (controller FileController) UploadPersonTest(c *gin.Context) {
   file, header, err := c.Request.FormFile("file") //image这个是uplaodify参数定义中的   'fileObjName':'image'
   file, _, err := c.Request.FormFile("file") //image这个是uplaodify参数定义中的   'fileObjName':'image'
   if err != nil {
      util.ResponseFormat(c, code.RequestParamError, "参数有误")
      return
   }
   //文件的名称
   filename := header.Filename
   fmt.Println(file, err, filename)
   if err != nil {
      log.Fatal(err)
      filename = uuid.NewV4().String()
   }
   var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
   //将上传的图片交人脸检测和人脸提取,获得特征
   var faceBase64=""
   faceExtArr, err := getFaceFeaFromSdk(file)
   if err ==nil && len(faceExtArr) >0 {
      for _,r := range faceExtArr {
   fileBytes, _ := ioutil.ReadAll(file)
   faceArr, err, pI := service.GetFaceFeaFromSdk(fileBytes, time.Second*5)
   if err ==nil && len(faceArr) >0 {
      var faceBase64= ""
      var rcFace *protomsg.Rect
      for _,r := range faceArr {
         rcFace = r.Pos.RcFace
         faceBase64 = base64.StdEncoding.EncodeToString(r.Feats)//获取提取到的第一张人脸特征
         break
      }
      fmt.Println("提取到的人脸特征为:",faceBase64)
      util.ResponseFormat(c,code.Success,faceBase64)
      return
      //根据人脸坐标扣出人脸小图
      cutFaceImgData := util.SubImg(*pI, int(rcFace.Left), int(rcFace.Top), int(rcFace.Right), int(rcFace.Bottom))
      weedFilePath, e := WeedFSClient.UploadFile(weedfsUri, "testCutFace", cutFaceImgData)
      if e !=nil{
         util.ResponseFormat(c,code.ComError,"文件上传失败")
      } else {
         util.ResponseFormat(c,code.Success,weedFilePath + ";" + faceBase64)
      }
   } else {
      util.ResponseFormat(c,code.ComError,"未提取到人脸")
   }
}
/*// 对上面的编码结果进行base64解码
@@ -129,73 +260,81 @@
}*/
func uploadFileReturnAddr(file multipart.File, filename string, tableId string) (string, map[string]interface{}, error) {
   defer file.Close()
   field := ""
   // weedfs 上传
   {
      fileInfo, e := esutil.PostFormData(weedfsUri, filename, "file", file)
      if e != nil {
         fmt.Println(e.Error())
         return "", nil, e
      } else {
         field = fileInfo[picUrlField].(string) // 文件路径
      }
   }
   if tableId != "" && field != "" {
      // 返回特征值  fileInfo["point"] = v.RcFace  fileInfo["feature"] = feat
      /*features := gorun.GetSimpleFaceDetect(picIp+field)  // 特征值     // linux
         if len(features) == 0 {                                               // linux
            return field,nil,errors.New("NotFeatureFindError")  // linux
         }else if len(features) > 1 {                                            // linux
            return field,nil,errors.New("TooManyFeatureFindError")  // linux
         }                                                                  // linux
         feat := features[0]["feature"].([]byte)   // linux
      if len(feat) != 2560 {                                // linux
         return field,nil,errors.New("NotFeatureFindError")
      }    */                     // linux
      //将上传的图片交人脸检测和人脸提取,获得特征
      var faceBase64=""
      faceExtArr, err := getFaceFeaFromSdk(file)
      if err ==nil && len(faceExtArr) >0 {
         for _,r := range faceExtArr {
            faceBase64 = base64.StdEncoding.EncodeToString(r.Feats)//获取提取到的第一张人脸特征
            break
         }
      }
      dbperson := new(models.Dbtablepersons)
      dbperson.FaceFeature = picIp + field //  图片路经
      dbperson.TableId = tableId           //
      dbperson.PersonName = filename       // 图片名
      // 演示base64编码
      dbperson.FaceFeature = faceBase64 // 特征值base64 码
      result := addDbPerson(dbperson)
      return field, result, nil
   } else {
      return field, nil, nil
   }
}
func getFaceFeaFromSdk(file multipart.File) ([]*protomsg.ResultFaceExtCom,error){
   s := service.NewFaceSdkService(file)
   i, err := s.ReadFromUploadImg()
   if err !=nil{
      return nil,err
   }
   bc, err := service.ImgCompress(i)
   fileBytes, err := ioutil.ReadAll(file)
   if err !=nil {
      return nil,err
      return "",nil,err
   }
   s.PushImgMsg(bc)
   return s.GetFaceFea()
   //将上传的图片交人脸检测和人脸提取,获得特征
   var faceBase64=""
   faceArr, err, pI := service.GetFaceFeaFromSdk(fileBytes, time.Second*5)
   if faceArr ==nil {
      return "",nil,errors.New("NotFeatureFindError")
   }
   var rcFace *protomsg.Rect
   if err ==nil && len(faceArr) >0 {
      for _,r := range faceArr {
         //拿到人脸的坐标
         rcFace = r.Pos.RcFace
         faceBase64 = base64.StdEncoding.EncodeToString(r.Feats)//获取提取到的第一张人脸特征
         break
      }
   }
   var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
   //根据人脸坐标扣出人脸小图
   cutFaceImgData := util.SubImg(*pI, int(rcFace.Left), int(rcFace.Top), int(rcFace.Right), int(rcFace.Bottom))
   fileInfo, e := esutil.PostFormData(weedfsUri, filename, "file", cutFaceImgData)
   if e != nil {
      fmt.Println(e.Error())
      return "", nil, e
   } else {
      field = fileInfo[picUrlField].(string) // 文件路径
   }
   if strings.Contains(field,"/"){
      idx := strings.Index(field, "/")
      field = field[idx+1:]
   }
   fmt.Println("field:",field)
   ext := path.Ext(filename)
   fileNameOnly := strings.TrimSuffix(filename, ext)
   dbperson := new(models.Dbtablepersons)
   dbperson.PersonPicUrl = field //  图片路经
   dbperson.TableId = tableId           //
   dbperson.PersonName = fileNameOnly       // 图片名
   // 演示base64编码
   dbperson.FaceFeature = faceBase64 // 特征值base64 码
   result := addDbPerson(dbperson)
   return fileNameOnly, result, nil
}
//func getFaceFeaFromSdk(fileBytes []byte) ([]*protomsg.ResultFaceExtCom,error,*protomsg.Image){
//   s := service.NewFaceSdkService(fileBytes)
//   i, err := s.ReadFromUploadImg()
//   if err !=nil{
//      fmt.Println("readFromUploadImg err:",err)
//      return nil,err,i
//   }
//   bc, err := service.ImgCompress(i)
//   if err !=nil {
//      fmt.Println("ImgCompress err:",err)
//      return nil,err,i
//   }
//   s.PushImgMsg(bc)
//   s.GetFaceFea()
//   if s.Result == nil{
//      return nil,errors.New("no fea"),i
//   } else {
//      return s.Result,nil,i
//   }
//}
/**上传方法**/
@@ -220,9 +359,9 @@
      return
   }
   extNames := make([]string, 0)
   isAllFiald := true
   addResult := make(map[string]interface{}, 0)
   details := make([]string, 0)
   successList := make([]string, 0)
   failList := make([]string,0)
   for _, head := range fileHeaders {
      //文件的名称
      filename := head.Filename
@@ -231,30 +370,34 @@
      if err != nil {
         log.Fatal(err)
      }
      //data, _ := ioutil.ReadAll(file)
      // weedfs 上传
      field, _, err1 := uploadFileReturnAddr(file, filename, tableId)
      extNames = append(extNames, field)
      if isAllFiald && err1 == nil {
         isAllFiald = false
      }
      if err1 != nil {
         if field == "" {
            details = append(details, filename+"上传失败,"+err1.Error())
         } else {
            details = append(details, filename+"加入底库失败,"+err1.Error())
         }
      //extNames = append(extNames, field)
      if err1 != nil || field == "" {
         failList = append(failList, filename)
      } else {
         successList = append(successList, filename)
      }
   }
   addResult["isAllFiald"] = isAllFiald
   addResult["successList"] = successList
   addResult["failList"] = failList
   addResult["fields"] = extNames
   addResult["detail"] = details
   //addResult["detail"] = details
   //fields := fdfsclient.UploadFileByBuffer100(bytess, extNames)     //  fastdfs 上传
   if !isAllFiald {
   if len(successList)>0 {
      util.ResponseFormat(c, code.Success, addResult)
   } else {
      util.ResponseFormat(c, code.ServiceInsideError, err.Error())
   }
}
type EsPersonSave struct {
   FaceFeature string `json:"faceFeature"`
   TableId string `json:"tableId"`
   Id string `json:"id"`
   PersonPicUrl string `json:"personPicUrl"`
   IdCard string `json:"idCard"`
}
// @Summary 上传图片 并切图
@@ -264,8 +407,8 @@
// @Tags dbperson 底库人员
// @Param file formData file true "底库人员图片"
// @Param tableId formData string false "底库id,有id 则加入底库,无则只上传图片"
// @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}"
// @Failure 500 {string} json "{"code":500,  msg:"返回错误信息", success:false}"
// @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true, data:""}"
// @Failure 500 {string} json "{"code":500,  msg:"返回错误信息", success:false, data:""}"
// @Router /data/api-v/es/ImageUploadReturnPics [POST]
func (fc FileController) ImageUploadReturnPics(c *gin.Context) {
   //得到上传的文件
@@ -277,9 +420,9 @@
   }
   //文件的名称
   filename := header.Filename
   fmt.Println(file, err, filename)
   defer file.Close()
   field := ""
   // weedfs 上传
   uploadData := make([]byte, header.Size)
   i, err2 := file.ReadAt(uploadData, 0)
@@ -288,6 +431,7 @@
      util.ResponseFormat(c, code.UploadFileError, err2.Error())
      return
   }
   var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
   {
      uri := weedfsUri
      fileInfo, e := esutil.PostFormBufferData(uri, filename, "file", uploadData)
@@ -302,7 +446,7 @@
   // fileInfo["point"] = v.RcFace   // 返回特征值
   //   fileInfo["feature"] = feat
   //features := gorun.GetSimpleFaceDetect(picIp + "/" + field) // 特征值  只在linux 下
   //feat := []byte("hello world")           // windows 测试放开
   result := make(map[string]interface{}, 0)
   result["uploadImage"] = picIp + field
   smUrl := make([]string, 0)