33 Commits

Author SHA1 Message Date
Dimitrii
f5e648f099 portable version of mmap 2023-01-05 17:16:47 +03:00
Dimitrii
63dd49eee7 additional comment 2023-01-03 19:07:02 +03:00
Dimitrii
ae97f8ced4 testing temprorary cfg files 2023-01-03 18:47:03 +03:00
Dimitrii
549fd8d315 test sections just in case 2023-01-03 17:39:23 +03:00
Dimitrii
0880b53f27 docs 2022-07-13 16:23:18 +03:00
Dimitrii
1969bdad71 test yolov7-tiny 2022-07-13 16:15:23 +03:00
Dimitrii
36d89f7409 mod 2022-03-17 13:38:36 +03:00
Dimitrii Lopanov
51c7e39572 Merge pull request #25 from lian/master
DarknetImage move float conversion into c code
2022-03-05 13:05:19 +03:00
Julian Langschaedel
7e34b459e6 DarknetImage move float conversion into c code
imgTofloat32 + fill_image_f32 took more than double the time since tofloat created needless allocations and iterate over each pixel, and fill_image in c then iterate over each pixel*3 again just to move it into the c image.
2022-03-02 19:19:47 +01:00
Dimitrii
a18a9cf3e0 rme 2022-02-05 18:21:10 +03:00
Dimitrii Lopanov
3d4b8507dc Checkout to stable YOLO v4 (#23)
* play with commit

* minor bench
2022-02-05 18:14:44 +03:00
Dimitrii
7edf795470 docs 2022-02-04 23:21:57 +03:00
Dimitrii
020dc47d85 go mod 2022-02-04 22:42:48 +03:00
Dimitrii Lopanov
f813086971 update .phone 2022-01-05 13:52:23 +03:00
Dimitrii Lopanov
7b59b7be33 upd rdme 2022-01-05 13:41:11 +03:00
Dimitrii Lopanov
774662381f misspell 2021-11-01 22:50:46 +03:00
Dimitrii Lopanov
d8cd9728c2 Merge pull request #20 from LdDl/install-cuda
update makefile
2021-08-18 13:09:48 +03:00
Dimitrii
8213e6e9ac update makefile 2021-08-18 13:08:37 +03:00
Dimitrii Lopanov
1b4b71fa8e Merge pull request #19 from LdDl/install-cuda
Install cuda
2021-08-18 13:04:42 +03:00
Dimitrii
7ed6d2e7c9 extend install 2021-08-18 13:02:20 +03:00
Dimitrii
4c748e7ba4 minor renames 2021-08-18 12:08:00 +03:00
Dimitrii
b27d031c92 rm docker temporary 2021-08-18 12:03:02 +03:00
Dimitrii Lopanov
fb66efa419 Update README.md 2021-02-19 14:25:47 +03:00
Dimitrii Lopanov
25fd9865dd Update README.md 2021-02-19 14:25:23 +03:00
Dimitrii Lopanov
687c472ea9 Update README.md 2021-02-19 14:25:12 +03:00
Dimitrii Lopanov
b8f4ad6d57 Merge pull request #16 from LdDl/issue-15
Issue 15
2021-02-01 08:07:24 +03:00
Dimitrii
40df8cce91 free_network_ptr instead of free_network 2021-01-30 13:57:21 +03:00
Dimitrii
13a0697585 remove sleep 2021-01-28 14:26:52 +03:00
Dimitrii
29e4d0d8bb clean 2021-01-28 14:20:38 +03:00
Dimitrii
165e59aaf3 remove defer for image 2021-01-28 14:20:08 +03:00
Dimitrii
81223ac67d start solving issue 2021-01-28 13:43:35 +03:00
Dimitrii Lopanov
7cbe2f50a7 load file 2020-10-16 13:20:22 +03:00
Dimitrii Lopanov
6a381223fa provide example picture 2020-10-16 13:18:39 +03:00
29 changed files with 392 additions and 593 deletions

18
.gitignore vendored
View File

@@ -1,10 +1,14 @@
example/main
example/sample.jpg
example/coco.names
example/yolov3.cfg
example/yolov3.weights
example/yolov4.cfg
example/yolov4.weights
cmd/examples/main
cmd/examples/base_example/main
cmd/examples/coco.names
cmd/examples/yolov3.cfg
cmd/examples/yolov3.weights
cmd/examples/yolov4.cfg
cmd/examples/yolov4.weights
cmd/examples/yolov4-tiny.cfg
cmd/examples/yolov4-tiny.weights
cmd/examples/yolov7-tiny.cfg
cmd/examples/yolov7-tiny.weights
darknet.h
*.so
predictions.png

View File

@@ -1,14 +1,54 @@
.ONESHELL:
.PHONY: download build clean
.PHONY: prepare_cuda prepare_cudnn download_darknet build_darknet build_darknet_gpu clean clean_cuda clean_cudnn sudo_install
# Latest battletested AlexeyAB version of Darknet commit
LATEST_COMMIT?=d65909fbea471d06e52a2e4a41132380dc2edaa6
# LATEST_COMMIT?=f056fc3b6a11528fa0522a468eca1e909b7004b7
LATEST_COMMIT?=9d40b619756be9521bc2ccd81808f502daaa3e9a
# Temporary folder for building Darknet
TMP_DIR?=/tmp/
# Manage cuda version
CUDA_VERSION = 10.2
CUDNN_VERSION = 7.6.5
CUDNN_FULL_VERSION = 7.6.5.32
OS_NAME_LOW_CASE = ubuntu
OS_VERSION_CONCATENATED = 1804
OS_ARCH = x86_64
OS_ALTER_ARCH = linux-x64
OS_FULLNAME = $(OS_NAME_LOW_CASE)$(OS_VERSION_CONCATENATED)
# I guess *.pub is static for most of systems
PUBNAME = 7fa2af80
# Install CUDA
prepare_cuda:
sudo apt-get install linux-headers-$(uname -r)
rm -rf $(TMP_DIR)install_cuda
mkdir $(TMP_DIR)install_cuda
wget -P $(TMP_DIR)install_cuda https://developer.download.nvidia.com/compute/cuda/repos/$(OS_FULLNAME)/$(OS_ARCH)/cuda-$(OS_FULLNAME).pin
cd $(TMP_DIR)install_cuda
sudo mv cuda-$(OS_FULLNAME).pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/$(OS_FULLNAME)/$(OS_ARCH)/$(PUBNAME).pub
sudo add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/$(OS_FULLNAME)/$(OS_ARCH)/ /"
sudo apt-get update
sudo apt-get -y install cuda-$(subst .,-,$(CUDA_VERSION))
cd -
# Install cuDNN
# Notice: this valid instruction for cuDNN version from v7.2.1 up to 8.1.0.77
prepare_cudnn:
rm -rf $(TMP_DIR)install_cudnn
mkdir $(TMP_DIR)install_cudnn
wget -P $(TMP_DIR)install_cudnn https://developer.download.nvidia.com/compute/redist/cudnn/v${CUDNN_VERSION}/cudnn-${CUDA_VERSION}-${OS_ALTER_ARCH}-v${CUDNN_FULL_VERSION}.tgz
cd $(TMP_DIR)install_cudnn
tar -xzvf cudnn-${CUDA_VERSION}-${OS_ALTER_ARCH}-v${CUDNN_FULL_VERSION}.tgz
sudo cp cuda/include/cudnn*.h /usr/local/cuda/include
sudo cp -P cuda/lib64/libcudnn* /usr/local/cuda/lib64
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
cd -
# Download AlexeyAB version of Darknet
download:
download_darknet:
rm -rf $(TMP_DIR)install_darknet
mkdir $(TMP_DIR)install_darknet
git clone https://github.com/AlexeyAB/darknet.git $(TMP_DIR)install_darknet
@@ -17,7 +57,7 @@ download:
cd -
# Build AlexeyAB version of Darknet for usage with CPU only.
build:
build_darknet:
cd $(TMP_DIR)install_darknet
sed -i -e 's/GPU=1/GPU=0/g' Makefile
sed -i -e 's/CUDNN=1/CUDNN=0/g' Makefile
@@ -27,7 +67,7 @@ build:
cd -
# Build AlexeyAB version of Darknet for usage with both CPU and GPU (CUDA by NVIDIA).
build_gpu:
build_darknet_gpu:
cd $(TMP_DIR)install_darknet
sed -i -e 's/GPU=0/GPU=1/g' Makefile
sed -i -e 's/CUDNN=0/CUDNN=1/g' Makefile
@@ -48,8 +88,17 @@ sudo_install:
clean:
rm -rf $(TMP_DIR)install_darknet
clean_cuda:
rm -rf $(TMP_DIR)install_cuda
clean_cudnn:
rm -rf $(TMP_DIR)install_cudnn
# Do every step for CPU-based only build.
install: download build sudo_install clean
install_darknet: download_darknet build_darknet sudo_install clean
# Do every step for both CPU and GPU-based build.
install_gpu: download build_gpu sudo_install clean
install_darknet_gpu: download_darknet build_darknet_gpu sudo_install clean
# Do every step for both CPU and GPU-based build if you haven't installed CUDA.
install_darknet_gpu_cuda: prepare_cuda prepare_cudnn download_darknet build_darknet_gpu sudo_install clean clean_cuda clean_cudnn

129
README.md
View File

@@ -3,38 +3,59 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/LdDl/go-darknet)](https://goreportcard.com/report/github.com/LdDl/go-darknet)
[![GitHub tag](https://img.shields.io/github/tag/LdDl/go-darknet.svg)](https://github.com/LdDl/go-darknet/releases)
# 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].
# go-darknet: Go bindings for Darknet (Yolo V4, Yolo V7-tiny, Yolo V3)
### go-darknet is a Go package, which uses Cgo to enable Go applications to use V4/V7-tiny/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 v7: https://arxiv.org/abs/2207.02696 (WARNING: Only 'tiny' variation works currently)
#### Paper Yolo v4: https://arxiv.org/abs/2004.10934
#### Paper Yolo v3: https://arxiv.org/abs/1804.02767
## Table of Contents
- [Why](#why)
- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
- [Documentation](#documentation)
- [License](#license)
## Why
**Why does this repository exist?**
Because this repository https://github.com/gyonluks/go-darknet is no longer maintained.
**What is purpose of this bindings when you can have [GoCV](https://github.com/hybridgroup/gocv#gocv) (bindings to OpenCV) and it handle Darknet YOLO perfectly?**
Well, you don't need bunch of OpenCV dependencies and OpenCV itself sometimes.
Example of such project here: https://github.com/LdDl/license_plate_recognition#license-plate-recognition-with-go-darknet---- .
## Requirements
You need to install fork of [darknet](https://github.com/AlexeyAB/darknet). Latest commit I've tested is [here](https://github.com/AlexeyAB/darknet/commit/d65909fbea471d06e52a2e4a41132380dc2edaa6)
You need to install fork of [darknet](https://github.com/AlexeyAB/darknet). Latest commit I've tested is [here](https://github.com/AlexeyAB/darknet/commit/9d40b619756be9521bc2ccd81808f502daaa3e9a). It corresponds last official [YOLOv4 release](https://github.com/AlexeyAB/darknet/releases/tag/yolov4)
Use provided [Makefile](Makefile).
* For CPU-based instalattion:
```shell
make install
make install_darknet
```
* For both CPU and GPU-based instalattion:
* For both CPU and GPU-based instalattion if you HAVE CUDA installed:
```shell
make install_gpu
make install_darknet_gpu
```
Note: If you want to have GPU-acceleration before running command above install [CUDA](https://developer.nvidia.com/cuda-downloads) and [cuDNN](https://developer.nvidia.com/cudnn) (Latest CUDA version I've tested is [10.2](https://developer.nvidia.com/cuda-10.2-download-archive) and cuDNN is [7.6.5](https://developer.nvidia.com/rdp/cudnn-archive#a-collapse765-102))
Note: I've tested CUDA [10.2](https://developer.nvidia.com/cuda-10.2-download-archive) and cuDNN is [7.6.5](https://developer.nvidia.com/rdp/cudnn-archive#a-collapse765-102))
* For both CPU and GPU-based instalattion if you HAVE NOT CUDA installed:
```shell
make install_darknet_gpu_cuda
```
Note: There is some struggle in Makefile for cuDNN, but I hope it works in Ubuntu atleast. Do not forget provide proper CUDA and cuDNN versions.
## Installation
@@ -44,19 +65,23 @@ go get github.com/LdDl/go-darknet
## Usage
Example Go program is provided in the [example] directory. Please refer to the code on how to use this Go package.
Example Go program is provided in the [examples] directory. Please refer to the code on how to use this Go package.
Building and running program:
* Navigate to [example] folder
* Navigate to [examples] folder
```shell
cd $GOPATH/github.com/LdDl/go-darknet/example/base_example
cd ${YOUR PATH}/github.com/LdDl/go-darknet/cmd/examples
```
* Download dataset (sample of image, coco.names, yolov4.cfg (or v3), yolov4.weights(or v3)).
```shell
#for yolo v4
./download_data.sh
#for yolo v4 tiny
./download_data_v4_tiny.sh
#for yolo v7 tiny
./download_data_v7_tiny.sh
#for yolo v3
./download_data_v3.sh
```
@@ -86,29 +111,71 @@ Building and running program:
It will reduce amount of VRAM used for detector test.
* Build and run program
Yolo V4:
* Build and run example program
Yolo v7 tiny:
```shell
go build main.go && ./main --configFile=yolov4.cfg --weightsFile=yolov4.weights --imageFile=sample.jpg
go build -o base_example/main base_example/main.go && ./base_example/main --configFile=yolov7-tiny.cfg --weightsFile=yolov7-tiny.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): 53.2890% | start point: (0,143) | end point: (89, 328)
truck (7): 42.1364% | start point: (685,182) | end point: (800, 318)
truck (7): 26.9703% | start point: (437,170) | end point: (560, 217)
car (2): 87.7818% | start point: (509,189) | end point: (742, 329)
car (2): 87.5633% | start point: (262,191) | end point: (423, 322)
car (2): 85.4743% | start point: (427,198) | end point: (549, 309)
car (2): 71.3772% | start point: (0,147) | end point: (87, 327)
car (2): 62.5698% | start point: (98,151) | end point: (197, 286)
car (2): 61.5811% | start point: (693,186) | end point: (799, 316)
car (2): 49.6343% | start point: (386,206) | end point: (441, 286)
car (2): 28.2012% | start point: (386,205) | end point: (440, 236)
bicycle (1): 71.9609% | start point: (179,294) | end point: (249, 405)
person (0): 85.4390% | start point: (146,130) | end point: (269, 351)
```
Yolo v4:
```shell
go build -o base_example/main base_example/main.go && ./base_example/main --configFile=yolov4.cfg --weightsFile=yolov4.weights --imageFile=sample.jpg
```
Output should be something like this:
```shell
traffic light (9): 73.5040% | 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)
truck (7): 46.8694% | 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.2532% | 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): 83.3920% | 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 v4 tiny:
```shell
go build -o base_example/main base_example/main.go && ./base_example/main --configFile=yolov4-tiny.cfg --weightsFile=yolov4-tiny.weights --imageFile=sample.jpg
```
Output should be something like this:
```shell
truck (7): 77.7936% | start point: (0,138) | end point: (90, 332)
truck (7): 55.9773% | start point: (696,174) | end point: (799, 314)
car (2): 53.1286% | start point: (696,184) | end point: (799, 319)
car (2): 98.0222% | start point: (262,189) | end point: (424, 330)
car (2): 97.8773% | start point: (430,190) | end point: (542, 313)
car (2): 81.4099% | start point: (510,190) | end point: (743, 325)
car (2): 43.3935% | start point: (391,207) | end point: (435, 299)
car (2): 37.4221% | start point: (386,206) | end point: (429, 239)
car (2): 32.0724% | start point: (109,196) | end point: (157, 289)
person (0): 73.0868% | start point: (154,132) | end point: (284, 382)
```
Yolo V3:
```
go build main.go && ./main --configFile=yolov3.cfg --weightsFile=yolov3.weights --imageFile=sample.jpg
@@ -116,19 +183,19 @@ Building and running program:
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)
truck (7): 49.5123% | start point: (0,136) | end point: (85, 311)
car (2): 36.3694% | start point: (95,152) | end point: (186, 283)
truck (7): 48.4177% | start point: (95,152) | end point: (186, 283)
truck (7): 45.6520% | start point: (694,178) | end point: (798, 310)
car (2): 76.8402% | start point: (1,145) | end point: (84, 324)
truck (7): 25.5920% | start point: (107,89) | end point: (215, 263)
car (2): 99.8782% | start point: (511,185) | end point: (748, 328)
car (2): 99.8193% | start point: (261,189) | end point: (427, 322)
car (2): 99.6405% | start point: (426,197) | end point: (539, 311)
car (2): 74.5627% | start point: (692,186) | end point: (796, 316)
car (2): 72.7975% | start point: (388,206) | end point: (437, 276)
bicycle (1): 72.2760% | start point: (178,270) | end point: (268, 406)
person (0): 97.3007% | start point: (143,135) | end point: (268, 343)
```
## Documentation
@@ -145,5 +212,5 @@ go-darknet follows [Darknet]'s [license].
[darknet.h]: https://github.com/AlexeyAB/darknet/blob/master/include/darknet.h
[include/darknet.h]: https://github.com/AlexeyAB/darknet/blob/master/include/darknet.h
[Makefile]: https://github.com/alexeyab/darknet/blob/master/Makefile
[example]: /example/base_example
[examples]: cmd/examples/base_example
[GoDoc]: https://godoc.org/github.com/LdDl/go-darknet

View File

@@ -11,6 +11,7 @@ import (
"os"
darknet "github.com/LdDl/go-darknet"
"github.com/disintegration/imaging"
)
@@ -61,13 +62,13 @@ func main() {
if err != nil {
panic(err.Error())
}
defer imgDarknet.Close()
dr, err := n.Detect(imgDarknet)
if err != nil {
printError(err)
return
}
imgDarknet.Close()
log.Println("Network-only time taken:", dr.NetworkOnlyTimeTaken)
log.Println("Overall time taken:", dr.OverallTimeTaken, len(dr.Detections))
@@ -92,6 +93,8 @@ func main() {
// }
}
}
n.Close()
}
func imageToBytes(img image.Image) ([]byte, error) {

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=yolov4-tiny.cfg https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov4-tiny.cfg
sed -i -e "\$anames = coco.names" yolov4-tiny.cfg
wget --output-document=yolov4-tiny.weights https://github.com/AlexeyAB/darknet/releases/download/yolov4/yolov4-tiny.weights

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=yolov7-tiny.cfg https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov7-tiny.cfg
sed -i -e "\$anames = coco.names" yolov7-tiny.cfg
wget --output-document=yolov7-tiny.weights https://github.com/AlexeyAB/darknet/releases/download/yolov4/yolov7-tiny.weights

View File

@@ -11,7 +11,7 @@ import (
"log"
"net/http"
"github.com/LdDl/go-darknet"
darknet "github.com/LdDl/go-darknet"
)
var configFile = flag.String("configFile", "",

BIN
cmd/examples/sample.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

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

View File

@@ -1,40 +0,0 @@
# 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"]

View File

@@ -1,52 +0,0 @@
# 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"]

View File

@@ -1,185 +0,0 @@
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)

View File

@@ -1,186 +0,0 @@
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)

View File

@@ -1,32 +0,0 @@
---
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

View File

@@ -1,10 +0,0 @@
#!/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

View File

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

14
go.mod Normal file
View File

@@ -0,0 +1,14 @@
module github.com/LdDl/go-darknet
go 1.17
require (
github.com/disintegration/imaging v1.6.2
github.com/pkg/errors v0.9.1
golang.org/x/image v0.0.0-20211028202545-6944b10bf410
)
require (
github.com/edsrzf/mmap-go v1.1.0 // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
)

14
go.sum Normal file
View File

@@ -0,0 +1,14 @@
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

15
image.c
View File

@@ -11,3 +11,18 @@ void set_data_f32_val(float* data, int index, float value) {
data[index] = value;
}
void to_float_and_fill_image(image* im, int w, int h, uint8_t* data) {
int x, y, idx_source;
int pixel_count = w * h;
int idx = 0;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
idx_source = (y*w + x) * 4;
im->data[(pixel_count*0) + idx] = (float)data[idx_source] / 255;
im->data[(pixel_count*1) + idx] = (float)data[idx_source+1] / 255;
im->data[(pixel_count*2) + idx] = (float)data[idx_source+2] / 255;
idx++;
}
}
}

View File

@@ -14,61 +14,33 @@ 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
}
// https://stackoverflow.com/questions/33186783/get-a-pixel-array-from-from-golang-image-image/59747737#59747737
func imgTofloat32(src image.Image) []float32 {
func Image2Float32(src image.Image) (*DarknetImage, error) {
bounds := src.Bounds()
width, height := bounds.Max.X, bounds.Max.Y
srcRGBA := image.NewRGBA(src.Bounds())
draw.Copy(srcRGBA, image.Point{}, src, src.Bounds(), draw.Src, nil)
srcRGBA := image.NewRGBA(bounds)
draw.Copy(srcRGBA, image.Point{}, src, bounds, draw.Src, nil)
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
pix := srcRGBA.Pix[idxSource : idxSource+4]
rpix, gpix, bpix := float32(pix[0])/257.0, float32(pix[1])/257.0, float32(pix[2])/257.0
red = append(red, rpix)
green = append(green, gpix)
blue = append(blue, bpix)
}
}
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
return ImageRGBA2Float32(srcRGBA)
}
// Image2Float32 Returns []float32 representation of image.Image
func Image2Float32(img image.Image) (*DarknetImage, error) {
// ans := imgTofloat32(img)
func ImageRGBA2Float32(img *image.RGBA) (*DarknetImage, error) {
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(&imgDarknet.ans[0])))
C.to_float_and_fill_image(&imgDarknet.image, C.int(width), C.int(height), (*C.uint8_t)(unsafe.Pointer(&img.Pix[0])))
return imgDarknet, nil
}

View File

@@ -3,4 +3,5 @@
#include <darknet.h>
extern void fill_image_f32(image *im, int w, int h, int c, float* data);
extern void set_data_f32_val(float* data, int index, float value);
extern void set_data_f32_val(float* data, int index, float value);
extern void to_float_and_fill_image(image *im, int w, int h, uint8_t* data);

View File

@@ -14,7 +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 };
network_predict(*n, sized.data);
// mleak at network_predict(), get_network_boxes() and network_predict_ptr()?
network_predict_ptr(n, sized.data);
int nboxes = 0;
result.detections = get_network_boxes(n, img->w, img->h, thresh, hier_thresh, 0, 1, &result.detections_len, letter_box);
if (nms) {

View File

@@ -7,9 +7,13 @@ package darknet
// #include "network.h"
import "C"
import (
"errors"
"io/ioutil"
"os"
"time"
"unsafe"
"github.com/edsrzf/mmap-go"
"github.com/pkg/errors"
)
// YOLONetwork represents a neural network using YOLO.
@@ -53,12 +57,87 @@ func (n *YOLONetwork) Init() error {
return nil
}
/* EXPERIMENTAL */
/*
By default AlexeyAB's Darknet doesn't export any functions in darknet.h to give ability to create network from scratch via code.
So I can't modify `parse_network_cfg_custom` to load `list *sections = read_cfg(filename);` from memory.
So, the point of this method is to be able create network configuration via Golang and then pass it to `C.load_network`
This code is portable for Windows/Linux/MacOS. See the ref.: https://github.com/edsrzf/mmap-go#mmap-go
*/
func (n *YOLONetwork) InitFromDefinedCfg() error {
wFile := C.CString(n.WeightsFile)
defer C.free(unsafe.Pointer(wFile))
/* Prepare network sections via Go */
/*
instead of using:
wFile := C.CString(n.WeightsFile)
defer C.free(unsafe.Pointer(wFile))
We call `load_network` that takes the first char* parameter (representing a file path to network configuration) with a Go function that takes an in-memory file
*/
cfgBytes, err := os.ReadFile(n.NetworkConfigurationFile)
if err != nil {
return errors.Wrap(err, "Can't read file bytes")
}
// Create a temporary file.
tmpFile, err := ioutil.TempFile("", "")
if err != nil {
return errors.Wrap(err, "Can't create temporary file")
}
defer os.Remove(tmpFile.Name())
// Write the file content to the temporary file.
if _, err := tmpFile.Write(cfgBytes); err != nil {
return errors.Wrap(err, "Can't write network's configuration into temporary file")
}
defer tmpFile.Close()
// Open the temporary file.
// fd, err := syscall.Open(tmpFile.Name(), syscall.O_RDWR, 0)
// if err != nil {
// return errors.Wrap(err, "Can't re-open temporary file")
// }
// defer syscall.Close(fd)
// Create a memory mapping of the file.
// addr, err := syscall.Mmap(fd, 0, len(cfgBytes), syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
// if err != nil {
// return errors.Wrap(err, "Can't mmap on temporary file")
// }
// Unmap the memory-mapped file.
// defer syscall.Munmap(addr)
// Map the temporary file to memory.
mapping, err := mmap.Map(tmpFile, mmap.RDWR, 0)
if err != nil {
return errors.Wrap(err, "Can't mmap on temporary file")
}
defer mapping.Unmap() // Unmap the memory-mapped file.
// GPU device ID must be set before `load_network()` is invoked.
C.cuda_set_device(C.int(n.GPUDeviceIndex))
nCfg := C.CString(tmpFile.Name())
defer C.free(unsafe.Pointer(nCfg))
n.cNet = C.load_network(nCfg, wFile, 0)
if n.cNet == nil {
return errUnableToInitNetwork
}
C.srand(2222222)
n.hierarchalThreshold = 0.5
n.nms = 0.45
metadata := C.get_metadata(nCfg)
n.Classes = int(metadata.classes)
n.ClassNames = makeClassNames(metadata.names, n.Classes)
return nil
}
// Close and release resources.
func (n *YOLONetwork) Close() error {
if n.cNet == nil {
return errNetworkNotInit
}
C.free_network(*n.cNet)
C.free_network_ptr(n.cNet)
n.cNet = nil
return nil
}

58
section.go Normal file
View File

@@ -0,0 +1,58 @@
package darknet
import (
"bufio"
"os"
"strings"
)
// Section represents a section in the configuration file.
type Section struct {
Type string
Options []string
}
// readCfg reads a configuration file and returns a list of sections.
func readCfg(filename string) ([]Section, error) {
// Open the configuration file.
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
// Create a list of sections.
var sections []Section
var current *Section
// Read each line in the file.
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" {
continue
}
switch line[0] {
case '[':
if current != nil {
sections = append(sections, *current)
}
current = &Section{Type: line}
case '#', ';', '\x00':
// Ignore comments and empty lines.
default:
if current == nil {
current = &Section{}
}
current.Options = append(current.Options, line)
}
}
if current != nil {
sections = append(sections, *current)
}
if err := scanner.Err(); err != nil {
return nil, err
}
return sections, nil
}

20
section_test.go Normal file
View File

@@ -0,0 +1,20 @@
package darknet
import (
"fmt"
"testing"
)
func TestReadSectionsFromCfg(t *testing.T) {
sections, err := readCfg("./cmd/examples/yolov7-tiny.cfg")
if err != nil {
fmt.Println(err)
return
}
for _, s := range sections {
fmt.Println(s.Type)
for _, o := range s.Options {
fmt.Println("\t", o)
}
}
}