286 lines
9.1 KiB
Go
286 lines
9.1 KiB
Go
|
package gocv
|
||
|
|
||
|
/*
|
||
|
#include <stdlib.h>
|
||
|
#include "objdetect.h"
|
||
|
*/
|
||
|
import "C"
|
||
|
import (
|
||
|
"image"
|
||
|
"unsafe"
|
||
|
)
|
||
|
|
||
|
// CascadeClassifier is a cascade classifier class for object detection.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// http://docs.opencv.org/master/d1/de5/classcv_1_1CascadeClassifier.html
|
||
|
//
|
||
|
type CascadeClassifier struct {
|
||
|
p C.CascadeClassifier
|
||
|
}
|
||
|
|
||
|
// NewCascadeClassifier returns a new CascadeClassifier.
|
||
|
func NewCascadeClassifier() CascadeClassifier {
|
||
|
return CascadeClassifier{p: C.CascadeClassifier_New()}
|
||
|
}
|
||
|
|
||
|
// Close deletes the CascadeClassifier's pointer.
|
||
|
func (c *CascadeClassifier) Close() error {
|
||
|
C.CascadeClassifier_Close(c.p)
|
||
|
c.p = nil
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Load cascade classifier from a file.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// http://docs.opencv.org/master/d1/de5/classcv_1_1CascadeClassifier.html#a1a5884c8cc749422f9eb77c2471958bc
|
||
|
//
|
||
|
func (c *CascadeClassifier) Load(name string) bool {
|
||
|
cName := C.CString(name)
|
||
|
defer C.free(unsafe.Pointer(cName))
|
||
|
return C.CascadeClassifier_Load(c.p, cName) != 0
|
||
|
}
|
||
|
|
||
|
// DetectMultiScale detects objects of different sizes in the input Mat image.
|
||
|
// The detected objects are returned as a slice of image.Rectangle structs.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// http://docs.opencv.org/master/d1/de5/classcv_1_1CascadeClassifier.html#aaf8181cb63968136476ec4204ffca498
|
||
|
//
|
||
|
func (c *CascadeClassifier) DetectMultiScale(img Mat) []image.Rectangle {
|
||
|
ret := C.CascadeClassifier_DetectMultiScale(c.p, img.p)
|
||
|
defer C.Rects_Close(ret)
|
||
|
|
||
|
return toRectangles(ret)
|
||
|
}
|
||
|
|
||
|
// DetectMultiScaleWithParams calls DetectMultiScale but allows setting parameters
|
||
|
// to values other than just the defaults.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// http://docs.opencv.org/master/d1/de5/classcv_1_1CascadeClassifier.html#aaf8181cb63968136476ec4204ffca498
|
||
|
//
|
||
|
func (c *CascadeClassifier) DetectMultiScaleWithParams(img Mat, scale float64,
|
||
|
minNeighbors, flags int, minSize, maxSize image.Point) []image.Rectangle {
|
||
|
|
||
|
minSz := C.struct_Size{
|
||
|
width: C.int(minSize.X),
|
||
|
height: C.int(minSize.Y),
|
||
|
}
|
||
|
|
||
|
maxSz := C.struct_Size{
|
||
|
width: C.int(maxSize.X),
|
||
|
height: C.int(maxSize.Y),
|
||
|
}
|
||
|
|
||
|
ret := C.CascadeClassifier_DetectMultiScaleWithParams(c.p, img.p, C.double(scale),
|
||
|
C.int(minNeighbors), C.int(flags), minSz, maxSz)
|
||
|
defer C.Rects_Close(ret)
|
||
|
|
||
|
return toRectangles(ret)
|
||
|
}
|
||
|
|
||
|
// HOGDescriptor is a Histogram Of Gradiants (HOG) for object detection.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/d5/d33/structcv_1_1HOGDescriptor.html#a723b95b709cfd3f95cf9e616de988fc8
|
||
|
//
|
||
|
type HOGDescriptor struct {
|
||
|
p C.HOGDescriptor
|
||
|
}
|
||
|
|
||
|
// NewHOGDescriptor returns a new HOGDescriptor.
|
||
|
func NewHOGDescriptor() HOGDescriptor {
|
||
|
return HOGDescriptor{p: C.HOGDescriptor_New()}
|
||
|
}
|
||
|
|
||
|
// Close deletes the HOGDescriptor's pointer.
|
||
|
func (h *HOGDescriptor) Close() error {
|
||
|
C.HOGDescriptor_Close(h.p)
|
||
|
h.p = nil
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// DetectMultiScale detects objects in the input Mat image.
|
||
|
// The detected objects are returned as a slice of image.Rectangle structs.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/d5/d33/structcv_1_1HOGDescriptor.html#a660e5cd036fd5ddf0f5767b352acd948
|
||
|
//
|
||
|
func (h *HOGDescriptor) DetectMultiScale(img Mat) []image.Rectangle {
|
||
|
ret := C.HOGDescriptor_DetectMultiScale(h.p, img.p)
|
||
|
defer C.Rects_Close(ret)
|
||
|
|
||
|
return toRectangles(ret)
|
||
|
}
|
||
|
|
||
|
// DetectMultiScaleWithParams calls DetectMultiScale but allows setting parameters
|
||
|
// to values other than just the defaults.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/d5/d33/structcv_1_1HOGDescriptor.html#a660e5cd036fd5ddf0f5767b352acd948
|
||
|
//
|
||
|
func (h *HOGDescriptor) DetectMultiScaleWithParams(img Mat, hitThresh float64,
|
||
|
winStride, padding image.Point, scale, finalThreshold float64, useMeanshiftGrouping bool) []image.Rectangle {
|
||
|
wSz := C.struct_Size{
|
||
|
width: C.int(winStride.X),
|
||
|
height: C.int(winStride.Y),
|
||
|
}
|
||
|
|
||
|
pSz := C.struct_Size{
|
||
|
width: C.int(padding.X),
|
||
|
height: C.int(padding.Y),
|
||
|
}
|
||
|
|
||
|
ret := C.HOGDescriptor_DetectMultiScaleWithParams(h.p, img.p, C.double(hitThresh),
|
||
|
wSz, pSz, C.double(scale), C.double(finalThreshold), C.bool(useMeanshiftGrouping))
|
||
|
defer C.Rects_Close(ret)
|
||
|
|
||
|
return toRectangles(ret)
|
||
|
}
|
||
|
|
||
|
// HOGDefaultPeopleDetector returns a new Mat with the HOG DefaultPeopleDetector.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/d5/d33/structcv_1_1HOGDescriptor.html#a660e5cd036fd5ddf0f5767b352acd948
|
||
|
//
|
||
|
func HOGDefaultPeopleDetector() Mat {
|
||
|
return newMat(C.HOG_GetDefaultPeopleDetector())
|
||
|
}
|
||
|
|
||
|
// SetSVMDetector sets the data for the HOGDescriptor.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/d5/d33/structcv_1_1HOGDescriptor.html#a09e354ad701f56f9c550dc0385dc36f1
|
||
|
//
|
||
|
func (h *HOGDescriptor) SetSVMDetector(det Mat) error {
|
||
|
C.HOGDescriptor_SetSVMDetector(h.p, det.p)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// GroupRectangles groups the object candidate rectangles.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/d5/d54/group__objdetect.html#ga3dba897ade8aa8227edda66508e16ab9
|
||
|
//
|
||
|
func GroupRectangles(rects []image.Rectangle, groupThreshold int, eps float64) []image.Rectangle {
|
||
|
cRectArray := make([]C.struct_Rect, len(rects))
|
||
|
for i, r := range rects {
|
||
|
cRect := C.struct_Rect{
|
||
|
x: C.int(r.Min.X),
|
||
|
y: C.int(r.Min.Y),
|
||
|
width: C.int(r.Size().X),
|
||
|
height: C.int(r.Size().Y),
|
||
|
}
|
||
|
cRectArray[i] = cRect
|
||
|
}
|
||
|
cRects := C.struct_Rects{
|
||
|
rects: (*C.Rect)(&cRectArray[0]),
|
||
|
length: C.int(len(rects)),
|
||
|
}
|
||
|
|
||
|
ret := C.GroupRectangles(cRects, C.int(groupThreshold), C.double(eps))
|
||
|
|
||
|
return toRectangles(ret)
|
||
|
}
|
||
|
|
||
|
// QRCodeDetector groups the object candidate rectangles.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/de/dc3/classcv_1_1QRCodeDetector.html
|
||
|
//
|
||
|
type QRCodeDetector struct {
|
||
|
p C.QRCodeDetector
|
||
|
}
|
||
|
|
||
|
// newQRCodeDetector returns a new QRCodeDetector from a C QRCodeDetector
|
||
|
func newQRCodeDetector(p C.QRCodeDetector) QRCodeDetector {
|
||
|
return QRCodeDetector{p: p}
|
||
|
}
|
||
|
|
||
|
func NewQRCodeDetector() QRCodeDetector {
|
||
|
return newQRCodeDetector(C.QRCodeDetector_New())
|
||
|
}
|
||
|
|
||
|
func (a *QRCodeDetector) Close() error {
|
||
|
C.QRCodeDetector_Close(a.p)
|
||
|
a.p = nil
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// DetectAndDecode Both detects and decodes QR code.
|
||
|
//
|
||
|
// Returns true as long as some QR code was detected even in case where the decoding failed
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/de/dc3/classcv_1_1QRCodeDetector.html#a7290bd6a5d59b14a37979c3a14fbf394
|
||
|
//
|
||
|
func (a *QRCodeDetector) DetectAndDecode(input Mat, points *Mat, straight_qrcode *Mat) string {
|
||
|
goResult := C.GoString(C.QRCodeDetector_DetectAndDecode(a.p, input.p, points.p, straight_qrcode.p))
|
||
|
return string(goResult)
|
||
|
}
|
||
|
|
||
|
// Detect detects QR code in image and returns the quadrangle containing the code.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/de/dc3/classcv_1_1QRCodeDetector.html#a64373f7d877d27473f64fe04bb57d22b
|
||
|
//
|
||
|
func (a *QRCodeDetector) Detect(input Mat, points *Mat) bool {
|
||
|
result := C.QRCodeDetector_Detect(a.p, input.p, points.p)
|
||
|
return bool(result)
|
||
|
}
|
||
|
|
||
|
// Decode decodes QR code in image once it's found by the detect() method. Returns UTF8-encoded output string or empty string if the code cannot be decoded.
|
||
|
//
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/de/dc3/classcv_1_1QRCodeDetector.html#a4172c2eb4825c844fb1b0ae67202d329
|
||
|
//
|
||
|
func (a *QRCodeDetector) Decode(input Mat, points Mat, straight_qrcode *Mat) string {
|
||
|
goResult := C.GoString(C.QRCodeDetector_DetectAndDecode(a.p, input.p, points.p, straight_qrcode.p))
|
||
|
return string(goResult)
|
||
|
}
|
||
|
|
||
|
// Detects QR codes in image and finds of the quadrangles containing the codes.
|
||
|
//
|
||
|
// Each quadrangle would be returned as a row in the `points` Mat and each point is a Vecf.
|
||
|
// Returns true if QR code was detected
|
||
|
// For usage please see TestQRCodeDetector
|
||
|
// For further details, please see:
|
||
|
// https://docs.opencv.org/master/de/dc3/classcv_1_1QRCodeDetector.html#aaf2b6b2115b8e8fbc9acf3a8f68872b6
|
||
|
func (a *QRCodeDetector) DetectMulti(input Mat, points *Mat) bool {
|
||
|
result := C.QRCodeDetector_DetectMulti(a.p, input.p, points.p)
|
||
|
return bool(result)
|
||
|
}
|
||
|
|
||
|
// Detects QR codes in image and finds of the quadrangles containing the codes and decode the decode the QRCodes to strings.
|
||
|
//
|
||
|
// Each quadrangle would be returned as a row in the `points` Mat and each point is a Vecf.
|
||
|
// Returns true as long as some QR code was detected even in case where the decoding failed
|
||
|
// For usage please see TestQRCodeDetector
|
||
|
// For further details, please see:
|
||
|
//https://docs.opencv.org/master/de/dc3/classcv_1_1QRCodeDetector.html#a188b63ffa17922b2c65d8a0ab7b70775
|
||
|
func (a *QRCodeDetector) DetectAndDecodeMulti(input Mat, decoded *[]string, points *Mat, qrCodes *[]Mat) bool {
|
||
|
cDecoded := C.CStrings{}
|
||
|
defer C.CStrings_Close(cDecoded)
|
||
|
cQrCodes := C.struct_Mats{}
|
||
|
defer C.Mats_Close(cQrCodes)
|
||
|
success := C.QRCodeDetector_DetectAndDecodeMulti(a.p, input.p, &cDecoded, points.p, &cQrCodes)
|
||
|
if !success {
|
||
|
return bool(success)
|
||
|
}
|
||
|
|
||
|
tmpCodes := make([]Mat, cQrCodes.length)
|
||
|
for i := C.int(0); i < cQrCodes.length; i++ {
|
||
|
tmpCodes[i].p = C.Mats_get(cQrCodes, i)
|
||
|
}
|
||
|
|
||
|
for _, qr := range tmpCodes {
|
||
|
*qrCodes = append(*qrCodes, qr)
|
||
|
}
|
||
|
|
||
|
for _, s := range toGoStrings(cDecoded) {
|
||
|
*decoded = append(*decoded, s)
|
||
|
}
|
||
|
return bool(success)
|
||
|
}
|