package service
|
|
import (
|
"basic.com/pubsub/protomsg.git"
|
"basic.com/valib/deliver.git"
|
"encoding/base64"
|
"fmt"
|
"github.com/gogo/protobuf/proto"
|
"github.com/pierrec/lz4"
|
"github.com/pkg/errors"
|
"github.com/satori/go.uuid"
|
"gocv.io/x/gocv"
|
"io/ioutil"
|
"mime/multipart"
|
"sync"
|
"time"
|
)
|
|
type FaceSdkService struct {
|
File *multipart.File
|
Id string
|
Result []*protomsg.ResultFaceExtCom
|
}
|
|
const (
|
Ipc_Push_Ext = "_2.ipc"
|
Ipc_Pull_Ext = "_1.ipc"
|
Ipc_Url_Pre = "ipc:///tmp///"
|
Virtual_FaceTaskId = "92496BDF-2BFA-98F2-62E8-96DD9866ABD2"
|
Virtual_FaceSdkId = "virtual-faceextract-sdk-pull"
|
Url_Service_PUSH = Ipc_Url_Pre + Virtual_FaceSdkId + Ipc_Push_Ext
|
Url_Service_PULL = Ipc_Url_Pre + Virtual_FaceSdkId + Ipc_Pull_Ext
|
)
|
|
func NewFaceSdkService(file multipart.File) FaceSdkService{
|
return FaceSdkService{
|
File:&file,
|
Id:uuid.NewV4().String(),
|
}
|
}
|
|
var imgPushChan chan []byte
|
var client_push deliver.Deliver
|
var client_pull deliver.Deliver
|
|
func TestPushImgMsg() {
|
InitService()
|
|
i := readTestImgFile()
|
|
fmt.Printf("width:%d,height:%d,data.length:%d,timestamp:%s,id:%d\n",i.Width,i.Height,len(i.Data),i.Timestamp,i.Id)
|
|
bc, err := ImgCompress(&i)
|
if err !=nil {
|
fmt.Println("image is not compressible")
|
} else {
|
var s FaceSdkService
|
s.PushImgMsg(bc)
|
}
|
}
|
|
func (s *FaceSdkService) ReadFromUploadImg() (*protomsg.Image,error){
|
defer (*(s.File)).Close()
|
imgB, err := ioutil.ReadAll(*(s.File))
|
if err !=nil{
|
fmt.Println("File.Read err:",err)
|
return nil,err
|
}
|
|
fmt.Println("imgB.len:",len(imgB))
|
|
picMat, err := gocv.IMDecode(imgB, gocv.IMReadColor)
|
if err !=nil {
|
fmt.Println("gocv.IMDecode err:",err)
|
return nil,err
|
}
|
defer picMat.Close()
|
if picMat.Empty() {
|
fmt.Println("file not exist")
|
return nil,errors.New("picMat is empty")
|
}
|
height := int32(picMat.Rows())
|
width := int32(picMat.Cols())
|
data := picMat.ToBytes()
|
timeUnix := time.Now().Unix()
|
formatTimeStr := time.Unix(timeUnix, 0).Format("2006-01-02 15:04:05")
|
|
return &protomsg.Image{
|
Width: width,
|
Height: height,
|
Timestamp: formatTimeStr,
|
Data: data,
|
Id: timeUnix,
|
Cid:s.Id,
|
},nil
|
}
|
|
func ImgCompress(i *protomsg.Image) ([]byte,error){
|
if b, err := proto.Marshal(i); err != nil {
|
fmt.Println("protoImage marshal err")
|
return nil,err
|
} else {
|
bc := make([]byte, len(b))
|
ht := make([]int, 64<<10)
|
n, err := lz4.CompressBlock(b, bc, ht)
|
if err != nil {
|
fmt.Println(err)
|
return nil,err
|
}
|
if n >= len(b) {
|
fmt.Println("image is not compressible")
|
return nil,errors.New("compressed len is 0")
|
}
|
bc = bc[:n]
|
return bc,nil
|
}
|
}
|
|
func (s *FaceSdkService) GetFaceFea(){
|
var wg sync.WaitGroup
|
wg.Add(1)
|
ticker := time.NewTicker(time.Second * 3)
|
go func(ticker *time.Ticker, s *FaceSdkService) {
|
defer ticker.Stop()
|
defer wg.Done()
|
|
for {
|
select {
|
case <-ticker.C:
|
return
|
default:
|
if feas,ok := resultMap[s.Id];ok {
|
s.Result = feas
|
return
|
}
|
}
|
}
|
}(ticker, s)
|
wg.Wait()
|
}
|
|
func readTestImgFile() protomsg.Image{
|
var i protomsg.Image
|
timeUnix := time.Now().Unix()
|
formatTimeStr := time.Unix(timeUnix, 0).Format("2006-01-02 15:04:05")
|
filePath := "/home/user/workspace/timg.jpg"
|
|
picMat := gocv.IMRead(filePath, gocv.IMReadColor)
|
|
defer picMat.Close()
|
|
if picMat.Empty() {
|
fmt.Println("file not exist")
|
return i
|
}
|
height := int32(picMat.Rows())
|
width := int32(picMat.Cols())
|
data := picMat.ToBytes()
|
//wrMat,_ := gocv.NewMatFromBytes(picMat.Rows(),picMat.Cols(),gocv.MatTypeCV8UC3,data)
|
//
|
//gocv.IMWrite("xxx.jpg", wrMat)
|
|
i = protomsg.Image{
|
Width: width,
|
Height: height,
|
Timestamp: formatTimeStr,
|
Data: data,
|
Id: timeUnix,
|
}
|
i.Cid = uuid.NewV4().String() //数据唯一id
|
fmt.Println("gocv read img completed")
|
return i
|
}
|
|
func (s *FaceSdkService) PushImgMsg(is []byte){
|
imgPushChan <- is
|
}
|
|
var resultMap map[string][]*protomsg.ResultFaceExtCom
|
|
func InitService() {
|
fmt.Println("service init!")
|
imgPushChan = make(chan []byte)
|
|
resultMap = make(map[string][]*protomsg.ResultFaceExtCom,0)
|
|
client_push = deliver.NewClient(deliver.PushPull, Url_Service_PUSH)
|
client_pull = deliver.NewClient(deliver.PushPull, Url_Service_PULL)
|
defer func() {
|
client_push.Close()
|
client_pull.Close()
|
}()
|
go thSend()
|
|
go thRecv()
|
}
|
|
func thSend() {
|
for {
|
select {
|
case d := <-imgPushChan:
|
fmt.Println("imgPushChan in")
|
err := client_push.Send(d)
|
if err != nil {
|
fmt.Println("img Send err:", err)
|
}
|
default:
|
//fmt.Println("no img in")
|
}
|
}
|
}
|
|
func thRecv() {
|
for {
|
resultBytes, err := client_pull.Recv()
|
if err != nil {
|
//fmt.Println("pull err:", err)
|
continue
|
}
|
rMsg := protomsg.SdkMessage{}
|
if err := proto.Unmarshal(resultBytes, &rMsg); err == nil {
|
fmt.Println("received MSG:", rMsg.Cid)
|
perId := rMsg.Cid //数据id
|
if rMsg.Tasklab != nil && rMsg.Tasklab.Taskid == Virtual_FaceTaskId {
|
sdkInfos := rMsg.Tasklab.Sdkinfos
|
|
fmt.Println("Len(sdkInfos)=",len(sdkInfos))
|
for _,swt :=range sdkInfos{
|
if swt.Sdktype =="FaceDetect"{
|
fmt.Println("人脸检测结果")
|
var pfp protomsg.ParamFacePos
|
err := proto.Unmarshal(swt.Sdkdata, &pfp)
|
if err !=nil {
|
fmt.Println("faceDetect result unmarshal err:",err)
|
} else {
|
for _,face :=range pfp.Faces{
|
fmt.Println("FacePos:",face.Pos)
|
fmt.Println("ThftResult:",face.Result)
|
}
|
}
|
}
|
if swt.Sdktype == "FaceExtract"{
|
var pff protomsg.ParamFaceFeature
|
if err := proto.Unmarshal(swt.Sdkdata, &pff);err !=nil{
|
//fmt.Println("ParamFaceFeature unmarshal err:",err)
|
} else {
|
fmt.Println("目标数:",len(pff.ExtComp))
|
if len(pff.ExtComp) >0 {
|
resultMap[rMsg.Cid] = pff.ExtComp
|
|
for _,fea :=range pff.ExtComp{
|
base64Fea := base64.StdEncoding.EncodeToString(fea.Feats)
|
fmt.Println("perId:",perId)
|
fmt.Println("faceFeature:",base64Fea)
|
}
|
}
|
}
|
break
|
}
|
}
|
}
|
} else {
|
fmt.Println("recv msg Err:", err)
|
}
|
|
}
|
}
|