16 Commits
v1.0 ... v1.1.0

Author SHA1 Message Date
Dimitrii Lopanov
420a74769d Merge pull request #7 from LdDl/mleak
Closes #6
2020-05-15 16:07:41 +03:00
Dimitrii
527e2942e9 clean up 2020-05-15 16:05:02 +03:00
Dimitrii
8105b8f1ae chechk latest alexeyab fork + yolov4 upd 2020-05-07 13:02:31 +03:00
Dimitrii
c625572f8c Merge branch 'master' of github.com:LdDl/go-darknet 2020-05-05 20:30:36 +03:00
Dimitrii
a58fecd863 clear newrgba memory and slice leaks 2020-05-05 20:30:25 +03:00
Dimitrii Lopanov
435d3f662c Merge pull request #5 from x0rzkov/docker
add docker container for cpu/gpu

Thanks a lot.
2020-04-10 15:43:03 +03:00
lucmichalski
d9682ca0f6 fix libcuda.so.1 missing 2020-04-10 04:58:21 +00:00
lucmichalski
4b38088916 fix commit, add golang to dockerfile.gpu 2020-04-08 08:16:20 +00:00
lucmichalski
766ff56e2e fix dockerfile.gpu 2020-04-08 08:02:03 +00:00
lucmichalski
3166cdca78 add docker container for cpu/gpu 2020-04-08 07:52:55 +00:00
Dimitrii Lopanov
02ab33b804 Merge pull request #3 from LdDl/new_example
Example of saving detected objects
2020-04-08 09:43:39 +03:00
Dimitrii Lopanov
0fd261e605 upd 2020-04-08 09:41:32 +03:00
Dimitrii
4c39be01f9 ptr causes segfault 2020-03-24 11:50:07 +03:00
Dimitrii
2dd85a84d6 rdm 2020-02-26 08:41:26 +03:00
Dimitrii
3a10d5a657 Merge branch 'master' of github.com:LdDl/go-darknet 2020-02-26 08:40:40 +03:00
Dimitrii
95332e0877 upd readmes 2020-02-26 08:34:03 +03:00
17 changed files with 680 additions and 55 deletions

2
.gitignore vendored
View File

@@ -3,6 +3,8 @@ example/sample.jpg
example/coco.names
example/yolov3.cfg
example/yolov3.weights
example/yolov4.cfg
example/yolov4.weights
darknet.h
*.so
predictions.png

View File

