python,opencvで任意の大きさの面積だけを抽出する

検索してもあんまり出てこなかったりして、右往左往してなんとか書きました。
でももっと効率の良い書き方があると思いますので知っていたら教えてください、、、

環境

ubuntu16.04
opencv3.4
python3.5

プログラム
import cv2
import numpy as np

frame = cv2.imread("img.png")
height = frame.shape[0]
width = frame.shape[1]

img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#2値化
thresh = 40
max_pixel = 255
ret, img_dst = cv2.threshold(img_gray,
                             thresh,
                             max_pixel,
                             cv2.THRESH_BINARY)
#指定領域面積のみ抽出                             
dst = np.zeros((height, width, 1), np.uint8)
connectivity = 4
min_area=100
max_area=10000
output = cv2.connectedComponentsWithStats(img_dst, connectivity, cv2.CV_32S)
for i in range(output[0]):
    if output[2][i][4] >= min_area and output[2][i][4] <= max_area:
        cv2.rectangle(dst, (output[2][i][0], output[2][i][1]), (
            output[2][i][0] + output[2][i][2], output[2][i][1] + output[2][i][3]), (255, 255, 255), -1)
res = cv2.bitwise_and(dst,img_dst)


cv2.imshow("gray", img_dst)
cv2.imshow("frame", frame)
cv2.imshow("result", res)

k = cv2.waitKey(0)


cv2.destroyAllWindows()

RealSenseSDK2で任意の場所の距離を取得する

距離を自由に扱いたいので、まず任意の場所の距離を取得したいと思います。
今回は画像の真ん中の座標の距離を取得します。

#include <stdio.h>
#include <librealsense2/rs.hpp> // Include RealSense Cross Platform API
#include <opencv2/opencv.hpp>   // Include OpenCV API

int main(int argc, char * argv[]) try
{
    // Declare depth colorizer for pretty visualization of depth data
    rs2::colorizer color_map;

    // Declare RealSense pipeline, encapsulating the actual device and sensors
    rs2::pipeline pipe;
    // Start streaming with default recommended configuration
    pipe.start();

    using namespace cv;
    const auto window_name = "Display Image";
    namedWindow(window_name, WINDOW_AUTOSIZE);
    float pixel_distance_in_meters;
    while (waitKey(1) < 0 && cvGetWindowHandle(window_name))
    {
        rs2::frameset data = pipe.wait_for_frames(); // Wait for next set of frames from the camera
        rs2::frame depth = color_map(data.get_depth_frame());
        rs2::depth_frame depth_point = data.get_depth_frame();

        // Query frame size (width and height)
        const int w = depth.as<rs2::video_frame>().get_width();
        const int h = depth.as<rs2::video_frame>().get_height();

        // Create OpenCV matrix of size (w,h) from the colorized depth data
        Mat image(Size(w, h), CV_8UC3, (void*)depth.get_data(), Mat::AUTO_STEP);

        //get depth
        //画像の真ん中のxy座標の距離を取得
        pixel_distance_in_meters = depth_point.get_distance(w/2,h/2);
        std::cout << pixel_distance_in_meters  << std::endl;

        // Update the window with new data
        imshow(window_name, image);
    }

    return EXIT_SUCCESS;
}
catch (const rs2::error & e)
{
    std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n    " << e.what() << std::endl;
    return EXIT_FAILURE;
}
catch (const std::exception& e)
{
    std::cerr << e.what() << std::endl;
    return EXIT_FAILURE;
}

RealSenseSDK2のプログラムをコンパイルする

RealSenseSDK2のサンプルを引っこ抜いて自分用に改造するためにした作業です。

環境

ubuntu16.04 kernel 4.4.0-130-generic
opencv3.4
 


開発パッケージ入手とインストール

GitHub - IntelRealSense/librealsense: Intel® RealSense™ SDK
ここからダウンロードもしくはgit cloneする
次に開発パッケージの入手

