liuxiaolong
2019-10-11 b0500fee9c01e17c81b9293b244c8ed88dc9ca29
controllers/fileController.go
@@ -10,7 +10,9 @@
   "fmt"
   "github.com/gin-gonic/gin"
   "github.com/satori/go.uuid"
   "gocv.io/x/gocv"
   "image"
   "image/color"
   "image/jpeg"
   "io/ioutil"
   "log"
@@ -22,10 +24,11 @@
   "strings"
   "sync"
   "time"
   "webserver/cache"
   "webserver/extend/code"
   "webserver/extend/config"
   "webserver/extend/esutil"
   "webserver/extend/logger"
   "basic.com/valib/logger.git"
   "webserver/extend/util"
   "webserver/models"
   "webserver/service"
@@ -120,7 +123,13 @@
      util.ResponseFormat(c, code.RequestParamError, "参数有误")
      return
   }
   var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
   localConf, err2 := cache.GetServerInfo()
   if err2 !=nil || localConf.WebPicIp == "" {
      logger.Debug("localConfig is wrong!!!")
      return
   }
   var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
   logger.Debug("weedfsUri:",weedfsUri)
   resultMap :=make(map[string]interface{},0)
   //将上传的图片交人脸检测和人脸提取,获得特征
   fileBytes, _ := ioutil.ReadAll(file)
