upd git ignore

This commit is contained in:
Dimitrii
2020-02-18 13:21:18 +03:00
parent 7337b22df9
commit 87175172a2
15 changed files with 132 additions and 288 deletions

4
.gitignore vendored
View File

@@ -7,4 +7,6 @@ example/yolov3-320.weights
example/yolov3-416.cfg
example/yolov3-416.weights
example/yolov3.cfg
example/yolov3.weights
example/yolov3.weights
darknet.h
*.so

View File

@@ -1,24 +0,0 @@
#include <stdlib.h>
#include <darknet.h>
void free_class_names(char **names)
{
free(names);
}
char ** read_class_names(char *data_cfg)
{
list *options = read_data_cfg(data_cfg);
char *name_list = option_find_str(options, "names", "data/names.list");
return get_labels(name_list);
}
char * get_class_name(char **names, int index, int names_len)
{
if (index >= names_len) {
return NULL;
}
return names[index];
}

View File

@@ -1,28 +0,0 @@
package darknet
// #include <stdlib.h>
// #include "classnames.h"
import "C"
import "unsafe"
func freeClassNames(names **C.char) {
C.free_class_names(names)
}
func loadClassNames(dataConfigFile string) **C.char {
d := C.CString(dataConfigFile)
defer C.free(unsafe.Pointer(d))
return C.read_class_names(d)
}
func makeClassNames(names **C.char, classes int) []string {
out := make([]string, classes)
for i := 0; i < classes; i++ {
n := C.get_class_name(names, C.int(i), C.int(classes))
s := C.GoString(n)
out[i] = s
}
return out
}

View File

@@ -1,5 +0,0 @@
#pragma once
extern void free_class_names(char **names);
extern char ** read_class_names(char *data_cfg);
extern char * get_class_name(char **names, int index, int names_len);

View File

@@ -1,5 +1,5 @@
package darknet
// #cgo CFLAGS: -I/usr/local/include -I/usr/local/cuda/include
// #cgo LDFLAGS: -L/usr/local/lib -ldarknet -lm
// #cgo LDFLAGS: -L./lib -ldark -lm
import "C"

View File

@@ -1,19 +0,0 @@
#include <darknet.h>
detection * get_detection(detection *dets, int index, int dets_len)
{
if (index >= dets_len) {
return NULL;
}
return dets + index;
}
float get_detection_probability(detection *det, int index, int prob_len)
{
if (index >= prob_len) {
return .0;
}
return det->prob[index];
}

View File

@@ -1,84 +0,0 @@
package darknet
// #include <darknet.h>
//
// #include "detection.h"
import "C"
import (
"image"
"time"
)
// Detection represents a detection.
type Detection struct {
BoundingBox
ClassIDs []int
ClassNames []string
Probabilities []float32
}
// DetectionResult represents the inference results from the network.
type DetectionResult struct {
Detections []*Detection
NetworkOnlyTimeTaken time.Duration
OverallTimeTaken time.Duration
}
func makeDetection(img *Image, det *C.detection, threshold float32, classes int,
classNames []string) *Detection {
if det == nil {
return &Detection{}
}
dClassIDs := make([]int, 0)
dClassNames := make([]string, 0)
dProbs := make([]float32, 0)
for i := 0; i < int(classes); i++ {
dProb := float32(
C.get_detection_probability(det, C.int(i), C.int(classes)))
if dProb > threshold {
dClassIDs = append(dClassIDs, i)
cN := classNames[i]
dClassNames = append(dClassNames, cN)
dProbs = append(dProbs, dProb*100)
}
}
fImgW := C.float(img.Width)
fImgH := C.float(img.Height)
halfRatioW := det.bbox.w / 2.0
halfRatioH := det.bbox.h / 2.0
out := Detection{
BoundingBox: BoundingBox{
StartPoint: image.Point{
X: int((det.bbox.x - halfRatioW) * fImgW),
Y: int((det.bbox.y - halfRatioH) * fImgH),
},
EndPoint: image.Point{
X: int((det.bbox.x + halfRatioW) * fImgW),
Y: int((det.bbox.y + halfRatioH) * fImgH),
},
},
ClassIDs: dClassIDs,
ClassNames: dClassNames,
Probabilities: dProbs,
}
return &out
}
func makeDetections(img *Image, detections *C.detection, detectionsLength int,
threshold float32, classes int, classNames []string) []*Detection {
// Make list of detection objects.
ds := make([]*Detection, detectionsLength)
for i := 0; i < int(detectionsLength); i++ {
det := C.get_detection(detections, C.int(i), C.int(classes))
d := makeDetection(img, det, threshold, classes, classNames)
ds[i] = d
}
return ds
}

View File