sudo apt-get install librealsense2-dev
sudo apt-get install librealsense2-dbg

以下参考HPを見ていたらcmake3.8.x以上が必要とのこと。
自分の環境ではcmakeバージョンが低いので以下を参考にして上げた。
デプスカメラRealSenseD435で "紫色のイカ" や "オレンジ色の玉ねぎ" を切り取ったり "金髪の人" を追っかけて距離を測る(1) with Ubuntu16.04
ここの「RealSenseとOpenCVの連携サンプルをビルド」の項目を参照
 
次にcmakeしてインストールする

cd
cd librealsense
mkdir build
cd build
cmake  ../ -DBUILD_EXAMPLES=true  -DBUILD_CV_EXAMPLES=true
make
sudo make install

(ホームにlibrealsenseとして展開している前提のコマンド)
ビルドのオプションは以下を参考。
Build Configuration · IntelRealSense/librealsense Wiki · GitHub
本当はpythonも入れたかったけど入らなかった。。。

rs-capture

にて動作するか確認。

自分用に改造するためにmakeが通るか確認

サンプルに何があるかは以下を参照する
librealsense/examples at master · IntelRealSense/librealsense · GitHub
 
まず、librealsenseを解凍したフォルダのexamples/captureを自分の作業したところにコピーする
次にexamples/third-partyもcaptureと同じフォルダにコピーしてくる
コマンドで

g++ rs-capture.cpp -o rs-capture.out -std=c++14 -I/home/librealsense/include/  `pkg-config --static --libs gl` `pkg-config --static --libs glew` -lglfw -lgomp -ljpeg  -L/usr/local/lib -lrealsense2
./rs-capture

これで起動確認
 
自分はglewが無いと怒られたので以下をインストール

sudo apt-get install libglew-dev

 
次にOpencvを用いたキャプチャをコンパイルしてみる
librealsense/wrappers/opencv/imshowをコピーしてくる

g++ rs-imshow.cpp -o rs-imshow.out -std=c++14 -I/home/librealsense/include/  `pkg-config --static --libs gl` `pkg-config --static --libs glew` `pkg-config --libs --cflags opencv` -lglfw -lgomp -ljpeg  -L/usr/local/lib -lrealsense2
./rs-imshow

で起動確認
f:id:weekendproject9:20180802193546p:plain
 
次回から少しずついじっていく予定
終わり

 

realSenseの環境構築とサンプル実行

Intel® RealSense™ Depth Camera D435を買ったので動かすまでのメモ
https://click.intel.com/intelr-realsensetm-depth-camera-d435.html
f:id:weekendproject9:20180802183355p:plain

[環境]
ubuntu16.04 kernel 4.4.0-130-generic

Realsenseインストール作業

自分の環境の確認

github.com
とにかくここを見る

ubuntuの人はInstallのところのLinuxへ行く
- ubuntバージョンとカーネルの確認
 2018/08/02現在
 >> Ubuntu LTS kernels 4.4, 4.10, 4.13  <<
 となっている。
 コマンドでは uname -a で自分のバージョンを確認できる

ちなみにopencvと連携して使い人は以下の一番下を確認 
 librealsense/wrappers/opencv at master · IntelRealSense/librealsense · GitHub
 2018/08/02現在ではopencv3.4で使える模様
 (このブログの下の方に3.4インストールの手順を記述)

SDKインストール作業

librealsense/distribution_linux.md at master · IntelRealSense/librealsense · GitHub
基本的にはここを見る。
しかし最新版になったり更新されると当然コマンドが変わったりキーが変わるので注意。

sudo apt-key adv --keyserver hkp://keys.gnupg.net:80 --recv-key C8B3A55A6F3EFCDE
sudo add-apt-repository "deb http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo xenial main" -u
#サンプル入手
sudo apt-get install librealsense2-dkms
sudo apt-get install librealsense2-utils

もし昔のrealsemseのバージョンが入っている人は事前に削除しておく。
サンプルを手に入れたらD435をPCに繋いで

