mirror of
https://github.com/LdDl/go-darknet.git
synced 2025-09-27 03:56:18 +08:00
Fix memory issues. Code improvements.
* Use `C.CString()` instead of `C._GoStringPtr()`. - Seems like sometimes the pointer returned by `C._GoStringPtr()` could already be freed, while work is being done in C code that uses the pointer. Using `C.CString()` ensures the C string's lifetime. * Remove own implementation of `free_network()`; Darknet actually does have its own! * Changed some field names of `YOLONetwork` to make them look more consistent.
This commit is contained in:
@@ -1,14 +1,19 @@
|
|||||||
package darknet
|
package darknet
|
||||||
|
|
||||||
|
// #include <stdlib.h>
|
||||||
// #include "class_name.h"
|
// #include "class_name.h"
|
||||||
import "C"
|
import "C"
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
func freeClassNames(names **C.char) {
|
func freeClassNames(names **C.char) {
|
||||||
C.free_class_names(names)
|
C.free_class_names(names)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadClassNames(dataConfigFile string) **C.char {
|
func loadClassNames(dataConfigFile string) **C.char {
|
||||||
return C.read_class_names(C._GoStringPtr(dataConfigFile))
|
d := C.CString(dataConfigFile)
|
||||||
|
defer C.free(unsafe.Pointer(d))
|
||||||
|
|
||||||
|
return C.read_class_names(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeClassNames(names **C.char, classes int) []string {
|
func makeClassNames(names **C.char, classes int) []string {
|
||||||
|
@@ -31,10 +31,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
n := darknet.YOLONetwork{
|
n := darknet.YOLONetwork{
|
||||||
DataConfiguration: *dataConfigFile,
|
DataConfigurationFile: *dataConfigFile,
|
||||||
ConfigurationFile: *configFile,
|
NetworkConfigurationFile: *configFile,
|
||||||
WeightsFile: *weightsFile,
|
WeightsFile: *weightsFile,
|
||||||
Threshold: .5,
|
Threshold: .5,
|
||||||
}
|
}
|
||||||
if err := n.Init(); err != nil {
|
if err := n.Init(); err != nil {
|
||||||
printError(err)
|
printError(err)
|
||||||
|
11
image.go
11
image.go
@@ -2,7 +2,10 @@ package darknet
|
|||||||
|
|
||||||
// #include <darknet.h>
|
// #include <darknet.h>
|
||||||
import "C"
|
import "C"
|
||||||
import "errors"
|
import (
|
||||||
|
"errors"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
// Image represents the image buffer.
|
// Image represents the image buffer.
|
||||||
type Image struct {
|
type Image struct {
|
||||||
@@ -22,8 +25,11 @@ func (img *Image) Close() error {
|
|||||||
|
|
||||||
// ImageFromPath reads image file specified by path.
|
// ImageFromPath reads image file specified by path.
|
||||||
func ImageFromPath(path string) (*Image, error) {
|
func ImageFromPath(path string) (*Image, error) {
|
||||||
|
p := C.CString(path)
|
||||||
|
defer C.free(unsafe.Pointer(p))
|
||||||
|
|
||||||
img := Image{
|
img := Image{
|
||||||
image: C.load_image_color(C._GoStringPtr(path), 0, 0),
|
image: C.load_image_color(p, 0, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
if img.image.data == nil {
|
if img.image.data == nil {
|
||||||
@@ -32,5 +38,6 @@ func ImageFromPath(path string) (*Image, error) {
|
|||||||
|
|
||||||
img.Width = int(img.image.w)
|
img.Width = int(img.image.w)
|
||||||
img.Height = int(img.image.h)
|
img.Height = int(img.image.h)
|
||||||
|
|
||||||
return &img, nil
|
return &img, nil
|
||||||
}
|
}
|
||||||
|
@@ -4,14 +4,6 @@
|
|||||||
|
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
|
||||||
void free_network(network *n)
|
|
||||||
{
|
|
||||||
free(n->layers);
|
|
||||||
free(n->seen);
|
|
||||||
free(n->t);
|
|
||||||
free(n->cost);
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_network_layer_classes(network *n, int index)
|
int get_network_layer_classes(network *n, int index)
|
||||||
{
|
{
|
||||||
return n->layers[index].classes;
|
return n->layers[index].classes;
|
||||||
|
22
network.go
22
network.go
@@ -9,14 +9,15 @@ import "C"
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// YOLONetwork represents a neural network using YOLO.
|
// YOLONetwork represents a neural network using YOLO.
|
||||||
type YOLONetwork struct {
|
type YOLONetwork struct {
|
||||||
DataConfiguration string
|
DataConfigurationFile string
|
||||||
ConfigurationFile string
|
NetworkConfigurationFile string
|
||||||
WeightsFile string
|
WeightsFile string
|
||||||
Threshold float32
|
Threshold float32
|
||||||
|
|
||||||
ClassNames []string
|
ClassNames []string
|
||||||
Classes int
|
Classes int
|
||||||
@@ -31,11 +32,12 @@ var errUnableToInitNetwork = errors.New("unable to initialise")
|
|||||||
|
|
||||||
// Init the network.
|
// Init the network.
|
||||||
func (n *YOLONetwork) Init() error {
|
func (n *YOLONetwork) Init() error {
|
||||||
n.cNet = C.load_network(
|
nCfg := C.CString(n.NetworkConfigurationFile)
|
||||||
C._GoStringPtr(n.ConfigurationFile),
|
defer C.free(unsafe.Pointer(nCfg))
|
||||||
C._GoStringPtr(n.WeightsFile),
|
wFile := C.CString(n.WeightsFile)
|
||||||
0,
|
defer C.free(unsafe.Pointer(wFile))
|
||||||
)
|
|
||||||
|
n.cNet = C.load_network(nCfg, wFile, 0)
|
||||||
|
|
||||||
if n.cNet == nil {
|
if n.cNet == nil {
|
||||||
return errUnableToInitNetwork
|
return errUnableToInitNetwork
|
||||||
@@ -51,7 +53,7 @@ func (n *YOLONetwork) Init() error {
|
|||||||
n.nms = .45
|
n.nms = .45
|
||||||
|
|
||||||
n.Classes = int(C.get_network_layer_classes(n.cNet, n.cNet.n-1))
|
n.Classes = int(C.get_network_layer_classes(n.cNet, n.cNet.n-1))
|
||||||
cClassNames := loadClassNames(n.DataConfiguration)
|
cClassNames := loadClassNames(n.DataConfigurationFile)
|
||||||
defer freeClassNames(cClassNames)
|
defer freeClassNames(cClassNames)
|
||||||
n.ClassNames = makeClassNames(cClassNames, n.Classes)
|
n.ClassNames = makeClassNames(cClassNames, n.Classes)
|
||||||
|
|
||||||
|
@@ -7,7 +7,6 @@ struct network_box_result {
|
|||||||
int detections_len;
|
int detections_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void free_network(network *n);
|
|
||||||
extern int get_network_layer_classes(network *n, int index);
|
extern int get_network_layer_classes(network *n, int index);
|
||||||
extern struct network_box_result perform_network_detect(
|
extern struct network_box_result perform_network_detect(
|
||||||
network *n, image *img,
|
network *n, image *img,
|
||||||
|
Reference in New Issue
Block a user