@@ -1,6 +0,0 @@
#pragma once
#include <darknet.h>
extern detection * get_detection(detection *dets, int index, int dets_len);
extern float get_detection_probability(detection *det, int index, int prob_len);

View File

@@ -2,8 +2,9 @@ package main
import (
"flag"
"fmt"
"image/jpeg"
"log"
"os"
darknet "github.com/LdDl/go-darknet"
)
@@ -44,31 +45,41 @@ func main() {
}
defer n.Close()
img, err := darknet.ImageFromPath(*imageFile)
infile, err := os.Open(*imageFile)
if err != nil {
printError(err)
return
panic(err.Error())
}
defer img.Close()
dr, err := n.Detect(img)
defer infile.Close()
src, err := jpeg.Decode(infile)
if err != nil {
printError(err)
return
panic(err.Error())
}
log.Println("Network-only time taken:", dr.NetworkOnlyTimeTaken)
log.Println("Overall time taken:", dr.OverallTimeTaken, len(dr.Detections))
for _, d := range dr.Detections {
for i := range d.ClassIDs {
bBox := d.BoundingBox
fmt.Printf("%s (%d): %.4f%% | start point: (%d,%d) | end point: (%d, %d)\n",
d.ClassNames[i], d.ClassIDs[i],
d.Probabilities[i],
bBox.StartPoint.X, bBox.StartPoint.Y,
bBox.EndPoint.X, bBox.EndPoint.Y,
)
}
imgFalot32, err := darknet.Image2Float32(src)
if err != nil {
panic(err.Error())
}
_ = imgFalot32
// defer img.Close()
// dr, err := n.Detect(img)
// if err != nil {
// printError(err)
// return
// }
// log.Println("Network-only time taken:", dr.NetworkOnlyTimeTaken)
// log.Println("Overall time taken:", dr.OverallTimeTaken, len(dr.Detections))
// for _, d := range dr.Detections {
// for i := range d.ClassIDs {
// bBox := d.BoundingBox
// fmt.Printf("%s (%d): %.4f%% | start point: (%d,%d) | end point: (%d, %d)\n",
// d.ClassNames[i], d.ClassIDs[i],
// d.Probabilities[i],
// bBox.StartPoint.X, bBox.StartPoint.Y,
// bBox.EndPoint.X, bBox.EndPoint.Y,
// )
// }
// }
}

17
image.c Normal file
View File

@@ -0,0 +1,17 @@
#include <darknet.h>
image new_darknet_image() {
image img;
img.w = 0;
img.h = 0;
img.c = 0;
img.data = NULL;
return img;
}
image prepare_image(image img, int w, int h, int c){
img.w=w;
img.h=h;
img.c=c;
return img;
}

View File

@@ -1,66 +1,40 @@
package darknet
// #include <darknet.h>
import "C"
import (
"errors"
"C"
"image"
"unsafe"
)
// Image represents the image buffer.
type Image struct {
Width int
Height int
// DarknetImage represents the image buffer.
// type DarknetImage struct {
// Width int
// Height int
// image C.image
// }
image C.image
func float_p(arr []float32) *C.float {
return (*C.float)(unsafe.Pointer(&arr[0]))
}
var (
errUnableToLoadImage = errors.New("unable to load image")
)
// Image2Float32 Returns []float32 representation of image.Image
func Image2Float32(img image.Image) ([]float32, error) {
width := img.Bounds().Dx()
height := img.Bounds().Dy()
imgwh := width * height
imgSize := imgwh * 3
// Close and release resources.
func (img *Image) Close() error {
C.free_image(img.image)
return nil
}
// 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(p, 0, 0),
}
if img.image.data == nil {
return nil, errUnableToLoadImage
}
img.Width = int(img.image.w)
img.Height = int(img.image.h)
return &img, nil
}
// ImageFromMemory reads image file data represented by the specified byte
// slice.
func ImageFromMemory(buf []byte) (*Image, error) {
cBuf := C.CBytes(buf)
defer C.free(cBuf)
img := Image{
image: C.load_image_from_memory_color((*C.uchar)(cBuf),
C.int(len(buf)), 0, 0),
}
if img.image.data == nil {
return nil, errUnableToLoadImage
}
img.Width = int(img.image.w)
img.Height = int(img.image.h)
return &img, nil
ans := make([]float32, imgSize)
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
r, g, b, _ := img.At(y, x).RGBA()
rpix, gpix, bpix := float32(r>>8)/float32(255.0), float32(g>>8)/float32(255.0), float32(b>>8)/float32(255.0)
ans[y+x*height] = rpix
ans[y+x*height+imgwh] = gpix
ans[y+x*height+imgwh+imgwh] = bpix
}
}
return ans, nil
}

6
image.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include <darknet.h>
extern image new_darknet_image();
extern image prepare_image(image img, int w, int h, int c);

BIN
main Executable file

