mirror of
https://github.com/hybridgroup/gocv
synced 2025-08-25 08:41:04 +08:00
added contrib.xobjdetect
This commit is contained in:
@@ -350,5 +350,5 @@ Your pull requests will be greatly appreciated!
|
||||
- [X] **wechat_qrcode. WeChat QR code detector for detecting and parsing QR code**
|
||||
- [ ] **xfeatures2d. Extra 2D Features Framework - WORK STARTED**
|
||||
- [ ] **ximgproc. Extended Image Processing - WORK STARTED**
|
||||
- [ ] xobjdetect. Extended object detection
|
||||
- [X] xobjdetect. Extended object detection
|
||||
- [X] **xphoto. Additional photo processing algorithms**
|
||||
|
51
contrib/xobjdetect.cpp
Normal file
51
contrib/xobjdetect.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "xobjdetect.h"
|
||||
|
||||
WBDetector WBDetector_Create(){
|
||||
return new cv::Ptr<cv::xobjdetect::WBDetector>(cv::xobjdetect::WBDetector::create());
|
||||
}
|
||||
|
||||
void WBDetector_Close(WBDetector det){
|
||||
delete det;
|
||||
}
|
||||
|
||||
WBDetector_detect_result WBDetector_Detect(WBDetector det, Mat img){
|
||||
std::vector<cv::Rect> bb;
|
||||
std::vector<double> conf;
|
||||
WBDetector_detect_result result;
|
||||
|
||||
(*det)->detect(*img, bb, conf);
|
||||
|
||||
Rect* result_rects = (Rect*)malloc(bb.size()*sizeof(Rect));
|
||||
float* result_confs = (float*)malloc(conf.size()*sizeof(float));
|
||||
|
||||
for(int i = 0; i < bb.size(); i ++) {
|
||||
result_rects[i].x = bb[i].x;
|
||||
result_rects[i].y = bb[i].y;
|
||||
result_rects[i].width = bb[i].width;
|
||||
result_rects[i].height = bb[i].height;
|
||||
}
|
||||
|
||||
for(int i = 0; i < conf.size(); i ++){
|
||||
result_confs[i] = conf[i];
|
||||
}
|
||||
|
||||
result.bboxes.rects = result_rects;
|
||||
result.bboxes.length = bb.size();
|
||||
|
||||
result.confidences.val = result_confs;
|
||||
result.confidences.length = conf.size();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void WBDetector_Read(WBDetector det, FileNode node){
|
||||
(*det)->read(*node);
|
||||
}
|
||||
|
||||
void WBDetector_Train(WBDetector det, const char* pos_samples, const char* neg_imgs){
|
||||
(*det)->train(pos_samples, neg_imgs);
|
||||
}
|
||||
|
||||
void WBDetector_Write(WBDetector det, FileStorage fs){
|
||||
(*det)->write(*fs);
|
||||
}
|
108
contrib/xobjdetect.go
Normal file
108
contrib/xobjdetect.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package contrib
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include "xobjdetect.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"image"
|
||||
"unsafe"
|
||||
|
||||
"gocv.io/x/gocv"
|
||||
)
|
||||
|
||||
// WBDetector is a wrapper around the cv::xobjdetect::WBDetector.
|
||||
type WBDetector struct {
|
||||
p C.WBDetector
|
||||
}
|
||||
|
||||
// NewWBDetector Creates a new WBDetector
|
||||
//
|
||||
// For further details, please see:
|
||||
// https://docs.opencv.org/4.x/de/d0e/classcv_1_1xobjdetect_1_1WBDetector.html#a58377ae61694aac08ad842ac830972d9
|
||||
func NewWBDetector() WBDetector {
|
||||
p := C.WBDetector_Create()
|
||||
return WBDetector{p: p}
|
||||
}
|
||||
|
||||
// Close Releases WBDetector allocated resources.
|
||||
func (det *WBDetector) Close() {
|
||||
C.WBDetector_Close(det.p)
|
||||
}
|
||||
|
||||
// Detect Detect objects on image using WaldBoost detector
|
||||
//
|
||||
// img: Input image for detection
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// Bounding boxes coordinates and
|
||||
// Confidence values for bounding boxes output vector
|
||||
//
|
||||
// For further details, please see:
|
||||
// https://docs.opencv.org/4.x/de/d0e/classcv_1_1xobjdetect_1_1WBDetector.html#ad19680e6545f49a9ca42dfc3457319e2
|
||||
func (det *WBDetector) Detect(img gocv.Mat) ([]image.Rectangle, []float32) {
|
||||
|
||||
result := C.WBDetector_Detect(det.p, C.Mat(img.Ptr()))
|
||||
|
||||
defer C.free(unsafe.Pointer(result.bboxes.rects))
|
||||
defer C.free(unsafe.Pointer(result.confidences.val))
|
||||
|
||||
cRects := unsafe.Slice(result.bboxes.rects, result.bboxes.length)
|
||||
cConfs := unsafe.Slice(result.confidences.val, result.confidences.length)
|
||||
|
||||
goRects := make([]image.Rectangle, int(result.bboxes.length))
|
||||
goConfs := make([]float32, int(result.confidences.length))
|
||||
|
||||
for i := 0; i < int(result.bboxes.length); i++ {
|
||||
r := image.Rect(int(cRects[i].x),
|
||||
int(cRects[i].y),
|
||||
int(cRects[i].width),
|
||||
int(cRects[i].height))
|
||||
|
||||
goRects = append(goRects, r)
|
||||
}
|
||||
|
||||
for i := 0; i < int(result.confidences.length); i++ {
|
||||
goConfs[i] = float32(cConfs[i])
|
||||
}
|
||||
|
||||
return goRects, goConfs
|
||||
}
|
||||
|
||||
// Read Read detector from gocv.FileNode
|
||||
//
|
||||
// For further details, please see:
|
||||
// https://docs.opencv.org/4.x/de/d0e/classcv_1_1xobjdetect_1_1WBDetector.html#aef2df760f45d25aade518196986e139f
|
||||
func (det *WBDetector) Read(node *gocv.FileNode) {
|
||||
C.WBDetector_Read(det.p, C.FileNode(node.Ptr()))
|
||||
}
|
||||
|
||||
// Train WaldBoost detector.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// posSamples: Path to directory with cropped positive samples
|
||||
//
|
||||
// negImgs: Path to directory with negative (background) images
|
||||
//
|
||||
// For further details, please see:
|
||||
// https://docs.opencv.org/4.x/de/d0e/classcv_1_1xobjdetect_1_1WBDetector.html#a3720fb425a2d16f6cd0625a2d8bc563e
|
||||
func (det *WBDetector) Train(posSamples string, negImgs string) {
|
||||
|
||||
pos_samples := C.CString(posSamples)
|
||||
neg_imgs := C.CString(negImgs)
|
||||
defer C.free(unsafe.Pointer(pos_samples))
|
||||
defer C.free(unsafe.Pointer(neg_imgs))
|
||||
|
||||
C.WBDetector_Train(det.p, pos_samples, neg_imgs)
|
||||
}
|
||||
|
||||
// Write detector to gocv.FileStorage.
|
||||
//
|
||||
// For further details, please see:
|
||||
// https://docs.opencv.org/4.x/de/d0e/classcv_1_1xobjdetect_1_1WBDetector.html#a7d85338895707904ae1ddb4374ec8dac
|
||||
func (det *WBDetector) Write(fs *gocv.FileStorage) {
|
||||
C.WBDetector_Write(det.p, C.FileStorage(fs.Ptr()))
|
||||
}
|
35
contrib/xobjdetect.h
Normal file
35
contrib/xobjdetect.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _OPENCV3_XOBJDETECT_H_
|
||||
#define _OPENCV3_XOBJDETECT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/xobjdetect.hpp>
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../core.h"
|
||||
#include "../persistence.h"
|
||||
|
||||
typedef struct WBDetector_detect_result_t {
|
||||
Rects bboxes;
|
||||
FloatVector confidences;
|
||||
} WBDetector_detect_result;
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef cv::Ptr<cv::xobjdetect::WBDetector>* WBDetector;
|
||||
#else
|
||||
typedef void* WBDetector;
|
||||
#endif
|
||||
|
||||
WBDetector WBDetector_Create();
|
||||
void WBDetector_Close(WBDetector det);
|
||||
WBDetector_detect_result WBDetector_Detect(WBDetector det, Mat img);
|
||||
void WBDetector_Read(WBDetector det, FileNode node);
|
||||
void WBDetector_Train(WBDetector det, const char* pos_samples, const char* neg_imgs);
|
||||
void WBDetector_Write(WBDetector det, FileStorage fs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_OPENCV3_XOBJDETECT_H_
|
36
contrib/xobjdetect_test.go
Normal file
36
contrib/xobjdetect_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package contrib
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gocv.io/x/gocv"
|
||||
)
|
||||
|
||||
func TestWBDetector(t *testing.T) {
|
||||
|
||||
img := gocv.IMRead("../images/face.jpg", gocv.IMReadAnyColor)
|
||||
if img.Empty() {
|
||||
t.Error("xobjdetect: cannot read image")
|
||||
}
|
||||
|
||||
det := NewWBDetector()
|
||||
defer det.Close()
|
||||
|
||||
det.Train("../images/gocvlogo.jpg", "../images/gocvlogo.png")
|
||||
|
||||
det.Detect(img)
|
||||
|
||||
fs := gocv.NewFileStorageWithParams("../testdata/WBDetector.json", gocv.FileStorageModeWrite, "utf-8")
|
||||
defer fs.Close()
|
||||
|
||||
fs.StartWriteStruct("gocv", gocv.FileNodeTypeSeq, "model")
|
||||
|
||||
det.Write(fs)
|
||||
|
||||
fs.EndWriteStruct()
|
||||
|
||||
node := fs.GetFirstTopLevelNode()
|
||||
|
||||
det.Read(node)
|
||||
|
||||
}
|
@@ -32,6 +32,10 @@ type FileNode struct {
|
||||
p C.FileNode
|
||||
}
|
||||
|
||||
func (fn *FileNode) Ptr() C.FileNode {
|
||||
return fn.p
|
||||
}
|
||||
|
||||
func (fn *FileNode) Empty() bool {
|
||||
return bool(C.FileNode_Empty(fn.p))
|
||||
}
|
||||
|
@@ -200,3 +200,7 @@ func (fs *FileStorage) Root(streamIdx int) *FileNode {
|
||||
node_p := C.FileStorage_Root(fs.p, C.int(streamIdx))
|
||||
return &FileNode{p: node_p}
|
||||
}
|
||||
|
||||
func (fs *FileStorage) Ptr() C.FileStorage {
|
||||
return fs.p
|
||||
}
|
||||
|
Reference in New Issue
Block a user