realsense-viewer

これで動くのを確認

Opencv3.4インストール

1.
OpenCV 3.4 - OpenCV library
The source code for all platforms can be downloaded from GitHub:のところからzip入手
Release 3.4.0 · opencv/opencv_contrib · GitHub
zip入手

2.
homeにopencvという名前のフォルダを作成してDLした2つのファイルを解凍して入れる

3.

cd
cd opencv
mkdir build
cd build

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=~/opencv/opencv_contrib-3.4.0/modules  -D BUILD_NEW_PYTHON_SUPPORT=ON -D PYTHON_EXECUTABLE=/usr/bin/python3.5 -D BUILD_opencv_python3=ON -D BUILD_opencv_python2=ON -D WITH_V4L=ON -D WITH_VTK=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -D WITH_OPENGL=ON -D WITH_CUDA=ON  ..

自分はpythonも使うのでcmake結果に出てくるpythonの項目がきちんとなっているかを確認した。
また、pythonのバージョンが違う人はPYTHON_EXECUTABLEの項目を変える

make -j  4
sudo make install
sudo /bin/bash -c ‘echo “/usr/local/lib” > /etc/ld.so.conf.d/opencv.conf’
sudo  ldconfig

おわり

DC-DCモジュール ステップアップを試してみる(2~24V→5~28V)

USBやリポなどの1セルから任意の電圧に昇圧するDCDCを買ったので電圧を確認しました。
今回買ったのは以下の物になります。
f:id:weekendproject9:20180727215004p:plain
www.denshi-trade.co.jp

モジュールにUSBをさして電圧を確認すると4.97V付近でした。
次に半固定抵抗のボリュームを時計周りに回したのですが、全然電圧が動かなくて、あれ?と思いましたが、次第に昇圧されていきました。
感覚ですが20回程度回したあたりから変動しました。


これも同じのかな?
ja.aliexpress.com

おわり

darknetでYoLoV3マルチクラス学習

Yolov3を多クラス学習したときのメモ。
といっても、サイトに手順書いてあるし、前回のyolov2とほぼ同じ。

Darknetサイト

YOLO: Real-Time Object Detection
 

注意

2018年4月30日現在、OpenCV 3.4.1以上はmakeできない
 

まず最新のdarknetを取得

$ git clone https://github.com/pjreddie/darknet
$ cd darknet

makefileを開き、自分の環境に合わせる
例:
 GPU=1
 CUDNN=1
 OPENCV=1
 OPENMP=0
 DEBUG=0

$ make

 

学習済みモデルのダウンロード

Darknetのサイト、”Download Pretrained Convolutional Weights”の項目からhere (76 MB).をクリックして
darknet53.conv.74をダウンロードする。
 

学習の準備

前回の学習ブログと同様で学習させたいデータ(画像・ラベル)を準備する。
同じやり方で大丈夫。もうある人は画像フォルダや設定ファイルをもってくれば使えます。
しかし、“・darknetで学習“の項目から編集が必要です。
・darknet/cfgの”obj.data”は以前と同様
・cfg/yolo-obj.cfgは編集する必要あり


 1.yolov3-voc.cfgをコピーしてyolo-obj.cfgに名前を変更
 2. 3行目 batch=1 を64に変更。4行目 subdivisions=1 を8に変更
 3..cfg内の[yolo]の項目を検索して、その一つ上の[convolutional]の項目内、filtersを filters=(classes + 5)x3 に変更する(3つある)
 4.各[yolo]内のclassesを自分のクラス数に書き換え
 
[確認]
・学習データ、ラベルをdataフォルダ内のobjフォルダに格納
・data/obj.names、data/objにtrain.txt,test.txtがあるか
・ darknet53.conv.74をdarknet/に保存したか
・darknet/cfgに独自のobj.data,yolo-obj.cfgを用意したか
・darknetフォルダにbackupフォルダがあるか
 