@@ -1,10 +1,13 @@
# go-darknet: Go bindings for Darknet
### This is fork of go-darknet https://github.com/gyonluks/go-darknet applied to FORK of Darknet https://github.com/AlexeyAB/darknet
[![GoDoc](https://godoc.org/github.com/LdDl/go-darknet?status.svg)](https://godoc.org/github.com/LdDl/go-darknet)
go-darknet is a Go package, which uses Cgo to enable Go applications to use YOLO in [Darknet].
# go-darknet: Go bindings for Darknet (Yolo V4, Yolo V3)
### go-darknet is a Go package, which uses Cgo to enable Go applications to use YOLO V4/V3 in [Darknet].
#### Since this repository https://github.com/gyonluks/go-darknet is no longer maintained I decided to move on and make little different bindings for Darknet.
#### This bindings aren't for [official implementation](https://github.com/pjreddie/darknet) but for [AlexeyAB's fork](https://github.com/AlexeyAB/darknet).
#### Paper Yolo v4: https://arxiv.org/abs/2004.10934
#### Paper Yolo v3: https://arxiv.org/abs/1804.02767
## Table of Contents
@@ -16,7 +19,7 @@ go-darknet is a Go package, which uses Cgo to enable Go applications to use YOLO
## Requirements
For proper codebase please use fork of [darknet](https://github.com/AlexeyAB/darknet). Latest commit I've tested [here](https://github.com/AlexeyAB/darknet/commit/64fb042c63637038671ae9d53c06165599b28912)
For proper codebase please use fork of [darknet](https://github.com/AlexeyAB/darknet). Latest commit I've tested [here](https://github.com/AlexeyAB/darknet/commit/08bc0c9373158da6c42f11b1359ca2c017cef1b5)
In order to use go-darknet, `libdarknet.so` should be available in one of
the following locations:
@@ -54,27 +57,62 @@ Navigate to [example] folder
cd $GOPATH/github.com/LdDl/go-darknet/example
```
Download dataset (sample of image, coco.names, yolov3.cfg, yolov3.weights).
Download dataset (sample of image, coco.names, yolov4.cfg (or v3), yolov4.weights(or v3)).
```shell
#for yolo v4
./download_data.sh
#for yolo v3
./download_data_v3.sh
```
Note: you don't need *coco.data* file anymore, because sh-script above does insert *coco.names* into 'names' filed in *yolov3.cfg* file (so AlexeyAB's fork can deal with it properly)
So last rows in yolov3.cfg file will look like:
Note: you don't need *coco.data* file anymore, because sh-script above does insert *coco.names* into 'names' filed in *yolov4.cfg* file (so AlexeyAB's fork can deal with it properly)
So last rows in yolov4.cfg file will look like:
```bash
......
[yolo]
mask = 0,1,2
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=80
num=9
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
.....
iou_loss=ciou
nms_kind=greedynms
beta_nms=0.6
names = coco.names # this is path to coco.names file
```
Also do not forget change batch and subdivisions sizes from:
```shell
batch=64
subdivisions=8
```
to
```shell
batch=1
subdivisions=1
```
It will reduce amount of VRAM used for detector test.
Build and run program
Yolo V4:
```shell
go build main.go && ./main --configFile=yolov4.cfg --weightsFile=yolov4.weights --imageFile=sample.jpg
```
Output should be something like this:
```shell
traffic light (9): 73.5039% | start point: (238,73) | end point: (251, 106)
truck (7): 96.6401% | start point: (95,79) | end point: (233, 287)
truck (7): 96.4774% | start point: (662,158) | end point: (800, 321)
truck (7): 96.1841% | start point: (0,77) | end point: (86, 333)
truck (7): 46.8695% | start point: (434,173) | end point: (559, 216)
car (2): 99.7370% | start point: (512,188) | end point: (741, 329)
car (2): 99.2533% | start point: (260,191) | end point: (422, 322)
car (2): 99.0333% | start point: (425,201) | end point: (547, 309)
car (2): 83.3919% | start point: (386,210) | end point: (437, 287)
car (2): 75.8621% | start point: (73,199) | end point: (102, 274)
car (2): 39.1925% | start point: (386,206) | end point: (442, 240)
bicycle (1): 76.3121% | start point: (189,298) | end point: (253, 402)
person (0): 97.7213% | start point: (141,129) | end point: (283, 362)
```
Yolo V3:
```
go build main.go && ./main --configFile=yolov3.cfg --weightsFile=yolov3.weights --imageFile=sample.jpg
```
@@ -95,6 +133,7 @@ car (2): 72.8053% | start point: (388,206) | end point: (437, 276)
bicycle (1): 72.2932% | start point: (178,270) | end point: (268, 406)
person (0): 97.3026% | start point: (143,135) | end point: (268, 343)
```
## Documentation
See go-darknet's API documentation at [GoDoc].

1
docker/.env Normal file
View File

@@ -0,0 +1 @@
NAMESPACE=darknet

40
docker/Dockerfile Normal file
View File

@@ -0,0 +1,40 @@
# Build phase
FROM ubuntu:18.04 as builder
ENV darknet_commit=a234a5022333c930de08f2470184ef4e0c68356e
WORKDIR /root/build
COPY Makefile.cpu .
RUN apt-get -y update && \
apt-get -y install --no-install-recommends git build-essential ca-certificates && \
git clone https://github.com/AlexeyAB/darknet && \
cd darknet && \
git checkout $darknet_commit && \
cp -f /root/build/Makefile.cpu Makefile && \
make
# Final Image
FROM golang:1.14
RUN apt-get -y update && \
apt-get -y install --no-install-recommends nano bash jq
WORKDIR /root
COPY --from=builder /root/build/darknet/darknet \
/root/build/darknet/libdarknet.so \
/root/build/darknet/include/darknet.h \
./staging/
RUN mv staging/darknet /usr/local/bin && \
mv staging/darknet.h /usr/include && \
mv staging/libdarknet.so /usr/lib && \
rm -rf staging
RUN go get -u github.com/LdDl/go-darknet \
&& go get -u github.com/disintegration/imaging
WORKDIR /darknet
COPY download_data.sh .
CMD ["/bin/bash"]

52
docker/Dockerfile.gpu Normal file
View File

@@ -0,0 +1,52 @@
# Build phase
FROM nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04 as builder
ENV darknet_commit=a234a5022333c930de08f2470184ef4e0c68356e
WORKDIR /root/build
COPY Makefile.gpu .
RUN apt-get -y update && \
apt-get -y install git build-essential && \
git clone https://github.com/AlexeyAB/darknet.git && \
cd darknet && \
git checkout $darknet_commit && \
cp -f /root/build/Makefile.gpu Makefile && \
make
# Final Image
FROM nvidia/cuda:10.0-cudnn7-runtime-ubuntu18.04
WORKDIR /root
COPY --from=builder /root/build/darknet/darknet \
/root/build/darknet/libdarknet.so \
/root/build/darknet/include/darknet.h \
./staging/
RUN mv staging/darknet /usr/local/bin && \
mv staging/darknet.h /usr/include && \
mv staging/libdarknet.so /usr/lib && \
rm -rf staging
WORKDIR /tmp
RUN cd /tmp \
&& apt-get -y update \
&& apt-get install -y wget git gcc \
&& wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz \
&& tar -xvf go1.14.linux-amd64.tar.gz \
&& mv go /usr/local
RUN cp /usr/local/cuda-10.0/compat/* /usr/local/cuda-10.0/targets/x86_64-linux/lib/
ENV GOROOT=/usr/local/go
ENV GOPATH=/go
ENV PATH=$GOPATH/bin:$GOROOT/bin:$PATH
ENV LIBRARY_PATH=$LIBRARY_PATH:/usr/local/cuda-10.0/compat/
RUN go get -u github.com/LdDl/go-darknet \
&& go get -u github.com/disintegration/imaging
WORKDIR /darknet
COPY download_data.sh .
CMD ["/bin/bash"]

185
docker/Makefile.cpu Normal file
View File

@@ -0,0 +1,185 @@
GPU=0
CUDNN=0
CUDNN_HALF=0
OPENCV=0
AVX=1
OPENMP=1
LIBSO=1
ZED_CAMERA=0 # ZED SDK 3.0 and above
ZED_CAMERA_v2_8=0 # ZED SDK 2.X
# set GPU=1 and CUDNN=1 to speedup on GPU
# set CUDNN_HALF=1 to further speedup 3 x times (Mixed-precision on Tensor Cores) GPU: Volta, Xavier, Turing and higher
# set AVX=1 and OPENMP=1 to speedup on CPU (if error occurs then set AVX=0)
USE_CPP=0
DEBUG=0
ARCH= -gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=[sm_50,compute_50] \
-gencode arch=compute_52,code=[sm_52,compute_52] \
-gencode arch=compute_61,code=[sm_61,compute_61]
OS := $(shell uname)
# Tesla V100
# ARCH= -gencode arch=compute_70,code=[sm_70,compute_70]
# GeForce RTX 2080 Ti, RTX 2080, RTX 2070, Quadro RTX 8000, Quadro RTX 6000, Quadro RTX 5000, Tesla T4, XNOR Tensor Cores
# ARCH= -gencode arch=compute_75,code=[sm_75,compute_75]
# Jetson XAVIER
# ARCH= -gencode arch=compute_72,code=[sm_72,compute_72]
# GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4
# ARCH= -gencode arch=compute_61,code=sm_61 -gencode arch=compute_61,code=compute_61
# GP100/Tesla P100 - DGX-1
# ARCH= -gencode arch=compute_60,code=sm_60
# For Jetson TX1, Tegra X1, DRIVE CX, DRIVE PX - uncomment:
# ARCH= -gencode arch=compute_53,code=[sm_53,compute_53]
# For Jetson Tx2 or Drive-PX2 uncomment:
# ARCH= -gencode arch=compute_62,code=[sm_62,compute_62]
# VPATH=./src/
VPATH=./src/:./examples
SLIB=libdarknet.so
EXEC=darknet
OBJDIR=./obj/
ifeq ($(LIBSO), 1)
LIBNAMESO=libdarknet.so
APPNAMESO=uselib
endif
ifeq ($(USE_CPP), 1)
CC=g++
else
CC=gcc
endif
CPP=g++ -std=c++11
NVCC=nvcc
OPTS=-Ofast
LDFLAGS= -lm -pthread
COMMON= -Iinclude/ -I3rdparty/stb/include
CFLAGS=-Wall -Wfatal-errors -Wno-unused-result -Wno-unknown-pragmas -fPIC
ifeq ($(DEBUG), 1)
#OPTS= -O0 -g
#OPTS= -Og -g
COMMON+= -DDEBUG
CFLAGS+= -DDEBUG
else
ifeq ($(AVX), 1)
CFLAGS+= -ffp-contract=fast -mavx -mavx2 -msse3 -msse4.1 -msse4.2 -msse4a
endif
endif
CFLAGS+=$(OPTS)
ifneq (,$(findstring MSYS_NT,$(OS)))
LDFLAGS+=-lws2_32
endif
ifeq ($(OPENCV), 1)
COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv4 2> /dev/null || pkg-config --libs opencv`
COMMON+= `pkg-config --cflags opencv4 2> /dev/null || pkg-config --cflags opencv`
endif
ifeq ($(OPENMP), 1)
CFLAGS+= -fopenmp
LDFLAGS+= -lgomp
endif
ifeq ($(GPU), 1)
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
ifeq ($(OS),Darwin) #MAC
LDFLAGS+= -L/usr/local/cuda/lib -lcuda -lcudart -lcublas -lcurand
else
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif
endif
ifeq ($(CUDNN), 1)
COMMON+= -DCUDNN
ifeq ($(OS),Darwin) #MAC
CFLAGS+= -DCUDNN -I/usr/local/cuda/include
LDFLAGS+= -L/usr/local/cuda/lib -lcudnn
else
CFLAGS+= -DCUDNN -I/usr/local/cudnn/include
LDFLAGS+= -L/usr/local/cudnn/lib64 -lcudnn
endif
endif
ifeq ($(CUDNN_HALF), 1)
COMMON+= -DCUDNN_HALF
CFLAGS+= -DCUDNN_HALF
ARCH+= -gencode arch=compute_70,code=[sm_70,compute_70]
endif
ifeq ($(ZED_CAMERA), 1)
CFLAGS+= -DZED_STEREO -I/usr/local/zed/include
ifeq ($(ZED_CAMERA_v2_8), 1)
LDFLAGS+= -L/usr/local/zed/lib -lsl_core -lsl_input -lsl_zed
#-lstdc++ -D_GLIBCXX_USE_CXX11_ABI=0
else
LDFLAGS+= -L/usr/local/zed/lib -lsl_zed
#-lstdc++ -D_GLIBCXX_USE_CXX11_ABI=0
endif
endif
OBJ=image_opencv.o http_stream.o gemm.o utils.o dark_cuda.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o darknet.o detection_layer.o captcha.o route_layer.o writing.o box.o nightmare.o normalization_layer.o avgpool_layer.o coco.o dice.o yolo.o detector.o layer.o compare.o classifier.o local_layer.o swag.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o rnn.o rnn_vid.o crnn_layer.o demo.o tag.o cifar.o go.o batchnorm_layer.o art.o region_layer.o reorg_layer.o reorg_old_layer.o super.o voxel.o tree.o yolo_layer.o gaussian_yolo_layer.o upsample_layer.o lstm_layer.o conv_lstm_layer.o scale_channels_layer.o sam_layer.o
ifeq ($(GPU), 1)
LDFLAGS+= -lstdc++
OBJ+=convolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o network_kernels.o avgpool_layer_kernels.o
endif
OBJS = $(addprefix $(OBJDIR), $(OBJ))
DEPS = $(wildcard src/*.h) Makefile include/darknet.h
all: $(OBJDIR) backup results setchmod $(EXEC) $(LIBNAMESO) $(APPNAMESO)
ifeq ($(LIBSO), 1)
CFLAGS+= -fPIC
$(LIBNAMESO): $(OBJDIR) $(OBJS) include/yolo_v2_class.hpp src/yolo_v2_class.cpp
$(CPP) -shared -std=c++11 -fvisibility=hidden -DLIB_EXPORTS $(COMMON) $(CFLAGS) $(OBJS) src/yolo_v2_class.cpp -o $@ $(LDFLAGS)
$(APPNAMESO): $(LIBNAMESO) include/yolo_v2_class.hpp src/yolo_console_dll.cpp
$(CPP) -std=c++11 $(COMMON) $(CFLAGS) -o $@ src/yolo_console_dll.cpp $(LDFLAGS) -L ./ -l:$(LIBNAMESO)
endif
$(EXEC): $(OBJS)
$(CPP) -std=c++11 $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS)
$(OBJDIR)%.o: %.c $(DEPS)
$(CC) $(COMMON) $(CFLAGS) -c $< -o $@
$(OBJDIR)%.o: %.cpp $(DEPS)
$(CPP) -std=c++11 $(COMMON) $(CFLAGS) -c $< -o $@
$(OBJDIR)%.o: %.cu $(DEPS)
$(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@
$(OBJDIR):
mkdir -p $(OBJDIR)
backup:
mkdir -p backup
results:
mkdir -p results
setchmod:
chmod +x *.sh
.PHONY: clean
clean:
rm -rf $(OBJS) $(EXEC) $(LIBNAMESO) $(APPNAMESO)

186
docker/Makefile.gpu Normal file
View File

@@ -0,0 +1,186 @@
GPU=1
CUDNN=1
CUDNN_HALF=0
OPENCV=0
AVX=0
OPENMP=0
LIBSO=1
ZED_CAMERA=0 # ZED SDK 3.0 and above
ZED_CAMERA_v2_8=0 # ZED SDK 2.X
# set GPU=1 and CUDNN=1 to speedup on GPU
# set CUDNN_HALF=1 to further speedup 3 x times (Mixed-precision on Tensor Cores) GPU: Volta, Xavier, Turing and higher
# set AVX=1 and OPENMP=1 to speedup on CPU (if error occurs then set AVX=0)
USE_CPP=0
DEBUG=0
ARCH= -gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=[sm_50,compute_50] \
-gencode arch=compute_52,code=[sm_52,compute_52] \
-gencode arch=compute_61,code=[sm_61,compute_61]
OS := $(shell uname)
# Tesla V100
# ARCH= -gencode arch=compute_70,code=[sm_70,compute_70]
# GeForce RTX 2080 Ti, RTX 2080, RTX 2070, Quadro RTX 8000, Quadro RTX 6000, Quadro RTX 5000, Tesla T4, XNOR Tensor Cores
# ARCH= -gencode arch=compute_75,code=[sm_75,compute_75]
# Jetson XAVIER
# ARCH= -gencode arch=compute_72,code=[sm_72,compute_72]
# GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4
# ARCH= -gencode arch=compute_61,code=sm_61 -gencode arch=compute_61,code=compute_61
# GP100/Tesla P100 - DGX-1
# ARCH= -gencode arch=compute_60,code=sm_60
# For Jetson TX1, Tegra X1, DRIVE CX, DRIVE PX - uncomment:
# ARCH= -gencode arch=compute_53,code=[sm_53,compute_53]
# For Jetson Tx2 or Drive-PX2 uncomment:
# ARCH= -gencode arch=compute_62,code=[sm_62,compute_62]
# VPATH=./src/
VPATH=./src/:./examples
SLIB=libdarknet.so
EXEC=darknet
OBJDIR=./obj/
ifeq ($(LIBSO), 1)
LIBNAMESO=libdarknet.so
APPNAMESO=uselib
endif
ifeq ($(USE_CPP), 1)
CC=g++
else
CC=gcc
endif
CPP=g++ -std=c++11
NVCC=nvcc
OPTS=-Ofast
LDFLAGS= -lm -pthread
COMMON= -Iinclude/ -I3rdparty/stb/include
CFLAGS=-Wall -Wfatal-errors -Wno-unused-result -Wno-unknown-pragmas -fPIC
ifeq ($(DEBUG), 1)
#OPTS= -O0 -g
#OPTS= -Og -g
COMMON+= -DDEBUG
CFLAGS+= -DDEBUG
else
ifeq ($(AVX), 1)
CFLAGS+= -ffp-contract=fast -mavx -mavx2 -msse3 -msse4.1 -msse4.2 -msse4a
endif
endif
CFLAGS+=$(OPTS)
ifneq (,$(findstring MSYS_NT,$(OS)))
LDFLAGS+=-lws2_32
endif
ifeq ($(OPENCV), 1)
COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv4 2> /dev/null || pkg-config --libs opencv`
COMMON+= `pkg-config --cflags opencv4 2> /dev/null || pkg-config --cflags opencv`
endif
ifeq ($(OPENMP), 1)
CFLAGS+= -fopenmp
LDFLAGS+= -lgomp
endif
ifeq ($(GPU), 1)
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
ifeq ($(OS),Darwin) #MAC
LDFLAGS+= -L/usr/local/cuda/lib -lcuda -lcudart -lcublas -lcurand
else
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif
endif
ifeq ($(CUDNN), 1)
COMMON+= -DCUDNN
ifeq ($(OS),Darwin) #MAC
CFLAGS+= -DCUDNN -I/usr/local/cuda/include
LDFLAGS+= -L/usr/local/cuda/lib -lcudnn
else
CFLAGS+= -DCUDNN -I/usr/local/cudnn/include
LDFLAGS+= -L/usr/local/cudnn/lib64 -lcudnn
endif
endif
ifeq ($(CUDNN_HALF), 1)
COMMON+= -DCUDNN_HALF
CFLAGS+= -DCUDNN_HALF
ARCH+= -gencode arch=compute_70,code=[sm_70,compute_70]
endif
ifeq ($(ZED_CAMERA), 1)
CFLAGS+= -DZED_STEREO -I/usr/local/zed/include
ifeq ($(ZED_CAMERA_v2_8), 1)
LDFLAGS+= -L/usr/local/zed/lib -lsl_core -lsl_input -lsl_zed
#-lstdc++ -D_GLIBCXX_USE_CXX11_ABI=0
else
LDFLAGS+= -L/usr/local/zed/lib -lsl_zed
#-lstdc++ -D_GLIBCXX_USE_CXX11_ABI=0
endif
endif
OBJ=image_opencv.o http_stream.o gemm.o utils.o dark_cuda.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o darknet.o detection_layer.o captcha.o route_layer.o writing.o box.o nightmare.o normalization_layer.o avgpool_layer.o coco.o dice.o yolo.o detector.o layer.o compare.o classifier.o local_layer.o swag.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o rnn.o rnn_vid.o crnn_layer.o demo.o tag.o cifar.o go.o batchnorm_layer.o art.o region_layer.o reorg_layer.o reorg_old_layer.o super.o voxel.o tree.o yolo_layer.o gaussian_yolo_layer.o upsample_layer.o lstm_layer.o conv_lstm_layer.o scale_channels_layer.o sam_layer.o
ifeq ($(GPU), 1)
LDFLAGS+= -lstdc++
OBJ+=convolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o network_kernels.o avgpool_layer_kernels.o
endif
OBJS = $(addprefix $(OBJDIR), $(OBJ))
DEPS = $(wildcard src/*.h) Makefile include/darknet.h
all: $(OBJDIR) backup results setchmod $(EXEC) $(LIBNAMESO) $(APPNAMESO)
ifeq ($(LIBSO), 1)
CFLAGS+= -fPIC
$(LIBNAMESO): $(OBJDIR) $(OBJS) include/yolo_v2_class.hpp src/yolo_v2_class.cpp
$(CPP) -shared -std=c++11 -fvisibility=hidden -DLIB_EXPORTS $(COMMON) $(CFLAGS) $(OBJS) src/yolo_v2_class.cpp -o $@ $(LDFLAGS)
$(APPNAMESO): $(LIBNAMESO) include/yolo_v2_class.hpp src/yolo_console_dll.cpp
$(CPP) -std=c++11 $(COMMON) $(CFLAGS) -o $@ src/yolo_console_dll.cpp $(LDFLAGS) -L ./ -l:$(LIBNAMESO)
endif
$(EXEC): $(OBJS)
$(CPP) -std=c++11 $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS)
$(OBJDIR)%.o: %.c $(DEPS)
$(CC) $(COMMON) $(CFLAGS) -c $< -o $@
$(OBJDIR)%.o: %.cpp $(DEPS)
$(CPP) -std=c++11 $(COMMON) $(CFLAGS) -c $< -o $@
$(OBJDIR)%.o: %.cu $(DEPS)
$(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@
$(OBJDIR):
mkdir -p $(OBJDIR)
backup:
mkdir -p backup
results:
mkdir -p results
setchmod:
chmod +x *.sh
.PHONY: clean
clean:
rm -rf $(OBJS) $(EXEC) $(LIBNAMESO) $(APPNAMESO)

32
docker/docker-compose.yml Normal file
View File

@@ -0,0 +1,32 @@
---
version: '3.7'
services:
sidekiq: &darknet_base
container_name: ${NAMESPACE}-sidekiq
build:
context: .
dockerfile: Dockerfile
image: go-darknet:latest
working_dir: /darknet
volumes:
- darknet-data:/darknet/models
command: /darknet/download_data.sh
darknet:
<<: *darknet_base
container_name: ${NAMESPACE}-api
ports:
- "9003:9003"
restart: unless-stopped
depends_on:
- sidekiq
command: ["/bin/bash"]
# command: ["darknet-server"]
volumes:
darknet-data:
driver_opts:
type: none
o: bind
device: ${PWD}/models

10
docker/download_data.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/sh
# set -x
# set -e
wget -nc --output-document=sample.jpg https://cdn-images-1.medium.com/max/800/1*EYFejGUjvjPcc4PZTwoufw.jpeg
wget -nc --output-document=./models/coco.names https://raw.githubusercontent.com/AlexeyAB/darknet/master/data/coco.names
wget -nc --output-document=./models/yolov3.cfg https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3.cfg
sed -i -e "\$anames = coco.names" ./models/yolov3.cfg
wget -nc --output-document=./models/yolov3.weights https://pjreddie.com/media/files/yolov3.weights

2
docker/models/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -2,33 +2,53 @@
This is an example Go application which uses go-darknet.
## Install
```shell
go get github.com/LdDl/go-darknet
go install github.com/LdDl/go-darknet/example
# Alternatively
go build github.com/LdDl/go-darknet/example
```
An executable named `example` should be in your `$GOPATH/bin`, if using
`go install`; otherwise it will be in your current working directory (`$PWD`),
if using `go build`.
## Run
Navigate to example folder:
```shell
$GOPATH/bin/example
cd $GOPATH/github.com/LdDl/go-darknet/example
```
or
```go
go run main.go -configFile=yolov3-320.cfg -dataConfigFile=coco.data -imageFile=sample.jpg -weightsFile=yolov3.weights
Download dataset (sample of image, coco.names, yolov3.cfg, yolov3.weights).
```shell
./download_data.sh
```
Note: you don't need *coco.data* file anymore, because script below does insert *coco.names* into 'names' filed in *yolov3.cfg* file (so AlexeyAB's fork can deal with it properly)
So last rows in yolov3.cfg file will look like:
```bash
......
[yolo]
mask = 0,1,2
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=80
num=9
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
names = coco.names # this is path to coco.names file
```
Please ensure that `libdarknet.so` is in your `$LD_LIBRARY_PATH`.
## Notes
Build and run program
```
go build main.go && ./main --configFile=yolov3.cfg --weightsFile=yolov3.weights --imageFile=sample.jpg
```
Note that the bounding boxes' values are ratios. To get the actual values, use
the ratios and multiply with either the image's width or height, depending on
which ratio is used.
Output should be something like this:
```shell
truck (7): 49.5197% | start point: (0,136) | end point: (85, 311)
car (2): 36.3747% | start point: (95,152) | end point: (186, 283)
truck (7): 48.4384% | start point: (95,152) | end point: (186, 283)
truck (7): 45.6590% | start point: (694,178) | end point: (798, 310)
car (2): 76.8379% | start point: (1,145) | end point: (84, 324)
truck (7): 25.5731% | start point: (107,89) | end point: (215, 263)
car (2): 99.8783% | start point: (511,185) | end point: (748, 328)
car (2): 99.8194% | start point: (261,189) | end point: (427, 322)
car (2): 99.6408% | start point: (426,197) | end point: (539, 311)
car (2): 74.5610% | start point: (692,186) | end point: (796, 316)
car (2): 72.8053% | start point: (388,206) | end point: (437, 276)
bicycle (1): 72.2932% | start point: (178,270) | end point: (268, 406)
person (0): 97.3026% | start point: (143,135) | end point: (268, 343)
```

View File

@@ -1,5 +1,5 @@
wget --output-document=sample.jpg https://cdn-images-1.medium.com/max/800/1*EYFejGUjvjPcc4PZTwoufw.jpeg
wget --output-document=coco.names https://raw.githubusercontent.com/AlexeyAB/darknet/master/data/coco.names
wget --output-document=yolov3.cfg https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3.cfg
sed -i -e "\$anames = coco.names" yolov3.cfg
wget --output-document=yolov3.weights https://pjreddie.com/media/files/yolov3.weights
wget --output-document=yolov4.cfg https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov4.cfg
sed -i -e "\$anames = coco.names" yolov4.cfg
wget --output-document=yolov4.weights https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights

5
example/download_data_v3.sh Executable file
View File

@@ -0,0 +1,5 @@
wget --output-document=sample.jpg https://cdn-images-1.medium.com/max/800/1*EYFejGUjvjPcc4PZTwoufw.jpeg
wget --output-document=coco.names https://raw.githubusercontent.com/AlexeyAB/darknet/master/data/coco.names
wget --output-document=yolov3.cfg https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3.cfg
sed -i -e "\$anames = coco.names" yolov3.cfg
wget --output-document=yolov3.weights https://pjreddie.com/media/files/yolov3.weights

View File

@@ -7,9 +7,11 @@ import (
"image"
"image/jpeg"
"log"
"math"
"os"
darknet "github.com/LdDl/go-darknet"
"github.com/disintegration/imaging"
)
var configFile = flag.String("configFile", "",
@@ -78,6 +80,16 @@ func main() {
bBox.StartPoint.X, bBox.StartPoint.Y,
bBox.EndPoint.X, bBox.EndPoint.Y,
)
// Uncomment code below if you want save cropped objects to files
// minX, minY := float64(bBox.StartPoint.X), float64(bBox.StartPoint.Y)
// maxX, maxY := float64(bBox.EndPoint.X), float64(bBox.EndPoint.Y)
// rect := image.Rect(round(minX), round(minY), round(maxX), round(maxY))
// err := saveToFile(src, rect, fmt.Sprintf("crop_%d.jpeg", i))
// if err != nil {
// fmt.Println(err)
// return
// }
}
}
}
@@ -87,3 +99,24 @@ func imageToBytes(img image.Image) ([]byte, error) {
err := jpeg.Encode(buf, img, nil)
return buf.Bytes(), err
}
func round(v float64) int {
if v >= 0 {
return int(math.Floor(v + 0.5))
}
return int(math.Ceil(v - 0.5))
}
func saveToFile(imgSrc image.Image, bbox image.Rectangle, fname string) error {
rectcropimg := imaging.Crop(imgSrc, bbox)
f, err := os.Create(fname)
if err != nil {
return err
}
defer f.Close()
err = jpeg.Encode(f, rectcropimg, nil)
if err != nil {
return err
}
return nil
}

View File

@@ -14,12 +14,14 @@ import (
type DarknetImage struct {
Width int
Height int
ans []float32
image C.image
}
// Close and release resources.
func (img *DarknetImage) Close() error {
C.free_image(img.image)
img.ans = nil
return nil
}
@@ -29,10 +31,10 @@ func imgTofloat32(src image.Image) []float32 {
width, height := bounds.Max.X, bounds.Max.Y
srcRGBA := image.NewRGBA(src.Bounds())
draw.Copy(srcRGBA, image.Point{}, src, src.Bounds(), draw.Src, nil)
ans := []float32{}
red := []float32{}
green := []float32{}
blue := []float32{}
red := make([]float32, 0, width*height)
green := make([]float32, 0, width*height)
blue := make([]float32, 0, width*height)
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
idxSource := (y*width + x) * 4
@@ -43,22 +45,40 @@ func imgTofloat32(src image.Image) []float32 {
blue = append(blue, bpix)
}
}
ans = append(ans, red...)
ans = append(ans, green...)
ans = append(ans, blue...)
srcRGBA = nil
ans := make([]float32, len(red)+len(green)+len(blue))
copy(ans[:len(red)], red)
copy(ans[len(red):len(red)+len(green)], green)
copy(ans[len(red)+len(green):], blue)
red = nil
green = nil
blue = nil
return ans
}
// Image2Float32 Returns []float32 representation of image.Image
func Image2Float32(img image.Image) (*DarknetImage, error) {
ans := imgTofloat32(img)
// ans := imgTofloat32(img)
width := img.Bounds().Dx()
height := img.Bounds().Dy()
imgDarknet := &DarknetImage{
Width: width,
Height: height,
ans: imgTofloat32(img),
image: C.make_image(C.int(width), C.int(height), 3),
}
C.fill_image_f32(&imgDarknet.image, C.int(width), C.int(height), 3, (*C.float)(unsafe.Pointer(&ans[0])))
C.fill_image_f32(&imgDarknet.image, C.int(width), C.int(height), 3, (*C.float)(unsafe.Pointer(&imgDarknet.ans[0])))
return imgDarknet, nil
}
// Float32ToDarknetImage Converts []float32 to darknet image
func Float32ToDarknetImage(flatten []float32, width, height int) (*DarknetImage, error) {
imgDarknet := &DarknetImage{
Width: width,
Height: height,
image: C.make_image(C.int(width), C.int(height), 3),
}
C.fill_image_f32(&imgDarknet.image, C.int(width), C.int(height), 3, (*C.float)(unsafe.Pointer(&flatten[0])))
return imgDarknet, nil
}

View File

@@ -14,10 +14,8 @@ struct network_box_result perform_network_detect(network *n, image *img, int cla
sized = resize_image(*img, n->w, n->h);
}
struct network_box_result result = { NULL };
float *X = sized.data;
network_predict_ptr(n, X);
network_predict_ptr(n, sized.data);
int nboxes = 0;
detection *dets = get_network_boxes(n, img->w, img->h, thresh, hier_thresh, 0, 1, &nboxes, letter_box);
result.detections = get_network_boxes(n, img->w, img->h, thresh, hier_thresh, 0, 1, &result.detections_len, letter_box);
if (nms) {
do_nms_sort(result.detections, result.detections_len, classes, nms);

View File

@@ -71,8 +71,8 @@ func (n *YOLONetwork) Detect(img *DarknetImage) (*DetectionResult, error) {
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), C.int(0))
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)
C.free_detections(result.detections, result.detections_len)
endTimeOverall := time.Now()
out := DetectionResult{
Detections: ds,