Binary file not shown.

View File

@@ -1,22 +1,22 @@
#include <stdlib.h>
// #include <stdlib.h>
#include <darknet.h>
// #include <darknet.h>
#include "network.h"
// #include "network.h"
int get_network_layer_classes(network *n, int index) {
return n->layers[index].classes;
}
// int get_network_layer_classes(network *n, int index) {
// return n->layers[index].classes;
// }
struct network_box_result perform_network_detect(network *n, image *img, int classes, float thresh, float hier_thresh, float nms) {
image sized = letterbox_image(*img, n->w, n->h);
struct network_box_result result = { NULL };
float *X = sized.data;
network_predict(n, X);
result.detections = get_network_boxes(n, img->w, img->h,thresh, hier_thresh, 0, 1, &result.detections_len);
if (nms) {
do_nms_sort(result.detections, result.detections_len, classes, nms);
}
free_image(sized);
return result;
}
// struct network_box_result perform_network_detect(network *n, image *img, int classes, float thresh, float hier_thresh, float nms) {
// image sized = letterbox_image(*img, n->w, n->h);
// struct network_box_result result = { NULL };
// float *X = sized.data;
// network_predict(n, X);
// result.detections = get_network_boxes(n, img->w, img->h,thresh, hier_thresh, 0, 1, &result.detections_len);
// if (nms) {
// do_nms_sort(result.detections, result.detections_len, classes, nms);
// }
// free_image(sized);
// return result;
// }

View File

@@ -8,7 +8,6 @@ package darknet
import "C"
import (
"errors"
"time"
"unsafe"
)
@@ -35,6 +34,7 @@ var (
// Init the network.
func (n *YOLONetwork) Init() error {
nCfg := C.CString(n.NetworkConfigurationFile)
defer C.free(unsafe.Pointer(nCfg))
wFile := C.CString(n.WeightsFile)
@@ -48,7 +48,7 @@ func (n *YOLONetwork) Init() error {
return errUnableToInitNetwork
}
C.set_batch_network(n.cNet, 1)
// C.set_batch_network(n.cNet, 1)
C.srand(2222222)
// Currently, hierarchal threshold is always 0.5.
@@ -57,10 +57,10 @@ func (n *YOLONetwork) Init() error {
// Currently NMS is always 0.4.
n.nms = .4
n.Classes = int(C.get_network_layer_classes(n.cNet, n.cNet.n-1))
cClassNames := loadClassNames(n.DataConfigurationFile)
defer freeClassNames(cClassNames)
n.ClassNames = makeClassNames(cClassNames, n.Classes)
// n.Classes = int(C.get_network_layer_classes(n.cNet, n.cNet.n-1))
// cClassNames := loadClassNames(n.DataConfigurationFile)
// defer freeClassNames(cClassNames)
// n.ClassNames = makeClassNames(cClassNames, n.Classes)
return nil
}
@@ -71,33 +71,33 @@ func (n *YOLONetwork) Close() error {
return errNetworkNotInit
}
C.free_network(n.cNet)
C.free_network(*n.cNet)
n.cNet = nil
return nil
}
// Detect specified image.
func (n *YOLONetwork) Detect(img *Image) (*DetectionResult, error) {
if n.cNet == nil {
return nil, errNetworkNotInit
}
// func (n *YOLONetwork) Detect(img *Image) (*DetectionResult, error) {
// if n.cNet == nil {
// return nil, errNetworkNotInit
// }
startTime := time.Now()
result := C.perform_network_detect(n.cNet, &img.image, C.int(n.Classes),
C.float(n.Threshold), C.float(n.hierarchalThreshold), C.float(n.nms))
endTime := time.Now()
defer C.free_detections(result.detections, result.detections_len)
// startTime := time.Now()
// result := C.perform_network_detect(n.cNet, &img.image, C.int(n.Classes),
// C.float(n.Threshold), C.float(n.hierarchalThreshold), C.float(n.nms))
// endTime := time.Now()
// defer C.free_detections(result.detections, result.detections_len)
ds := makeDetections(img, result.detections, int(result.detections_len),
n.Threshold, n.Classes, n.ClassNames)
// ds := makeDetections(img, result.detections, int(result.detections_len),
// n.Threshold, n.Classes, n.ClassNames)
endTimeOverall := time.Now()
// endTimeOverall := time.Now()
out := DetectionResult{
Detections: ds,
NetworkOnlyTimeTaken: endTime.Sub(startTime),
OverallTimeTaken: endTimeOverall.Sub(startTime),
}
// out := DetectionResult{
// Detections: ds,
// NetworkOnlyTimeTaken: endTime.Sub(startTime),
// OverallTimeTaken: endTimeOverall.Sub(startTime),
// }
return &out, nil
}
// return &out, nil
// }