学習開始

./darknet detector train cfg/obj.data  cfg/yolo-obj.cfg darknet53.conv.74

*学習過程で "-nan" が出てくるが学習における82,94,108のどれかで数字が出ていれば学習が進んでいる
 参考→Training IOU, Cass, OBj, etc. = nan ? · Issue #600 · AlexeyAB/darknet · GitHub 
*うまくいかない場合はyolo-obj.cfgの3行目 batch=1 を32に変更。4行目 subdivisions=1 を16に変更(メモリが足らずに落ちる場合も同様)
 それでもうまくいかない場合は、batch=1、 subdivisions=1に戻して学習の挙動を見てみる
 

参考

てかこっちの方が親切でありがたい
github.com

darknetでマルチクラス学習と画像認識

今までtensorflowなどでYoLoV2をしてきましたが、今回は複数の物体判別ができるようにdarknetで多クラスの学習をしようと思います。

参考にしたのは以下の2つのHPです。貴重な情報ありがとうございます。

 

追記(2018_04)

yolov3 の学習はこちら
http://weekendproject9.hatenablog.com/entry/2018/04/30/205622

・環境

 ubuntu16.04
 gtx-1070
 python 2.7
 python 3.5
 opencv 3.1

・darknetのインストール

GitHub - pjreddie/darknet: Convolutional Neural Networks
ここからdarknetをダウンロード。Makefileを編集。

 GPU=1
 CUDNN=1
 OPENCV=1
 DEBUG=0
 OPENMP=0
 LIBSO=0
 
GPUOPENCVを1に変更。
そしたら、端末で”make”と打って実行。
 
・自分の場合以下のエラーが出ました。 
gcc -DOPENCV `pkg-config --cflags opencv` -DGPU -I/usr/local/cuda/include/ -DCUDNN -Wall -Wfatal-errors -Ofast -DOPENCV -DGPU -DCUDNN -I/usr/local/cudnn/include -c ./src/gemm.c -o obj/gemm.o
In file included from ./src/gemm.c:3:0:
./src/cuda.h:14:26: fatal error: cuda_runtime.h: そのようなファイルやディレクトリはありません
compilation terminated.
Makefile:89: ターゲット 'obj/gemm.o' のレシピで失敗しました
make: *** [obj/gemm.o] エラー 1
 
解決方法は以下のリンクにあるのですが、MakefileのCOMMONとLDFLAGSのCUDAのパスを書き換えることで解消できました。
CUDA8の人は以下のような書き方になります。

 COMMON+= -DGPU -I/usr/local/cuda/include/
 CFLAGS+= -DGPU
 LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
  ↓ ↓ ↓
 COMMON+= -DGPU -I/usr/local/cuda-8.0/include/
 CFLAGS+= -DGPU
 LDFLAGS+= -L/usr/local/cuda-8.0/lib64 -lcuda -lcudart -lcublas -lcurand

problem compiling · Issue #9 · cvjena/darknet · GitHub

・学習したい画像の用意

 *画像に写っているものが何なのかを判別したいときは以下の画像で学習可能です。
f:id:weekendproject9:20180310163519p:plain
 しかし、部屋や街の中のシーン中に何が写っているかを判別したいときは以下ようなの画像を用意する必要があります。
f:id:weekendproject9:20180310163705p:plain
 
以下のプログラムはwebカメラで対象物の画像を保存するものになります。
また、ネットで集めてもいいです。

-- capture.py --

# -*- coding: utf-8 -*-
import numpy as np
import cv2

# webカメラの準備
cap = cv2.VideoCapture(0)
i=0
while(True):
	# フレームをキャプチャする
	ret, frame = cap.read()

	# 画面に表示する
	cv2.imshow('frame',frame)

	# キーボード入力待ち
	key = cv2.waitKey(1) & 0xFF

	# qが押された場合は終了する
	if key == ord('q'):
		break
	# sが押された場合は保存する
	if key == ord('s'):
		path = str(i) + ".jpg" 
		cv2.imwrite(path,frame)
		i+=1

