# 【Darknet】複数枚のpredictions
をまとめて取得する
# 経緯
複数枚のテストをしたいとき、predictions.jpg
が上書きされるため、一度にすべての検出画像を取得できません。
shell、bat などで自動化して、一枚ずつ〔実行・リネーム〕の工程を繰り返しても、毎回ネットワークを構築する時間がかかって遅くなってしまいます。
predictions.jpg
に上書きされるのが問題なので、内部を書き換えてファイル名で保存するようにしました。
# 変更箇所
detector.c
内のtest_detector()
の中身を変更します。
1346行目(2020 / 02 / 02現在)のsave_image(im, "predictions")
の下に以下のコードを追加します。
/* please change according to your environment. */
// export root path. (specified directory need to create before execute.)
char* rootPath = (char*)"prediction-results";
/* -------------------------------------------- */
// replace all backslash to slash. ('\\' -> '/')
char* target = input;
int i;
for (i = 0; target[i] != '/'; i++) {
if (target[i] == '\\')
target[i] = '/';
}
// get filename.
char* fname = strrchr(target, '/');
// calc length, allocate memory.
int len = strlen(fname);
char* buf = (char*)calloc(len, sizeof(char));
// delete extension of filename. (xx.jpg -> xx)
for (i = 1; i < len; i++) {
if (fname[i] == '.')
break;
buf[i - 1] = fname[i];
}
// calc length of exportPath.
len = strlen(buf) + strlen(rootPath) + 1;
char* exportPath = (char*)calloc(len, sizeof(char));
sprintf(exportPath, "%s/%s", rootPath, buf); // format
// whether predictions image can save.
save_image(im, exportPath);
printf("\nSave to %s.jpg\n\n", exportPath);
画像の保存先のディレクトリを変更したい場合は、ディレクトリ名を変更します。
char* rootPath = (char*)"prediction-results";
NOTE
指定したディレクトリは、あらかじめ作成しておく必要があります。
ディレクトリがない場合は、保存されません。
# リビルド
変更を適用するために、もう一度ビルドします。
# 実行
list.txt
には、テスト画像のパスを列挙します。
darknet detector test <data> <cfg> <weights> < list.txt -dont_show
# OR
darknet detector test <data> <cfg> <weight> [img_path]
# まとめ
最近Pythonばっかり書いているのもあって、C言語でファイル名の区切りだとかを書くのは正直めんどくさかったです。
やっぱりDarknet書いてる人頭おかしい。
ソースコードはGistにも置いています。
https://gist.github.com/kazuya0202/1576a0cbfdc3b2a67798f8d2e3157f24 (opens new window)
初めまして Darknetをgoogle colab上実行し、predectionsを複数取得したいと思い参考にさせていただきました。お伺いしたいのですが、
detector.c内にコードを追加し、txtファイルでパスを記述したのですが、darknetで実行すると Enter Image Path: Cannot load imageと出力されてしまい、物体の検出ができません。"prediction-results"には一応出力されているのですが、画像の読み込みできません。
txtファイル内のpathは /content/drive/My Drive/darknet/test/画像名.jpgとなっています。
大変失礼ですが、入力するファイルのpathはどのように記述されましたか?
追記
txtファイルの最終行の改行をなくすと最終行の画像のみ検出できました。
@KT-20742 さん
コメントありがとうございます。
大変失礼ですが、入力するファイルのpathはどのように記述されましたか?
環境は Windows でしか検証していないので、Windows での例ですが以下のように絶対パスで指定しています。
D:\workspace\data\img\img_001.jpg
D:\workspace\data\img\img_002.jpg
D:\workspace\data\img\img_003.jpg
...
txtファイル内のpathは /content/drive/My Drive/darknet/test/画像名.jpgとなっています。
/content/drive/My Drive/darknet/test/画像名.jpg
のパスであれば、google colab で絶対パスでの指定になっているので問題ないと思います。
ただ、これで実行できていないということなので、【追記】も踏まえたうえで、はっきりとはわからないのですがいくつか原因を考えてみました。
① パスを列挙したファイルをローカルで作成した
google colab は Linux なので、Windows などの改行コードとは違うのが原因でパスを正しく判断できてない可能性が一番高いと思います。そのため、最終行の改行をなくした場合うまくいったのではないかと思います。
以下の1、2のどちらかを行ってから再度 test コマンドを実行してみてください。
-
ローカルで作成した txt ファイルの改行コードを
LF
(Linuxの改行コード)に変更してから保存する -
google colab 上で txt ファイルを作成する
-
find
コマンドを利用して作成。(darknet
を実行するディレクトリで実行)※ 以下のコードは拡張子が
.jpg
のファイルのみを取得します。!find /content/drive/My Drive/darknet/test/*.jpg -maxdepth 1 -type f > list.txt
-
② txtファイルに記述したパスが間違っている(ファイルが存在しない)
この可能性は低いとは思いますが、google colab 上で表示できるかどうか1枚だけ確認してみるのがいいと思います。
from IPython.display import Image, display_jpeg
display_jpeg(Image('/content/drive/My Drive/darknet/test/[任意の画像名].jpg'))
③ パスに空白が含まれている
こちらに関しては、Windows上で試してみたところ、パスに空白があること自体に関係はなかったので可能性としては低いと思いますが、パスをダブルクォーテーションで囲むことで解決するかもしれません。
上記の3つのどれかで解決しない場合は、再度コメントを頂ければと思います。
大変詳細かつ丁寧に説明いただき感謝致します。
問題については説明いただいた方法で解決しました。
➀に示していただいたコマンドを実行したところ、
find: ‘/content/drive/My’: No such file or directory
find: ‘Drive/darknet/test/*.jpg’: No such file or directory
となってしまいました。相対パスにして(test/~)で実行すると作成できました。これを使い実行すると無事全ファイル検出できました。
cd、➁のコマンドではファイルを読み込めるのですが、ダブルクォーテーション等で括っても絶対パスが通らないのはMy Driveの表記が原因になっている気がします...
大変丁寧に説明いただき勉強になりました。
ありがとうございました。