yoloV 3 darknet GPUハンドルコンパイルからトレーニングまでC++呼び出しAPI
まず、システムはUbuntu 18であることを宣言します.04、私の機械はopencv 4を取り付けました.1.1とcuda 10.0の、プロセスは私の別のブログを参考にすることができて、この部分はIDEがqtcreatorを使うことを説明しません
1.Darknetのダウンロード
Githubリンク公式サイトリンク
これは言うまでもなく、直接git clone、ネットがよくなくても構わない.
予備トレーニングウェイトdarknet 53もダウンロードする.conv.74これは先に置いて、後でそれを訓練フォルダにしてダウンロードして完成した後にdarknetフォルダに入ります
2.Makefileの構成
コードの修正を容易にするため、VSCodeを使用してdarknetがあるフォルダを開きます.
Makefileファイルを見つけて開き、最初の5行は構成のパラメータで、OPENCV、GPU、CUDNNはすべて開きます
修正が済んだらこうなります
後のグラフィックカードの計算能力の構成についてこの参考の別のブログ、私は改正しないで問題にぶつかることがありません
42行目を見つけてpkg-congifのパッケージ名を変更し、opencv 4の名前はopencv 4で、両方を変更します.
これで、他は動かなくてもいいです.
次はcudaのライブラリで、自分のパスと一致しているかどうかをチェックして、私のデフォルトでいいです.
このMakefileの構成が完了しました
3.コンパイルし、いくつかのエラーを修正する
ショートカットキーCtrl+shift+Pを押してVSCodeのコマンドを開き、C/C++を検索し、編集構成(UI)を開き、UIを使わずに勝手に含むパスを見つけて、opencvの含むパスとcudaの含むパスを追加して、後でコードを修正して簡単にopencvの含むアドレスを見るためにpkg-configでいいです.例えば、私の書いた のようにします.グローバルを追加して、下の格の中で、配置パラメータは開いて何を記入して、私のはこのように です
実は簡単にCtrl+shift+`を押してVSCodeの端末を開けて、makeを実行してそれから間違いを報告します
これは彼がopencv 3の構造と命名を書いたためで、4のいくつかの変動はCtrlを押して、マウスは./src/image_opencv.cpp:12:1直接この位置に移動します.これは私がVSCodeを使った大きな理由で一番上にヘッダファイルを追加しました.
この間違いは解決しましたそして
これがネーミングの変化で、このような前のCVを削除すればいい、この間違いはimageにある.opencv.cppの中で、このファイルは後で役に立ちます.覚えておいてください.間違いを直すとコンパイルが完了します.
4.独自のデータセットを作成する
まずフォルダを建てて、名前は任意で、中国語を持たないでください、あなたは知っていてそれから以下はすべてこの中でdarknet YoloV 3のデータセットのフォーマットを操作するのはテキストのドキュメントで、構造は簡単で1つのJPEGImagesフォルダで、中に画像を置いて、すべてJPGフォーマットで、そうでなければopencvで自分でプログラムを書いて自動的に別のlabelsフォルダを変換することができますタグファイルを保存するのもtxt形式です文書ドキュメントタグファイルの具体的な形式は、ファイル名と対応するJPGファイル名が同じであることを保証します
それから2つのフォルダは必ず一緒に置いて、darknetは直接自動的に画像ファイルの
1行1つ私が5つの目標を例にvocを新規作成しました.data文書ドキュメントには5行あります
もう1つの最も重要なcfgファイルは、
次に[yolo]の項を探して、全部で3つあって、608行で、692行で、776行は1つを例にとって、その他の3つは同じです
最初にダウンロードしたプリトレーニングの重みを加えると、最終的なフォルダ構造が完了します.
トレーニングセットのラベルや写真集の生成については、みんなコードを使っていると思いますが、サボる方法が思いつかないわけがないでしょう.
4.1オートメーションツールを少しください
もともと直接訓練を始めることができて、しかし私は比較的に怠け者で、命令が長すぎるのが嫌で、それからこれがありました
前は簡単ですが、使用方法は、
5.トレーニング開始
前の行の変数を設定すれば
6.C++呼び出し
まずdarknetディレクトリの下にinclude/darknet.hとlibdarknet.so/usr/localの下にフォルダを新規作成するなど、他の安全な場所にコピーし、その共有ライブラリをシステムに追加します.
新しいqtcreatorのプロジェクト(qtcreatorを例に挙げると、操作は他のプラットフォームで再現できます)proファイルにopencvを追加します.(これは詳しくは言いません)darknet.hの参照ディレクトリを追加し、cudaの参照ディレクトリを追加します.前述したように、一般的に
VSCodeに戻ってdarknetのソースコードを読んでexamples/darknetを見つけます.c,中はmain関数を含んで、沿って関数を探し当てることができて、呼び出しはきっとテストとあまり差がなくて、detectorコマンドを識別する場所を探し当てます
この関数を定義します
定義
これが最良のルーチンです.$が終わるのは必須のステップです.
Opencvで画像を読み取りたい場合は、
detection構造体の説明については、私も理解していませんが、これらは十分です.
最後にルーチンを1部送る
もうここまで来たんだから無駄なことを考えないで
1.Darknetのダウンロード
Githubリンク公式サイトリンク
これは言うまでもなく、直接git clone、ネットがよくなくても構わない.
git clone https://github.com/pjreddie/darknet
予備トレーニングウェイトdarknet 53もダウンロードする.conv.74これは先に置いて、後でそれを訓練フォルダにしてダウンロードして完成した後にdarknetフォルダに入ります
2.Makefileの構成
コードの修正を容易にするため、VSCodeを使用してdarknetがあるフォルダを開きます.
Makefileファイルを見つけて開き、最初の5行は構成のパラメータで、OPENCV、GPU、CUDNNはすべて開きます
GPU=0
CUDNN=0
OPENCV=0
OPENMP=0
DEBUG=0
修正が済んだらこうなります
GPU=1
CUDNN=1
OPENCV=1
OPENMP=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_20,code=[sm_20,sm_21] \ This one is deprecated?
# This is what I use, uncomment if you know your arch and want to specify
# ARCH= -gencode arch=compute_52,code=compute_52
42行目を見つけてpkg-congifのパッケージ名を変更し、opencv 4の名前はopencv 4で、両方を変更します.
ifeq ($(OPENCV), 1)
COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv` -lstdc++
COMMON+= `pkg-config --cflags opencv`
endif
これで、他は動かなくてもいいです.
ifeq ($(OPENCV), 1)
COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv4` -lstdc++
COMMON+= `pkg-config --cflags opencv4`
endif
次はcudaのライブラリで、自分のパスと一致しているかどうかをチェックして、私のデフォルトでいいです.
ifeq ($(GPU), 1)
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif
このMakefileの構成が完了しました
3.コンパイルし、いくつかのエラーを修正する
ショートカットキーCtrl+shift+Pを押してVSCodeのコマンドを開き、C/C++を検索し、編集構成(UI)を開き、UIを使わずに勝手に
/usr/local/include/opencv4/**
は自分で探せばいいです.cudaの見つからないようにして、一般的に/usr/local/cuda/include
の中で、私の追加は以下の${workspaceFolder}/**
/usr/local/cuda/include/
/usr/local/include/opencv4/**
OPENCV
CUDNN
GPU
do{
make;
if( ){
;
continue;
}
else break;
}while(1); //
実は簡単にCtrl+shift+`を押してVSCodeの端末を開けて、makeを実行してそれから間違いを報告します
./src/image_opencv.cpp:12:1: error: ‘IplImage’ does not name a type; did you mean ‘image’?
IplImage *image_to_ipl(image im)
^~~~~~~~
これは彼がopencv 3の構造と命名を書いたためで、4のいくつかの変動はCtrlを押して、マウスは./src/image_opencv.cpp:12:1直接この位置に移動します.これは私がVSCodeを使った大きな理由で一番上にヘッダファイルを追加しました.
#include "opencv2/imgproc/imgproc_c.h"
この間違いは解決しましたそして
./src/image_opencv.cpp:76:20: error: ‘CV_CAP_PROP_FRAME_WIDTH’ was not declared in this scope
if(w) cap->set(CV_CAP_PROP_FRAME_WIDTH, w);
これがネーミングの変化で、このような前のCVを削除すればいい、この間違いはimageにある.opencv.cppの中で、このファイルは後で役に立ちます.覚えておいてください.間違いを直すとコンパイルが完了します.
4.独自のデータセットを作成する
まずフォルダを建てて、名前は任意で、中国語を持たないでください、あなたは知っていてそれから以下はすべてこの中でdarknet YoloV 3のデータセットのフォーマットを操作するのはテキストのドキュメントで、構造は簡単で1つのJPEGImagesフォルダで、中に画像を置いて、すべてJPGフォーマットで、そうでなければopencvで自分でプログラムを書いて自動的に別のlabelsフォルダを変換することができますタグファイルを保存するのもtxt形式です文書ドキュメントタグファイルの具体的な形式は、ファイル名と対応するJPGファイル名が同じであることを保証します
2 0.341624 0.582733 0.00729167 0.0175926
1 0.433048 0.624979 0.0286458 0.062963
4 0.265383 0.666638 0.0776042 0.125926
#ID box X box Y W H
# 0-1,
#
それから2つのフォルダは必ず一緒に置いて、darknetは直接自動的に画像ファイルの
../labels/xxxxxx.txt
に対してマークファイルの再構築backupフォルダを探して、訓練の重みファイルのバックアップweigitsフォルダを保存して、訓練が完了して保留する重みファイルを保存するために、この自発的なImageSetsフォルダ、画像セットを保存するために2つのテキストドキュメントを再構築します.画像セットにはtrainという名前があります.txtは訓練のためのピクチャセットで、中にJPGピクチャの経路を保存して、絶対経路を推薦して、1行の1つの経路のもう1つのval.txtはフォーマットが同じImageSetsフォルダを検証して、新しいvocを作ります.names文書ドキュメントには、ターゲットのラベルが書かれています.たとえば、car
people
bicycle
bird
boat
1行1つ私が5つの目標を例にvocを新規作成しました.data文書ドキュメントには5行あります
classes=
train = /...../ /ImageSets/train.txt
valid = /...../ /ImageSets/val.txt
names = /...../ /voc.names
backup = /...../ /backup
もう1つの最も重要なcfgファイルは、
cfg/yolov3-voc.cfg
から1つコピーして、あなたのフォルダに行って、名前を変更することができて、接尾辞は保留して(実は大丈夫です)、それから前のいくつかの行を修正します[net]の下[net]
# Testing
batch=1 #batch , ,
subdivisions=1 #subdivisions batch
# batch/subdivisions,
# Training
# batch=64
# subdivisions=16
width=416 #width height channels , ,
height=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1
learning_rate=0.001 # ,
burn_in=1000
max_batches = 50200 #
policy=steps # ,
steps=40000,45000 # 40000 0.1,45000 0.1
scales=.1,.1 # ,
次に[yolo]の項を探して、全部で3つあって、608行で、692行で、776行は1つを例にとって、その他の3つは同じです
[convolutional]
size=1
stride=1
pad=1
filters=10 # , , 3*( +5),
activation=linear
[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=20 #
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1 # , , ,
# ,
最初にダウンロードしたプリトレーニングの重みを加えると、最終的なフォルダ構造が完了します.
╞backup
╞ImageSets
║ └train.txt val.txt
╞JPEGImages
║ └
╟labels
║ └
╟weigits
╟voc.names
╟voc.data
╟yolov3-voc.cfg
└darknet53.conv.74
トレーニングセットのラベルや写真集の生成については、みんなコードを使っていると思いますが、サボる方法が思いつかないわけがないでしょう.
4.1オートメーションツールを少しください
もともと直接訓練を始めることができて、しかし私は比較的に怠け者で、命令が長すぎるのが嫌で、それからこれがありました
DARKNET_PATH= darknet
LOCAT=${PWD} #
classes=5
TRAIN_PATH=${LOCAT}/ImageSets/train.txt
VALID_PATH=${LOCAT}/ImageSets/val.txt
NAMES_PATH=${LOCAT}/voc.names
BACKUP_PATH=${LOCAT}/backup
DATA_PATH=${LOCAT}/voc.data
CFG_PATH=${LOCAT}/yolov3-voc.cfg
MODEL_PATH=${LOCAT}/darknet53.conv.74
cat>${DATA_PATH}<<EOF
classes= ${classes}
train = ${TRAIN_PATH}
valid = ${VALID_PATH}
names = ${NAMES_PATH}
backup = ${BACKUP_PATH}
EOF
cd ${DARKNET_PATH}
if [ "$1" = "train" ];then
if [ "$2" = "" ];then
./darknet detector train ${DATA_PATH} ${CFG_PATH} darknet53.conv.74 -gpus 0
else
if [ "$2" = "goon" ];then
WEIGHT=${BACKUP_PATH}/yolov3-voc.backup
./darknet detector train ${DATA_PATH} ${CFG_PATH} ${WEIGHT} -gpus 0
else
./darknet detector train ${DATA_PATH} ${CFG_PATH} $2 -gpus 0
fi
fi
fi
if [ "$1" = "test" ];then
WEIGHT=${BACKUP_PATH}/yolov3-voc.backup
if [ "$3" = "" ];then
./darknet detector test ${DATA_PATH} ${CFG_PATH} ${WEIGHT} -gpus 0 $2
else
./darknet detector test ${DATA_PATH} ${CFG_PATH} $3 $2 -gpus 0
fi
fi
前は簡単ですが、使用方法は、
./xxxx.sh train
がトレーニング(デフォルトではdarknet 53.conv.74トレーニング)./xxxx.sh train goon
が前回のウェイトトレーニングを継続することです.(デフォルトではbackup/yolov 3-voc.backupトレーニングを使用)./xxxx.sh train
は別の重みファイルに基づいて./xxxx.sh test JPG
を訓練します.その画像テスト./xxxx.sh test JPG
を使用します.その画像と重みファイルテストを使用して、このスクリプトをトレーニングセットフォルダに入れてください.5.トレーニング開始
前の行の変数を設定すれば
./xxxx.sh train
になります.プレビュー効果は./xxxx.sh test JPG
になります.6.C++呼び出し
まずdarknetディレクトリの下にinclude/darknet.hとlibdarknet.so/usr/localの下にフォルダを新規作成するなど、他の安全な場所にコピーし、その共有ライブラリをシステムに追加します.
cd /etc/ld.so.conf.d/
sudo vim darknet.conf #
sudo ldconfig #
新しいqtcreatorのプロジェクト(qtcreatorを例に挙げると、操作は他のプラットフォームで再現できます)proファイルにopencvを追加します.(これは詳しくは言いません)darknet.hの参照ディレクトリを追加し、cudaの参照ディレクトリを追加します.前述したように、一般的に
/usr/local/cuda/include
にdarknetとcudaのライブラリパスを追加し、OPENCVを追加するVSCodeに追加したいくつかのマクロを追加するのはこのようなことです.#darknet cuda, cuda
INCLUDEPATH += /usr/local/darknet /usr/local/cuda/include
LIBS += -L/usr/local/darknet/lib -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand -lcudnn -ldarknet
DEFINES += GPU OPENCV CUDNN #darknet ,
VSCodeに戻ってdarknetのソースコードを読んでexamples/darknetを見つけます.c,中はmain関数を含んで、沿って関数を探し当てることができて、呼び出しはきっとテストとあまり差がなくて、detectorコマンドを識別する場所を探し当てます
} else if (0 == strcmp(argv[1], "detector")){
run_detector(argc, argv);
この関数を定義します
if(0==strcmp(argv[2], "test")) test_detector(datacfg, cfg, weights, filename, thresh, hier_thresh, outfile, fullscreen);
else if(0==strcmp(argv[2], "train")) train_detector(datacfg, cfg, weights, gpus, ngpus, clear);
定義
test_detector
までtestコマンドとtrainコマンドが見つかりますvoid test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen)
{
/*
printf(" test_detector
"
"datacfg = %s
" //
"cfgfile = %s
" //
"weightfile = %s
" //
"filename = %s
" //
"thresh = %f
" // , 0.5
"hier_thresh = %f
"//? = 0.5
"outfile = %s
" //
"fullscreen = %d
" //
, datacfg, cfgfile, weightfile, filename, thresh, hier_thresh, outfile, fullscreen);*/
list *options = read_data_cfg(datacfg); // .data $
char *name_list = option_find_str(options, "names", "data/names.list"); // $
/*printf("name_list = %s
", name_list);*/
char **names = get_labels(name_list); // $
image **alphabet = load_alphabet(); //
network *net = load_network(cfgfile, weightfile, 0); // $
set_batch_network(net, 1); // (CUDNN )$
srand(2222222);
double time;
char buff[256];
char *input = buff;
float nms=.45;
while(1){
if(filename){ // ,
strncpy(input, filename, 256);
} else { //
printf("Enter Image Path: ");
fflush(stdout);
input = fgets(input, 256, stdin);
if(!input) return;
strtok(input, "
");
}
image im = load_image_color(input,0,0); // (load_image_cv )
image sized = letterbox_image(im, net->w, net->h); // $
//image sized = resize_image(im, net->w, net->h);
//image sized2 = resize_max(im, net->w);
//image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);
//resize_network(net, sized.w, sized.h);
layer l = net->layers[net->n-1];
float *X = sized.data; //
time=what_time_is_it_now(); //
network_predict(net, X); // $
printf("%s: Predicted in %f seconds.
", input, what_time_is_it_now()-time);
int nboxes = 0;
// bandbox $
detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
//printf("%d
", nboxes);
//if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);
if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes); // bandbox
free_detections(dets, nboxes); // bandbox
if(outfile){
save_image(im, outfile); // outfile , outfile
}
else{
save_image(im, "predictions");
#ifdef OPENCV
make_window("predictions", 512, 512, 0);
show_image(im, "predictions", 0);
#endif
}
free_image(im);
free_image(sized);
if (filename) break;
}
}
これが最良のルーチンです.$が終わるのは必須のステップです.
Opencvで画像を読み取りたい場合は、
src/image_opencv.cpp
のmat_を見つけます.to_イメージはopencvのMatをYoloに変換して受け入れるフォーマットが関数、ipl_to_imageとrgbgr_イメージはすぐそばにあるので、必要なものをコピーしてください.image mat_to_image(Mat m)
{
IplImage ipl = m;
image im = ipl_to_image(&ipl);
rgbgr_image(im);
return im;
}
detection構造体の説明については、私も理解していませんが、これらは十分です.
typedef struct
{
// bandbox ( )
float x, y, w, h;
} box;
typedef struct detection
{
boxbbox; //bandbox
int classes;
float *prob; // ,
float *mask;
float objectness;
int sort_class;
} detection;
最後にルーチンを1部送る
#include
#include
#include
#include
using namespace std;
using namespace cv;
#define datacfg "/home/yao/Documents/yoloV3/darknet/VOCdevkit/VOC2007/voc.data"
#define cfgfile "/home/yao/Documents/yoloV3/darknet/VOCdevkit/VOC2007/yolov3-voc.cfg"
#define weightfile "/home/yao/Documents/yoloV3/darknet/VOCdevkit/VOC2007/weigits/640_480_3K_5.23.weights"
#define videosrc "/home/yao/Videos/0.mp4"
#define SavePAYH "/home/yao/Videos/640_480_3K_5.23.avi"
#define PicturePATH "/home/yao/Downloads/qq-files/1790931015/file_recv/BL}A~RL7L3Y0({BI0[}JGRT.png"
#define SaveVideo 1
#define USE_Picture 0
void drawBox(Mat& Src, const Scalar& color, box Box, const char* name, float prob);
Scalar get_Scalar(int index, int classes);
image cvmat_to_image(cv::Mat m);
int main()
{
list *options = read_data_cfg(datacfg); //
char *name_list = option_find_str(options, "names", NULL); //
char **names = get_labels(name_list); //
int classes = option_find_int(options, "classes", 2); //
network *net = load_network(cfgfile, weightfile, 0); //
set_batch_network(net, 1); // (CUDNN )
#if (USE_Picture == 0)
VideoCapture CAP(videosrc);
//
// CAP.open("/dev/video0", CAP_V4L2);
// CAP.set(CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
// CAP.set(CAP_PROP_FRAME_HEIGHT, 480);
// CAP.set(CAP_PROP_FRAME_WIDTH, 640);
// CAP.set(CAP_PROP_AUTO_WB, 1);
// CAP.set(CAP_PROP_AUTO_EXPOSURE, 0);
// CAP.set(CAP_PROP_EXPOSURE, 121);
// CAP.set(CAP_PROP_FPS, 120);
#endif
#if(SaveVideo == 1)
VideoWriter Writer(SavePAYH, VideoWriter::fourcc('M', 'J', 'P', 'G'), 30, Size(1920, 1080));
if(!Writer.isOpened())
{
cout << "Writer Error" << endl;
exit(-1);
}
#endif
Mat Src, Dst;
int nboxes = 0;
namedWindow("Video", WINDOW_NORMAL);
resizeWindow("Video", 1280, 720);
#if (USE_Picture == 0)
double time1 = 0;
double time2 = 0;
char buff[100] = { 0 };
if(CAP.isOpened())
{
while(CAP.read(Src))
{
time1 = (double)getCPUTickCount();
#else
Src = imread(PicturePATH);
#endif
resize(Src, Dst, Size(net->w,net->h)); //
image im = cvmat_to_image(Dst); // Yolo
network_predict(net, im.data); //
detection *dets = get_network_boxes(net, im.w, im.h, 0.5, 0.5, 0, 1, &nboxes); // bandbox
cout << nboxes << endl;
for(int i = 0; i < nboxes; ++i)
{
//cout << i << ": objectness=" << dets[i].objectness << endl;
float probmax = dets[i].prob[0];
int index = 0;
for(int j = 0; j < dets->classes; ++j)
{
if(probmax < dets[i].prob[j]) //
{
probmax = dets[i].prob[j];
index = j;
}
//cout << "names=" << names[j] << " prob=" << dets[i].prob[j] << endl;
}
if(probmax < 0.5) //
{
cout << "throw" << endl;
continue;
}
drawBox(Src, get_Scalar(index, classes), dets[i].bbox, names[index], probmax);
}
#if (USE_Picture == 0)
#if(SaveVideo == 1)
time2 = (double)getCPUTickCount();
double usetime = (time2 - time1) / getTickFrequency();
sprintf(buff, "Time = %4.3lfms FPS = %2.2lf BoxConut = %d", usetime * 1000.0, 1.0 / usetime, nboxes);
cout << buff << endl;
putText(Src, buff, Point(25, 100), FONT_ITALIC, 1, Scalar(0, 255, 0), 2);
putText(Src, weightfile, Point(25, 50), FONT_ITALIC, 1, Scalar(0, 255, 0), 2);
imshow("Video", Src);
Writer.write(Src);
#endif
waitKey(1);
#else
imshow("Video", Src);
waitKey(100000);
#endif
free_image(im); //free!!!!!!! C darknet
free_detections(dets, nboxes); //free!!!!!!! C darknet
#if (USE_Picture == 0)
}
}
else
{
cout << "CAP Error" << endl;
}
#endif
free_network(net); //free!!!!!!! C darknet
free_ptrs((void**)names, classes); //free!!!!!!! C darknet
free_list(options); //free!!!!!!! C darknet
cout << "Done!" << endl;
}
// bandbox
void drawBox(Mat& Src, const Scalar& color, box Box, const char* name, float prob)
{
int left = (Box.x-Box.w/2.)*Src.cols;
int right = (Box.x+Box.w/2.)*Src.cols;
int top = (Box.y-Box.h/2.)*Src.rows;
int bot = (Box.y+Box.h/2.)*Src.rows;
if(left < 0) left = 0;
if(right > Src.cols-1) right = Src.cols-1;
if(top < 0) top = 0;
if(bot > Src.rows-1) bot = Src.rows-1;
Point p1(left, top);
Point p2(right, bot);
putText(Src, name + to_string(prob * 100) + "%", p1 - Point(0, 3), FONT_HERSHEY_PLAIN, 1, color);
rectangle(Src, p1, p2, color, 2);
}
float get_color(int c, int x, int max)
{
float colors[6][3] = { {1,0,1}, {0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,0,0} };
float ratio = ((float)x / max) * 5;
int i = floor(ratio);
int j = ceil(ratio);
ratio -= i;
float r = (1-ratio) * colors[i][c] + ratio*colors[j][c];
return r;
}
Scalar get_Scalar(int index, int classes)
{
int offset = index * 123457 % classes;
int red = get_color(0, offset, classes) * 255;
int green = get_color(1, offset, classes) * 255;
int blue = get_color(2, offset, classes) * 255;
return Scalar(blue, green, red);
}
image cvipl_to_image(IplImage *src)
{
int h = src->height;
int w = src->width;
int c = src->nChannels;
image im = make_image(w, h, c);
unsigned char *data = (unsigned char *)src->imageData;
int step = src->widthStep;
int i, j, k;
for (i = 0; i < h; ++i)
{
for (k = 0; k < c; ++k)
{
for (j = 0; j < w; ++j)
{
im.data[k * w * h + i * w + j] = data[i * step + j * c + k] / 255.;
}
}
}
return im;
}
image cvmat_to_image(cv::Mat m)
{
IplImage ipl = m;
image im = cvipl_to_image(&ipl);
rgbgr_image(im);
return im;
}
もうここまで来たんだから無駄なことを考えないで