# キャプチャの後始末と,ウィンドウをすべて消す
cap.release()
cv2.destroyAllWindows()

「操作方法」
 コマンド 「 python capture.py 」 で起動
 キーボード ”s”で1枚保存。画像名の数字は自動で増える
 キーボード ”q”で終了
 

・対象物にクラス名のラベルをつけていく

GitHub - puzzledqs/BBox-Label-Tool at multi-class
BBoxのブランチmulti-classを利用し、画像中の対象物の範囲に枠をつけ、クラス名のラベルをつけていきます。
 
以下手順  
1. main.pyの134行目と152行目の拡張子をJPGからjpgに変更する。
2. BBoxフォルダ内のclass.txtに自分が認識させたいクラス名を書く。以下例:

   car
   human
   pen
   dog
   cat 
3. BBoxのimagesとlabelsの中にフォルダを002の数値で作ります。(別の数字でもいいです。)
4. imagesに作ったフォルダの中に学習させたい画像を移動させます
5. コマンド 「 python2 main.py 」にてBBox起動 (*python2で起動してください)
6. BBox画面上部のimageDirの項目に学習画像を入れたフォルダ名を書いて”Load”をクリック
7. 右上のプルダウンでクラス名を選択して”ComfirmClass”をクリック
8. 領域を左クリックして囲んで、右に出力される結果で間違いなければ下の”Next”をクリック
  (操作を間違ったらDeleteとかClearAllをする)
9.全画像に領域をつけて終了。(NEXTで次の画像にいかないと終了と判断)
10. labelsフォルダ内の自分が作成したフォルダに画像と同じ名前のファイルがあるか確認

・学習データの水増し(必須ではありません)

何千枚、何万枚もの学習データを自分で用意するのは大変なので、プログラムで画像を増やします。
このとき、画像をぼやかしたりやノイズを与えたりしています。
(長いので一番下にプログラム記載(increase_picture.py))
 
1.BBoxのmain,pyと同じところにincrease_picture.pyを置く
2.ImagesとLabelsフォルダ内に"output"というフォルダを作成
3.コマンド 「 python increase_picture.py Images/002 Labels/002 」 (自分のフォルダ名に合わせる)
4.画像が水増しされており、元画像に加工がされているのを確認

 

・学習用データの変換

BBoxは領域とラベルをつけるだけなので、これをdarknetで学習できる形に変換します。
darknet/convert.py at master · Guanghan/darknet · GitHub
ここのプログラムを元に多クラス用に書き換えました。(長いので一番下にプログラム記載(convert.py))
1.BBoxフォルダ一番上の階層に”convert.py”でプログラムを作ります
2.BBoxフォルダ一番上の階層に"convertLabels"というフォルダを作って中に"train"フォルダを作ります
3.コマンド 「 python convert.py 」 で変換します
4.結果をconvertLabels/train内のテキストを見て、下のように一番左にクラス番号、その後に枠の座標値が割合で書かれているのを確認します

 データの並び:【カテゴリ番号 オブジェクトの中心x座標  オブジェクトの中心y座標  オブジェクトの幅  オブジェクトの高さ】
 出力結果例 : 0      0.59609375      0.16041666666666665   0.3484375   0.2791666666666667
 

・darknetで学習

1.darknetフォルダのdata内に”obj”フォルダを作成
2.How to train YOLOv2 to detect custom objects
  からprocess.pyを持ってきてobjフォルダに置く
3.objフォルダにBBOXフォルダのimages/outputの画像たちをobjフォルダにコピー
4.コマンド 「 python process.py 」 を起動させて、test.txt(評価用)とtrain.txt(学習用)ができているのを確認
5.BBoxフォルダ内のconvertLabels/train内のテキスト達をdarknet/data/obj内にコピー
6.darknet/data内に"data.names"を作成後、自分の学習させるクラス名を記入(BBoxフォルダのclass.txtの中身と一緒)

   car
   human
   pen
   dog
   cat 
