package main /* #cgo CFLAGS: -I${SRCDIR}/sdk/include -w -g #cgo CXXFLAGS: -I${SRCDIR}/sdk/include -w -g -std=c++11 #cgo LDFLAGS: -L/usr/local/cuda-8.0/lib64 -L${SRCDIR}/sdk/lib #cgo LDFLAGS: -Wl,-rpath,${SRCDIR}/sdk/lib #cgo LDFLAGS: -lTHFaceImage -lTHFeature -lTHFaceProperty -lTHFaceTracking #cgo LDFLAGS: -lcudart -lcublas -lcurand -lrt -ldl -lpthread #include #include "cface.h" */ import "C" import ( "unsafe" "basic.com/libgowrapper/sdkstruct.git" ) // SDKFace sdk type SDKFace struct { handle unsafe.Pointer detector bool extractor bool propertizer bool tracker bool fnLogger func(...interface{}) } // NewSDK sdk func NewSDK(fn func(...interface{})) interface{} { h := C.create_sdkface() if h == nil { return nil } return &SDKFace{ handle: h, detector: false, extractor: false, propertizer: false, tracker: false, fnLogger: fn, } } // Free free func Free(i interface{}) { s := i.(*SDKFace) if s != nil && s.handle != nil { C.release(s.handle) } } func (s *SDKFace) printLog(l ...interface{}) { if s.fnLogger != nil { s.fnLogger(l) } } // Detector detector func Detector(i interface{}, minFaces, rollAngles, threadMax, gpu int) bool { s := i.(*SDKFace) if s.detector { return true } ret := C.init_detector(s.handle, C.int(minFaces), C.int(rollAngles), C.int(threadMax), C.int(gpu)) if ret <= 0 { s.printLog("->face--> CREATE Detector ERROR") return false } s.detector = true return true } // Extractor ext func Extractor(i interface{}, threadMax, gpu int) bool { s := i.(*SDKFace) if s.extractor { return true } ret := C.init_extractor(s.handle, C.int(threadMax), C.int(gpu)) if ret <= 0 { s.printLog("->face--> CREATE Extractor ERROR") return false } s.extractor = true return true } // Propertizer prop func Propertizer(i interface{}, threadMax int) bool { s := i.(*SDKFace) if s.propertizer { return true } ret := C.init_propertizer(s.handle, C.int(threadMax)) if ret <= 0 { s.printLog("->face--> CREATE Propertizer ERROR") return false } s.propertizer = true return true } // Tracker track func Tracker(i interface{}, w, h, maxFaces, interval, sampleSize, threadMax, gpu int) bool { s := i.(*SDKFace) if s.tracker { return s.tracker } ret := C.init_tracker(s.handle, C.int(w), C.int(h), C.int(maxFaces), C.int(interval), C.int(sampleSize), C.int(threadMax), C.int(gpu)) if ret <= 0 { s.printLog("->face--> CREATE Tracker ERROR") return false } s.tracker = true return true } // CFacePosArrayToGoArray convert cFacePos array to go func CFacePosArrayToGoArray(cArray unsafe.Pointer, count int) (goArray []sdkstruct.CFacePos) { p := uintptr(cArray) for i := 0; i < count; i++ { j := *(*sdkstruct.CFacePos)(unsafe.Pointer(p)) goArray = append(goArray, j) p += unsafe.Sizeof(j) } return } // Detect det func Detect(s *SDKFace, data []byte, w, h, c int, ch int) []sdkstruct.CFacePos { if !s.detector { return nil } var cfpos unsafe.Pointer var count C.int ret := C.detect(s.handle, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &cfpos, &count) if ret > 0 { return CFacePosArrayToGoArray(cfpos, int(count)) } s.printLog("->face--> Detect No One, Ret: ", ret) return nil } // Extract extract func Extract(s *SDKFace, fpos sdkstruct.CFacePos, data []byte, w, h, c int, ch int) []byte { pos := (*C.cFacePos)(unsafe.Pointer(&fpos)) //(void *handle, const cFacePos *pos, const void*data, const int w, const int h, const int c, const int chan, void **feat, int *featLen); var feat unsafe.Pointer var featLen C.int ret := C.extract(s.handle, pos, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &feat, &featLen) if ret > 0 { return C.GoBytes(feat, featLen) } s.printLog("->face--> Extract Nothing, Ret: ", ret) return nil } // Compare face compare func Compare(i interface{}, feat1 []byte, feat2 []byte) float32 { s := i.(*SDKFace) if s.extractor { return 0 } res := C.compare(s.handle, (*C.uchar)(unsafe.Pointer(&feat1[0])), (*C.uchar)(unsafe.Pointer(&feat2[0]))) return float32(res) } // Propertize prop func Propertize(s *SDKFace, fpos sdkstruct.CFacePos, data []byte, w, h, c int, ch int) *sdkstruct.CThftResult { if !s.propertizer { return nil } pos := (*C.cFacePos)(unsafe.Pointer(&fpos)) var thft unsafe.Pointer ret := C.propertize(s.handle, pos, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &thft) if ret == 0 { gothft := *(*sdkstruct.CThftResult)(thft) C.free(thft) return &gothft } s.printLog("->face--> Propertize Nothing, Ret: ", ret) return nil } // CFaceInfoArrayToGoArray convert cFaceInfo array to go func CFaceInfoArrayToGoArray(cArray unsafe.Pointer, count int) (goArray []sdkstruct.CFaceInfo) { p := uintptr(cArray) for i := 0; i < count; i++ { j := *(*sdkstruct.CFaceInfo)(unsafe.Pointer(p)) goArray = append(goArray, j) p += unsafe.Sizeof(j) } return } // Track track func Track(s *SDKFace, data []byte, w, h, c int, ch int) []sdkstruct.CFaceInfo { if !s.tracker { return nil } //img, const int chan, void **fInfo, int *fcnt); var fCount C.int var finfos unsafe.Pointer ret := C.track(s.handle, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &finfos, &fCount) if ret > 0 { faces := CFaceInfoArrayToGoArray(finfos, int(fCount)) //if len(faces) > 0{ // fmt.Println("faces detected:", len(faces)) //} return faces } return nil } // FaceInfo2FacePos info -> pos func FaceInfo2FacePos(face sdkstruct.CFaceInfo) (fPos sdkstruct.CFacePos) { fPos.RcFace = face.RcFace fPos.PtLeftEye = face.PtLeftEye fPos.PtRightEye = face.PtRightEye fPos.PtNose = face.PtNose fPos.PtMouth = face.PtMouth fPos.FAngle.Yaw = face.FAngle.Yaw fPos.FAngle.Pitch = face.FAngle.Pitch fPos.FAngle.Roll = face.FAngle.Roll fPos.FAngle.Confidence = face.FAngle.Confidence copy(fPos.PFacialData[:], face.PFacialData[:512]) return fPos } // TrackerResize init face tracker func TrackerResize(i interface{}, w, h, ch int) bool { s := i.(*SDKFace) if !s.tracker { s.printLog("->face--> TrackerResize Failed, No Tracker Init") return false } ret := C.resize(s.handle, C.int(w), C.int(h), C.int(ch)) if ret == 1 { return true } s.printLog("->face--> TrackerResize Failed, Ret: ", ret, " SDK Channel: ", ch, " Size: ", w, "x", h) return false } // Run run func Run(i interface{}, data []byte, w, h, c, dchan int) []sdkstruct.CFaceResult { if data == nil || w <= 0 || h <= 0 { return nil } s := i.(*SDKFace) if !s.tracker || !s.extractor || !s.propertizer { return nil } channel := c if channel == 0 { channel = 3 } // if !TrackerResize(i, w, h, dchan) { // return nil // } var fInfo []sdkstruct.CFaceInfo fInfo = Track(s, data, w, h, c, dchan) var faces []sdkstruct.CFaceResult //将sdk返回值转换成protomsg类型 for _, d := range fInfo { //运行sd dec := FaceInfo2FacePos(d) prop := Propertize(s, dec, data, w, h, c, dchan) feat := Extract(s, dec, data, w, h, c, dchan) result := sdkstruct.CFaceResult{ Info: d, Prop: *prop, Feat: feat, } faces = append(faces, result) } return faces }