package HikNetSDK import ( "fmt" "sync" "unsafe" ) type HIKBallCamera struct { core unsafe.Pointer State bool BallCameraCfg BallCamera mux sync.RWMutex } func NewHIKBallCamera(BallCameraCfg BallCamera) *HIKBallCamera { return &HIKBallCamera{ core: newHIKBallCamera(), BallCameraCfg: BallCameraCfg, State: false, mux: sync.RWMutex{}, } } func (hikBC *HIKBallCamera) Login() bool { hikBC.mux.Lock() hikBC.State = initBallCamera(hikBC.core, hikBC.BallCameraCfg.Ip, hikBC.BallCameraCfg.Port, hikBC.BallCameraCfg.User, hikBC.BallCameraCfg.Password, hikBC.BallCameraCfg.Type) hikBC.mux.Unlock() return hikBC.State } func (hikBC *HIKBallCamera) opt(action func() bool) bool { hikBC.mux.RLock() if hikBC.State { hikBC.mux.RUnlock() hikBC.mux.Lock() hikBC.State = action() hikBC.mux.Unlock() } else { hikBC.mux.RUnlock() } return hikBC.State } func (hikBC *HIKBallCamera) PTZGet(P, T, Z *float32) bool { return hikBC.opt(func() bool { return ptzGet(hikBC.core, unsafe.Pointer(P), unsafe.Pointer(T), unsafe.Pointer(Z)) }) } func (hikBC *HIKBallCamera) PtzTo(Action int, P, T, Z float32) bool { return hikBC.opt(func() bool { return ptzTo(hikBC.core, Action, P, T, Z) }) } func (hikBC *HIKBallCamera) StartBus(Direction, Speed int) bool { return hikBC.opt(func() bool { return startBus(hikBC.core, Direction, Speed) }) } func (hikBC *HIKBallCamera) StopBus(Direction int) bool { return hikBC.opt(func() bool { return stopBus(hikBC.core, Direction) }) } func (hikBC *HIKBallCamera) OneClickToSeeInFullView(point Point) bool { TransPoint := hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.Matrix, point) return hikBC.PtzTo(5, float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, TransPoint.X, hikBC.BallCameraCfg.Matrix.PPositiveDirection, "inv")), float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, TransPoint.Y, hikBC.BallCameraCfg.Matrix.TPositiveDirection, "inv")), 0.0, ) } func (hikBC *HIKBallCamera) PTZ2FullView() (Point, error) { var ptz PTZ if !hikBC.PTZGet(&ptz.P, &ptz.T, &ptz.Z) { return Point{}, fmt.Errorf("PTZ Get Error") } return hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.InvMatrix, Point{ X: hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, float64(ptz.P), hikBC.BallCameraCfg.Matrix.PPositiveDirection, ""), Y: hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, float64(ptz.T), hikBC.BallCameraCfg.Matrix.TPositiveDirection, "")}), nil } func (hikBC *HIKBallCamera) WarpingPtByHomography(matrix []float64, p Point) Point { var x, y, z float64 x = matrix[0]*p.X + matrix[1]*p.Y + 1.*matrix[2] y = matrix[3]*p.X + matrix[4]*p.Y + 1.*matrix[5] z = matrix[6]*p.X + matrix[7]*p.Y + 1.*matrix[8] x /= z y /= z return Point{X: x, Y: y} } func (hikBC *HIKBallCamera) Invert3x3() bool { a := hikBC.BallCameraCfg.Matrix.Matrix[0] b := hikBC.BallCameraCfg.Matrix.Matrix[1] c := hikBC.BallCameraCfg.Matrix.Matrix[2] d := hikBC.BallCameraCfg.Matrix.Matrix[3] e := hikBC.BallCameraCfg.Matrix.Matrix[4] f := hikBC.BallCameraCfg.Matrix.Matrix[5] g := hikBC.BallCameraCfg.Matrix.Matrix[6] h := hikBC.BallCameraCfg.Matrix.Matrix[7] i := hikBC.BallCameraCfg.Matrix.Matrix[8] det := a*(e*i-f*h) - b*(d*i-f*g) + c*(d*h-e*g) if det == 0 { return false } invDet := 1.0 / det hikBC.BallCameraCfg.Matrix.InvMatrix = []float64{ (e*i - f*h) * invDet, (c*h - b*i) * invDet, (b*f - c*e) * invDet, (f*g - d*i) * invDet, (a*i - c*g) * invDet, (c*d - a*f) * invDet, (d*h - e*g) * invDet, (b*g - a*h) * invDet, (a*e - b*d) * invDet, } return true } func (hikBC *HIKBallCamera) mapping(startV float64, max float64, value float64, direction string, method string) float64 { if direction == "+" { if method == "inv" { if value > (max - startV) { return value - (max - startV) } else { return startV + value // 映射 } } else { if value > startV { return value - startV } else { return (max - startV) + value // 映射 } } } else { if value > startV { return startV + max - value } else { return startV - value } } }