7.darknet/cfgに”obj.data”を作成。中身は以下のようにする
 classes= 5
 train = data/obj/train.txt
 valid = data/obj/test.txt
 names = data/obj.names
 backup = backup/
ここでclasses= 5 は学習させるクラスの数なので自分の数値に合わせる。今回の例だと5になる。
8.darknetフォルダ内に学習結果を保存するための”backup”フォルダを作成
9.darknet/cfg/yolo-obj.cfgの内容を編集しますが、以下参考HPの内容をそのまま記述させていただきます。

cfg/yolo-obj.cfgはもとからcfgディレクトリの中にある.cfgファイルをコピーしてちょっと編集してyolo-obj.cfgとします。今回はyolo-voc.cfgファイルをコピーして使いますが、他のモデル(tiny-yolo.cfg等)が使いたかったら適宜変えてください。
コピーしてリネームしたyolo-obj.cfgを少し編集します。
3行目:batch=64 にします。学習ステップごとに使い画像の枚数です。
4行目:subdivisions=8 にします。バッチが8で除算されます。強力なGPUを積んでればこれを減らすか、バッチを増やすことができます。
244行目:classes=1 にします。クラス数です。
237行目:filters=30 にします。フィルターの大きさです。filters=(classes + 5) * 5 と決まっています?
YOLOv2を使って自前のデータを学習させて認識させるまで。 - 可変ブログ

参考HP内容から変更する部分は、”244行目:classes=1” の部分です。ここを自分のクラスの数値にして下さい。(項目の7と同じ数)
また、自分の場合はgtx1070なのでこの設定で学習できますが、もしgtx960、gtx950などのメモリ数が少ない人はメモリが足らないこともあるかと思います。
そうした場合は学習結果が悪くなりますが、以下を変更することでなんとか学習をすることができます。
3行目 batch を32とかに減らす
258行目 random=0 これは画像をいじりながら学習する設定ですが、0にすることで無しにできます。
もっとありますが試したのはこの2つです。
 
10. https://pjreddie.com/media/files/darknet19_448.conv.23 から初期データをダウンロードして,darknetフォルダ内に移動。
11.以下のコマンドで学習開始

 ./darknet detector train cfg/obj.data cfg/yolo-obj.cfg darknet19_448.conv.23
 
 
12.学習ができているか確認
画像を読み込ませて確認
 ./darknet detector test cfg/obj.data cfg/yolo-obj.cfg backup/yolo-obj_***.backup data/testimage.jpg 
                               ↑学習した数値入れる   ↑画像の場所は自分の環境にあわせる

webカメラで確認する場合
 ./darknet detector demo cfg/obj.data cfg/yolo-obj.cfg backup/yolo-obj_***.weights
                                ↑学習した数値入れる
 

・プログラム

・画像の水増し
yoloの画像を生成するまで · GitHub

-- increase_picture.py --

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#

import cv2
import numpy as np
import sys
import glob
import os
import re
import numpy as np
from os import walk, getcwd

# ヒストグラム均一化
def equalizeHistRGB(src):

    RGB = cv2.split(src)
    Blue   = RGB[0]
    Green = RGB[1]
    Red    = RGB[2]
    for i in range(3):
        cv2.equalizeHist(RGB[i])

    img_hist = cv2.merge([RGB[0],RGB[1], RGB[2]])
    return img_hist

# ガウシアンノイズ
def addGaussianNoise(src):
    row,col,ch= src.shape
    mean = 0
    var = 0.1
    sigma = 15
    gauss = np.random.normal(mean,sigma,(row,col,ch))
    gauss = gauss.reshape(row,col,ch)
    noisy = src + gauss

    return noisy

