mirror of
https://github.com/LdDl/go-darknet.git
synced 2025-09-26 19:51:27 +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
|
||||
|
||||
// #include <stdlib.h>
|
||||
// #include "class_name.h"
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func freeClassNames(names **C.char) {
|
||||
C.free_class_names(names)
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@@ -31,10 +31,10 @@ func main() {
|
||||
}
|
||||
|
||||
n := darknet.YOLONetwork{
|
||||
DataConfiguration: *dataConfigFile,
|
||||
ConfigurationFile: *configFile,
|
||||
WeightsFile: *weightsFile,
|
||||
Threshold: .5,
|
||||
DataConfigurationFile: *dataConfigFile,
|
||||
NetworkConfigurationFile: *configFile,
|
||||
WeightsFile: *weightsFile,
|
||||
Threshold: .5,
|
||||
}
|
||||
if err := n.Init(); err != nil {
|
||||
printError(err)
|
||||
|
11
image.go
11
image.go
@@ -2,7 +2,10 @@ package darknet
|
||||
|
||||
// #include <darknet.h>
|
||||
import "C"
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Image represents the image buffer.
|
||||
type Image struct {
|
||||
@@ -22,8 +25,11 @@ func (img *Image) Close() error {
|
||||
|
||||
// ImageFromPath reads image file specified by path.
|
||||
func ImageFromPath(path string) (*Image, error) {
|
||||
p := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(p))
|
||||
|
||||
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 {
|
||||
@@ -32,5 +38,6 @@ func ImageFromPath(path string) (*Image, error) {
|
||||
|
||||
img.Width = int(img.image.w)
|
||||
img.Height = int(img.image.h)
|
||||
|
||||
return &img, nil
|
||||
}
|
||||
|
@@ -4,14 +4,6 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
return n->layers[index].classes;
|
||||
|
22
network.go
22
network.go
@@ -9,14 +9,15 @@ import "C"
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// YOLONetwork represents a neural network using YOLO.
|
||||
type YOLONetwork struct {
|
||||
DataConfiguration string
|
||||
ConfigurationFile string
|
||||
WeightsFile string
|
||||
Threshold float32
|
||||
DataConfigurationFile string
|
||||
NetworkConfigurationFile string
|
||||
WeightsFile string
|
||||
Threshold float32
|
||||
|
||||
ClassNames []string
|
||||
Classes int
|
||||
@@ -31,11 +32,12 @@ var errUnableToInitNetwork = errors.New("unable to initialise")
|
||||
|
||||
// Init the network.
|
||||
func (n *YOLONetwork) Init() error {
|
||||
n.cNet = C.load_network(
|
||||
C._GoStringPtr(n.ConfigurationFile),
|
||||
C._GoStringPtr(n.WeightsFile),
|
||||
0,
|
||||
)
|
||||
nCfg := C.CString(n.NetworkConfigurationFile)
|
||||
defer C.free(unsafe.Pointer(nCfg))
|
||||
wFile := C.CString(n.WeightsFile)
|
||||
defer C.free(unsafe.Pointer(wFile))
|
||||
|
||||
n.cNet = C.load_network(nCfg, wFile, 0)
|
||||
|
||||
if n.cNet == nil {
|
||||
return errUnableToInitNetwork
|
||||
@@ -51,7 +53,7 @@ func (n *YOLONetwork) Init() error {
|
||||
n.nms = .45
|
||||
|
||||
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)
|
||||
n.ClassNames = makeClassNames(cClassNames, n.Classes)
|
||||
|
||||
|
Reference in New Issue
Block a user