@@ -141,13 +150,31 @@
         }
      }
      //2.大图画框,标识人脸位置
      originFilePath, _ := WeedFSClient.UploadFile(weedfsUri, "FaceUrl", fileBytes)
      drawedB, _ := drawPolygonOnImg(pI, &faceArr)
      originFilePath, _ := WeedFSClient.UploadFile(weedfsUri, "FaceUrl", *drawedB)
      resultMap["uploadImage"] = originFilePath
      resultMap["smImage"] = urlArr
      util.ResponseFormat(c,code.Success, resultMap)
   } else {
      util.ResponseFormat(c,code.ComError,"未提取到人脸")
   }
}
func drawPolygonOnImg(i *protomsg.Image,faceArr *[]*protomsg.ResultFaceDetect) (*[]byte,error) {
   rook, _ := gocv.NewMatFromBytes(int(i.Height), int(i.Width), gocv.MatTypeCV8UC3, i.Data)
   defer rook.Close()
   //yellow := color.RGBA{255, 255, 0, 0}
   red := color.RGBA{255, 0, 0, 0}
   for _,faceResult := range *faceArr {
      left := int(faceResult.Pos.RcFace.Left)
      top := int(faceResult.Pos.RcFace.Top)
      right := int(faceResult.Pos.RcFace.Right)
      bottom := int(faceResult.Pos.RcFace.Bottom)
      gocv.Rectangle(&rook, image.Rect(left,top,right,bottom), red, 1)
   }
   fData,err := gocv.IMEncode(".jpg", rook)
   return &fData,err
}
type CompareResult struct {
@@ -214,15 +241,15 @@
   }
   logger.Debug("comp len(personIds):", len(personIds))
   logger.Debug("comp len(captureIds):", len(captureIds))
   esServerIp := config.EsInfo.Masterip
   esServerPort := config.EsInfo.Httpport
   index := config.EsInfo.EsIndex.Dbtablepersons.IndexName
   var dbpersons []protomsg.Dbperson
   if len(personIds) >0 {
      dbpersons, _ = esApi.Dbpersoninfosbyid(personIds, index, esServerIp, esServerPort)
      var dbpApi dbapi.DbPersonApi
      dbpersons, _ = dbpApi.Dbpersoninfosbyid(personIds)
   }
   if len(dbpersons) >0 {
      var dtApi dbapi.DbTableApi
      for _,p :=range dbpersons {
         var dbP = DbPersonVo {
            PersonId: p.Id,
@@ -236,7 +263,7 @@
            TableId: p.TableId,
            Enable: p.Enable,
         }
         dbTableInfos, _ := esApi.Dbtablefosbyid([]string{p.TableId}, config.EsInfo.EsIndex.DbTables.IndexName, esServerIp, esServerPort)
         dbTableInfos, _ := dtApi.DbtablesById([]string{ p.TableId })
         if dbTableInfos !=nil{
            dbP.BwType = dbTableInfos[0].BwType
            dbP.TableName = dbTableInfos[0].TableName
@@ -248,7 +275,13 @@
      }
   }
   if len(captureIds) >0 {
      videopersons, _ := esApi.Videopersonsinfosbyid(captureIds, config.EsInfo.EsIndex.VideoPersons.IndexName, config.EsInfo.Masterip, config.EsInfo.Httpport)
      localConf, err2 := cache.GetServerInfo()
      if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
         logger.Debug("localConfig is wrong!!!")
         return nil
      }
      logger.Debug("captureIds:",strings.Join(captureIds,","))
      videopersons, _ := esApi.Videopersonsinfosbyid(captureIds, config.EsInfo.EsIndex.VideoPersons.IndexName, localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort)))
      logger.Debug("comp videoPersons.len:",len(videopersons))
      for _,vp :=range videopersons {
         isAlarmInt, _ := strconv.Atoi(vp.IsAlarm)
@@ -305,6 +338,36 @@
   return level
}
func GetFeaFromOneFaceImg(fileBytes []byte) (faceB []byte,oriImg string,smImgs []string, err error){
   localConf, err2 := cache.GetServerInfo()
   if err2 !=nil || localConf.WebPicIp == "" {
      logger.Debug("localConfig is wrong!!!")
      return nil,"",nil,errors.New("localConf err")
   }
   var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
   logger.Debug("weedfsUri:",weedfsUri)
   faceArr, err, pI := service.GetFaceFeaFromSdk(fileBytes, time.Second*60)
   if err ==nil && len(faceArr) ==1 {
      rcFace := faceArr[0].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:faceArr[0].Feats,
         }
         smImgs = append(smImgs, weedFilePath)
      }
      //2.大图画框,标识人脸位置
      drawedB, _ := drawPolygonOnImg(pI, &faceArr)
      originFilePath, _ := WeedFSClient.UploadFile(weedfsUri, "FaceUrl", *drawedB)
      return faceArr[0].Feats,originFilePath,smImgs,nil
   } else {
      return nil,"",nil,errors.New("no face")
   }
}
// @Summary 以图搜图
// @Description  以图搜图
// @Accept json
@@ -314,49 +377,69 @@
// @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) {
func (fc FileController) SearchByPhoto(c *gin.Context) {
   var searchBody models.EsSearch
   err := c.BindJSON(&searchBody)
   if err !=nil{
      util.ResponseFormat(c, code.RequestParamError, "参数有误")
      return
   }
   localConf, err2 := cache.GetServerInfo()
   if err2 !=nil || localConf.AlarmIp == "" || localConf.ServerId == "" {
      logger.Debug("localConfig is wrong!!!")
      util.ResponseFormat(c,code.ComError,"localConf wrong")
      return
   }
   var faceB []byte
   if searchBody.CaptureId != "" {//做查找此人,搜所有抓拍和底库
      searchBase64Fea, err := esApi.GetVideoPersonFaceFeatureById(searchBody.CaptureId, config.EsInfo.EsIndex.VideoPersons.IndexName, config.EsInfo.Masterip, config.EsInfo.Httpport)
      if err !=nil {
         util.ResponseFormat(c, code.ComError, "抓拍数据不存在,请检查")
         return
      }
      if searchBase64Fea !=""{
         decodeF, err := base64.StdEncoding.DecodeString(searchBase64Fea)
         if err !=nil {
            util.ResponseFormat(c, code.ComError, "本条抓怕特征不是base64,请检查")
   if searchBody.CompTargetId != "" {//做查找此人,按抓拍的人脸或者底库的人脸以图搜图
      if searchBody.CompTargetType == 0 {//本张人脸是底库人脸
         var dbpApi dbapi.DbPersonApi
         dbPersons, e := dbpApi.Dbpersoninfosbyid([]string{searchBody.CompTargetId})
         if e ==nil && dbPersons !=nil && len(dbPersons) ==1 {
            searchBase64Fea := dbPersons[0].FaceFeature
            if searchBase64Fea != "" {
               decodeF, err := base64.StdEncoding.DecodeString(dbPersons[0].FaceFeature)
               if err !=nil {
                  util.ResponseFormat(c, code.ComError, "本条底库人员特征不是base64,请检查")
                  return
               }
               faceB = decodeF
            } else {
               util.ResponseFormat(c, code.ComError, "本条底库人员特征为空,请检查")
               return
            }
         } else {
            util.ResponseFormat(c, code.ComError, "底库人员查询失败,请检查")
            return
         }
         faceB = decodeF
      } else {
         searchBase64Fea, err := esApi.GetVideoPersonFaceFeatureById(searchBody.CompTargetId, config.EsInfo.EsIndex.VideoPersons.IndexName, localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort)))
         if err !=nil {
            util.ResponseFormat(c, code.ComError, "抓拍数据不存在,请检查")
            return
         }
         if searchBase64Fea !=""{
            decodeF, err := base64.StdEncoding.DecodeString(searchBase64Fea)
            if err !=nil {
               util.ResponseFormat(c, code.ComError, "本条抓怕特征不是base64,请检查")
               return
            }
            faceB = decodeF
         }
      }
   } else {//做以图搜图
      if searchBody.PicUrl == "" || len(searchBody.DataBases) == 0 {
         util.ResponseFormat(c, code.RequestParamError, "参数有误")
         util.ResponseFormat(c, code.RequestParamError, "以图搜图PicUrl不能为空")
         return
      }
      if face,ok := faceExtractedMap[searchBody.PicUrl];!ok{
         util.ResponseFormat(c, code.RequestParamError, "请重新上传图片")
         util.ResponseFormat(c, code.RequestParamError, "人脸特征未检测,请重新上传图片")
         return
      } else {
         faceB = face.FaceBytes
      }
   }
   var sysSetApi dbapi.SysSetApi
   analyServerId := ""
   flag, sysconf := sysSetApi.GetServerInfo()
   if flag {
      analyServerId = sysconf.ServerId
   } else {
      util.ResponseFormat(c, code.ComError, "analyServerId为空,配置有误")
      return
   }
   if faceB == nil {
@@ -368,11 +451,12 @@
      CompareThreshold: searchBody.Threshold,
   }
   var hasCompEsPerson = false
   if searchBody.DataBases !=nil {
      for idx,tableId :=range searchBody.DataBases {
         if tableId == "esData" {
            searchBody.DataBases = append(searchBody.DataBases[:idx], searchBody.DataBases[idx+1:]...)
            searchBody.DataBases = append(searchBody.DataBases,service.CaptureTable)
            hasCompEsPerson = true
            break
         }
      }
@@ -388,40 +472,45 @@
   arg.SearchTime = searchBody.SearchTime
   arg.InputValue = searchBody.InputValue
   arg.Collection = searchBody.Collection
   arg.AnalyServerId = analyServerId
   arg.AnalyServerId = localConf.ServerId
   logger.Debug("arg.TableIds:", arg.TableIds, ",alarmLevel:",arg.AlarmLevel,",treeNodes:",arg.TreeNodes,",searchTime:",arg.SearchTime,
      ",inputValue:",arg.InputValue,",tasks:",arg.Tasks,",compThreshold:",arg.CompareThreshold)
   timeStart := time.Now()
   compareService := service.NewFaceCompareService(arg)
   compareOnce := compareService.Compare()
   totalData := compareOnce.CompareData
   var totalData service.CompareList
   if len(arg.TableIds) >0 {//有比对底库
      dbPersonTargets := compareService.CompareDbPersons()
      if dbPersonTargets !=nil {
         totalData = append(totalData,*dbPersonTargets...)
      }
   }
   if hasCompEsPerson {//有比对Es抓拍
      esPersons := compareService.CompareVideoPersons()
      if esPersons !=nil {
         totalData = append(totalData, *esPersons...)
      }
   }
   logger.Debug("comp 比对结束,用时:",time.Since(timeStart))
   service.SetCompResultByNum(&service.CompareOnce{
      CompareNum: compareService.CompareNum,
      CompareData: &totalData,
   })
   m := make(map[string]interface{},3)
   if totalData != nil && totalData.Len() > 0{
      //按分值排序
      //var scorePre []float32
      //for _,f1 :=range *totalData {
      //   scorePre = append(scorePre, f1.CompareScore)
      //}
      //logger.Debug("comp 排序前分值数组:",scorePre)
      sort.Sort(totalData)
      //var scoreAf []float32
      //for _,f2 :=range *totalData {
      //   scoreAf = append(scoreAf, f2.CompareScore)
      //}
      //logger.Debug("comp 排序后分值数组:",scoreAf)
      total := totalData.Len()
      m["compareNum"] = compareOnce.CompareNum
      m["compareNum"] = compareService.CompareNum
      m["total"] = total
      var sCompResult protomsg.SdkCompareResult
      if total <= searchBody.Size {
         sCompResult.CompareResult = *totalData
         sCompResult.CompareResult = totalData
      } else {
         sCompResult.CompareResult = (*totalData)[0:searchBody.Size]
         sCompResult.CompareResult = totalData[0:searchBody.Size]
      }
      resultList := FillDataToCompareResult(&sCompResult)
      m["totalList"] = resultList
@@ -429,7 +518,7 @@
   } else {
      m["total"] = 0
      m["compareNum"] = searchBody.CompareNum
      m["compareNum"] = compareService.CompareNum
      m["totalList"] = []CompareResult{}
   }
   util.ResponseFormat(c,code.Success,m)
@@ -525,7 +614,12 @@
      util.ResponseFormat(c, code.RequestParamError, "参数有误")
      return
   }
   var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
   localConf, err2 := cache.GetServerInfo()
   if err2 !=nil || localConf.WebPicIp == "" {
      logger.Debug("localConfig is wrong!!!")
      return
   }
   var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
   //将上传的图片交人脸检测和人脸提取,获得特征
   fileBytes, _ := ioutil.ReadAll(file)
@@ -559,7 +653,6 @@
func uploadFileReturnAddr(file multipart.File, filename string, tableId string) (string, map[string]interface{}, error) {
   defer file.Close()
   field := ""
   // weedfs 上传
   fileBytes, err := ioutil.ReadAll(file)
   if err !=nil {
@@ -585,35 +678,33 @@
         break
      }
   }
   var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
   localConf, err2 := cache.GetServerInfo()
   if err2 !=nil || localConf.WebPicIp == "" {
      logger.Debug("localConfig is wrong!!!")
      return "",nil,err2
   }
   var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
   //根据人脸坐标扣出人脸小图
   t1 := time.Now()
   cutFaceImgData := util.SubImg(*pI, int(rcFace.Left), int(rcFace.Top), int(rcFace.Right), int(rcFace.Bottom))
   logger.Debug("SubImg用时:", time.Since(t1))
   t1 = time.Now()
   fileInfo, e := esutil.PostFormData(weedfsUri, filename, "file", cutFaceImgData)
   weedFilePath, e := WeedFSClient.UploadFile(weedfsUri, filename, cutFaceImgData)
   logger.Debug("上传到weedfs用时:", time.Since(t1))
   t1 = time.Now()
   if e != nil {
      fmt.Println(e.Error())
      logger.Debug("WeedFSClient.UploadFile err:", e)
      return "", nil, e
   } else {
      field = fileInfo[picUrlField].(string) // 文件路径
   }
   if strings.Contains(field,"/"){
      idx := strings.Index(field, "/")
      field = field[idx+1:]
   }
   ext := path.Ext(filename)
   fileNameOnly := strings.TrimSuffix(filename, ext)
   dbperson := new(models.Dbtablepersons)
   dbperson.PersonPicUrl = field //  图片路经
   dbperson.PersonPicUrl = weedFilePath //  图片路经
   dbperson.TableId = tableId           //
   dbperson.PersonName = fileNameOnly       // 图片名
   dbperson.Enable = 1 //默认有效
   // 演示base64编码
   dbperson.FaceFeature = faceBase64 // 特征值base64 码
   result := addDbPerson(dbperson)
@@ -657,8 +748,15 @@
         defer wg.Done()
         tIStart := time.Now()
         filename := head.Filename
         fileExt := path.Ext(filename)
         fileExt = strings.ToLower(fileExt)
         if fileExt !=".jpg" && fileExt != ".jpeg" && fileExt != ".png" {
            lock.Lock()
            failList = append(failList, filename)
            lock.Unlock()
            return
         }
         file, err := head.Open()
         fmt.Println(file, err, filename)
         if err != nil {
            lock.Lock()
            failList = append(failList, filename)
@@ -682,11 +780,11 @@
   addResult["failList"] = failList
   addResult["fields"] = extNames
   if len(successList)>0 {
   //if len(successList)>0 {
      util.ResponseFormat(c, code.DbPersonUploadSuccess, addResult)
   } else {
      util.ResponseFormat(c, code.DbPersonUploadFail, addResult)
   }
   //} else {
   //   util.ResponseFormat(c, code.DbPersonUploadFail, addResult)
   //}
}
type EsPersonSave struct {
@@ -728,7 +826,12 @@
      util.ResponseFormat(c, code.UploadFileError, err2.Error())
      return
   }
   var weedfsUri = "http://"+config.WeedFs.Ip+":"+strconv.Itoa(config.WeedFs.UploadPort)+"/submit"
   localConf, err2 := cache.GetServerInfo()
   if err2 !=nil || localConf.WebPicIp == "" {
      logger.Debug("localConfig is wrong!!!")
      return
   }
   var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit"
   {
      uri := weedfsUri
      fileInfo, e := esutil.PostFormBufferData(uri, filename, "file", uploadData)