# salt&pepperノイズ
def addSaltPepperNoise(src):
    row,col,ch = src.shape
    s_vs_p = 0.5
    amount = 0.004
    out = src.copy()
    # Salt mode
    num_salt = np.ceil(amount * src.size * s_vs_p)
    coords = [np.random.randint(0, i-1 , int(num_salt))
              for i in src.shape]
    out[coords[:-1]] = (255,255,255)

    # Pepper mode
    num_pepper = np.ceil(amount* src.size * (1. - s_vs_p))
    coords = [np.random.randint(0, i-1 , int(num_pepper))
              for i in src.shape]
    out[coords[:-1]] = (0,0,0)
    return out

if __name__ == '__main__':
    # ルックアップテーブルの生成
    min_table = 50
    max_table = 205
    diff_table = max_table - min_table
    gamma1 = 0.75
    gamma2 = 1.5

    LUT_HC = np.arange(256, dtype = 'uint8' )
    LUT_LC = np.arange(256, dtype = 'uint8' )
    LUT_G1 = np.arange(256, dtype = 'uint8' )
    LUT_G2 = np.arange(256, dtype = 'uint8' )

    LUTs = []

    # 平滑化用
    average_square = (10,10)

    # ハイコントラストLUT作成
    for i in range(0, min_table):
        LUT_HC[i] = 0

    for i in range(min_table, max_table):
        LUT_HC[i] = 255 * (i - min_table) / diff_table

    for i in range(max_table, 255):
        LUT_HC[i] = 255

    # その他LUT作成
    for i in range(256):
        LUT_LC[i] = min_table + i * (diff_table) / 255
        LUT_G1[i] = 255 * pow(float(i) / 255, 1.0 / gamma1)
        LUT_G2[i] = 255 * pow(float(i) / 255, 1.0 / gamma2)

    LUTs.append(LUT_HC)
    LUTs.append(LUT_LC)
    LUTs.append(LUT_G1)
    LUTs.append(LUT_G2)

    wd = getcwd()
    # 画像の読み込み
    iamge_path = sys.argv[1]
    files = glob.glob(iamge_path + '/*.jpg')
    print(files)

    for item_index, file in enumerate(files):
        img_src = cv2.imread(file, 1)

        trans_img = []
        trans_img.append(img_src)

        # LUT変換
        for i, LUT in enumerate(LUTs):
            trans_img.append( cv2.LUT(img_src, LUT))

        # 平滑化
        trans_img.append(cv2.blur(img_src, average_square))

        # ヒストグラム均一化
        trans_img.append(equalizeHistRGB(img_src))

        # ノイズ付加
        trans_img.append(addGaussianNoise(img_src))
        trans_img.append(addSaltPepperNoise(img_src))

        # 反転
        flip_img = []
        for img in trans_img:
            flip_img.append(cv2.flip(img, 1))
        trans_img.extend(flip_img)

        # 保存
        #if not os.path.exists("training_images"):
        #    os.mkdir("training_images")

        base = os.path.splitext(os.path.basename(file))[0] + "_"
        item_txt = os.path.splitext(os.path.basename(file))[0] + '.txt'
        img_src.astype(np.float64)
        for i, img in enumerate(trans_img):
            # 比較用
            # cv2.imwrite("images/003/" + base + str(i) + ".jpg" ,cv2.hconcat([img_src.astype(np.float64), img.astype(np.float64)]))
            #9以下は反転していない
            coordinate = ''
            labels_path = sys.argv[2]

            file = open(labels_path + '/' + item_txt, 'r')
            if i <= 8:
                coordinate = file.read()
            #9以上は反転している
            else:
                line = file.readline()
                coordinate = line

                while line:
                    line = file.readline()
                    words = re.split(" +", line)
                    if len(words) >= 2:
                        x = words[0]
                        y = words[1]
                        width = words[2]
                        height = words[3]
                        class_name = words[4]
                        img_width = img.shape[1]

                        x = int(img_width) - int(width)
                        width = int(img_width) - int(words[0])

                        coordinate = coordinate + ' '.join([
                            str(x).strip(),
                            str(y).strip(),
                            str(width).strip(),
                            str(height).strip(),
                            class_name
                        ]) + '\n'

            file.close()

            f = open("Labels/output/" + base + str(i) + ".txt", 'w')
            f.write(coordinate)
            f.close()

            cv2.imwrite("Images/output/" + base + str(i) + ".jpg" ,img)

 
・学習データ用に変換

-- convert.py --

# -*- coding: utf-8 -*-
"""
Created on Wed Dec  9 14:55:43 2015
This script is to convert the txt annotation files to appropriate format needed by YOLO 
@author: Guanghan Ning
Email: gnxr9@mail.missouri.edu
"""

import os
from os import walk, getcwd
from PIL import Image

classes = ["train"]

def convert(size, box):
    dw = 1./size[0]
    dh = 1./size[1]
    x = (box[0] + box[1])/2.0
    y = (box[2] + box[3])/2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x*dw
    w = w*dw
    y = y*dh
    h = h*dh
    return (x,y,w,h)
    
    
"""-------------------------------------------------------------------""" 

""" Configure Paths"""   
mypath = "Labels/output/"
outpath = "convertLabels/train/"
imgpath = "/Images/output"

cls = "train"
if cls not in classes:
    exit(0)
cls_id = classes.index(cls)

wd = getcwd()
""" GET class text file list """
class_path = "class"
class_file = open('%s/%s.txt'%(wd, class_path), 'r')
class_list = class_file.read().split('\n')   #for ubuntu, use "\r\n" instead of "\n"
print(class_list)

list_file = open('%s/%s_list.txt'%(wd, cls), 'w')

""" Get input text file list """
txt_name_list = []
for (dirpath, dirnames, filenames) in walk(mypath):
    txt_name_list.extend(filenames)
    break
#print(txt_name_list)

""" Process """
for txt_name in txt_name_list:
    # txt_file =  open("Labels/stop_sign/001.txt", "r")
    
    """ Open input text files """
    txt_path = mypath + txt_name
    #print("Input:" + txt_path)
    txt_file = open(txt_path, "r")
    lines = txt_file.read().split('\n')   #for ubuntu, use "\r\n" instead of "\n"
    
    """ Open output text files """
    txt_outpath = outpath + txt_name
    #print("Output:" + txt_outpath)
    txt_outfile = open(txt_outpath, "w")
    
    
    """ Convert the data to YOLO format """
    ct = 0
    for line in lines:
        #print('lenth of line is: ')
        #print(len(line))
        #print('\n')
        if(len(line) >= 2):
            ct = ct + 1
            print(line)
            elems = line.split(' ')
            #print(elems)
            xmin = elems[0]
            xmax = elems[2]
            ymin = elems[1]
            ymax = elems[3]
            class_name = elems[4]
            #print(class_name)
            #
            img_path = str('%s/%s.jpg'%(wd+imgpath,os.path.splitext(txt_name)[0]))
            print("img_path:",img_path)
            #t = magic.from_file(img_path)
            #wh= re.search('(\d+) x (\d+)', t).groups()
            im=Image.open(img_path)
            w= int(im.size[0])
            h= int(im.size[1])
            #w = int(xmax) - int(xmin)
            #h = int(ymax) - int(ymin)
            # print(xmin)
            #print(w, h)
            b = (float(xmin), float(xmax), float(ymin), float(ymax))
            bb = convert((w,h), b)
            #print(bb)
            print('\n')
            i=0
            for class_num in class_list:
               if class_name == class_num:
                 class_id = i
               i+=1
            txt_outfile.write(str(class_id) + " " + " ".join([str(a) for a in bb]) + '\n')

    """ Save those images with bb into list"""
    if(ct != 0):
        list_file.write('%s/images/%s/%s.jpg\n'%(wd, cls, os.path.splitext(txt_name)[0]))
                
list_file.close()