YOLO의 Tensorflow버전인 Darkflow를 사용해보겠습니다.
Darkflow란?
기본 YOLO는 C를 기반으로 작성되었습니다. 이를 Tensorflow으로 작성된것이 darkflow입니다.
YOLO에 대한 설명과 사용법은 ☞여기☜에 작성했습니다.
darkflow 깃허브 : https://github.com/thtrieu/darkflow
실행 환경
UBUNTU |
16.04 |
CUDA_VERSION |
9.1.85 |
CUDNN_VERSION |
7.1.2.21 |
OpenCV |
3 |
Python |
3 |
Tensorflow |
1.0 |
labeling
이미 Darknet으로 라벨링 한 분들은 다시 라벨링을 할 필요 없이 아래의 코드를 사용하면 (.txt) 에서 (.xml)로 변환됩니다.
코드출처 : https://murra.tistory.com/category/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D%20/YOLO
▼ Darknet(YOLO) Annotations (txt) to Darkflow Annotations (xml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | from lxml import etree from PIL import Image import csv import os IMG_PATH = "D:/__Project__/darkflow-master/data/train_traffic_light" fw = os.listdir(IMG_PATH) # path of save xml file save_path = 'D:/__Project__/darkflow-master/data/annotations/' # txt_folder is txt file root that using darknet rectbox txt_folder = 'D:/__Project__/darkflow-master/data/train_traffic_light_TXT' # edit ypur label set labels = ['traffic light'] def csvread(fn): with open(fn, 'r') as csvfile: list_arr = [] reader = csv.reader(csvfile, delimiter=' ') for row in reader: list_arr.append(row) return list_arr def convert_label(txt_file): if((txt_file[0]) == str(0)): label = 'traffic light' return label # core code = convert the yolo txt file to the x_min,x_max... def extract_coor(txt_file, img_width, img_height): x_rect_mid = float(txt_file[1]) y_rect_mid = float(txt_file[2]) width_rect = float(txt_file[3]) height_rect = float(txt_file[4]) x_min_rect = ((2 * x_rect_mid * img_width) - (width_rect * img_width)) / 2 x_max_rect = ((2 * x_rect_mid * img_width) + (width_rect * img_width)) / 2 y_min_rect = ((2 * y_rect_mid * img_height) - (height_rect * img_height)) / 2 y_max_rect = ((2 * y_rect_mid * img_height) + (height_rect * img_height)) / 2 return x_min_rect, x_max_rect, y_min_rect, y_max_rect for line in fw: root = etree.Element("annotation") # try debug to check your path img_style = IMG_PATH.split('/')[-1] img_name = line image_info = IMG_PATH + "/" + line img_txt_root = txt_folder + "/" + line[:-4] txt = ".txt" txt_path = img_txt_root + txt txt_file = csvread(txt_path) ###################################### # read the image information img_size = Image.open(image_info).size img_width = img_size[0] img_height = img_size[1] img_depth = Image.open(image_info).layers ###################################### folder = etree.Element("folder") folder.text = "%s" % (img_style) filename = etree.Element("filename") filename.text = "%s" % (img_name) path = etree.Element("path") path.text = "%s" % (IMG_PATH) source = etree.Element("source") ##################source - element################## source_database = etree.SubElement(source, "database") source_database.text = "Unknown" #################################################### size = etree.Element("size") ####################size - element################## image_width = etree.SubElement(size, "width") image_width.text = "%d" % (img_width) image_height = etree.SubElement(size, "height") image_height.text = "%d" % (img_height) image_depth = etree.SubElement(size, "depth") image_depth.text = "%d" % (img_depth) #################################################### segmented = etree.Element("segmented") segmented.text = "0" root.append(folder) root.append(filename) root.append(path) root.append(source) root.append(size) root.append(segmented) for ii in range(len(txt_file)): label = convert_label(txt_file[ii][0]) x_min_rect, x_max_rect, y_min_rect, y_max_rect = extract_coor( txt_file[ii], img_width, img_height) object = etree.Element("object") ####################object - element################## name = etree.SubElement(object, "name") name.text = "%s" % (label) pose = etree.SubElement(object, "pose") pose.text = "Unspecified" truncated = etree.SubElement(object, "truncated") truncated.text = "0" difficult = etree.SubElement(object, "difficult") difficult.text = "0" bndbox = etree.SubElement(object, "bndbox") #####sub_sub######## xmin = etree.SubElement(bndbox, "xmin") xmin.text = "%d" % (x_min_rect) ymin = etree.SubElement(bndbox, "ymin") ymin.text = "%d" % (y_min_rect) xmax = etree.SubElement(bndbox, "xmax") xmax.text = "%d" % (x_max_rect) ymax = etree.SubElement(bndbox, "ymax") ymax.text = "%d" % (y_max_rect) #####sub_sub######## root.append(object) #################################################### file_output = etree.tostring(root, pretty_print=True, encoding='UTF-8') # print(file_output.decode('utf-8')) ff = open('%s%s.xml' % (save_path, img_name[:-4]), 'w', encoding="utf-8") ff.write(file_output.decode('utf-8')) | cs |
사용법
pip가 등록된 패키지가 아니므로 git을 사용해 다운받아야합니다.
https://github.com/thtrieu/darkflow.git cd darkflow python3 setup.py build_ext --inplace pip install . | cs |
현재 yolov3는 지원하지 않습니다. Issue #665
1. label.txt 수정
./label.txt의 내용을 해당 classes로 수정한다.
diseased | cs |
2. ./cfg/yolo.cfg 수정
사용할 cfg파일을 복사해 다른이름으로 저장
convolutional의 filter = (archors+class)*num 로 변경
yolo 레이어의 classes를 수정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [convolutional] size=1 stride=1 pad=1 filters=425 activation=linear [region] anchors = 0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, 9.77052, 9.16828 bias_match=1 classes=80 coords=4 num=5 softmax=1 jitter=.3 rescore=1 | cs |
(1) CUDA_VISIBLE_DEVICES=2 python 자체로 GPU사용해서 돌리기
(2) 학습할 때 --train 꼭 사용
(3) --dataset ./data/corn_img/ 에 이미지 사진 폴더 위치(.jpg .png)
CUDA_VISIBLE_DEVICES=2 python3 flow \ --model ./cfg/my-yolo.cfg \ --labels ./labels.txt \ --dataset ./data/corn_img/ \ --annotation ./data/annotation_corn/ \ --train \ --trainer adam \ --batch 5 \ --epoch 100 \ --save 50 \ --keep 5 \ --lr 1e-04 \ --gpu 0.9 \ --load -1 --summary ./logs \ --gpuName /gpu:2 \ --savepb True \ | cs |
detect
(2) --threshold 0.5 임계값 설정해서 0.5이상만 표시
python3 flow \ --imgdir ./sample_img/ttt/ \ --model ./cfg/my-tiny-yolo.cfg \ --load -1 \ --batch 1 \ --threshold 0.5 | cs |
참고
flow --help
Example usage: flow --imgdir sample_img/ --model cfg/yolo.cfg --load bin/yolo.weights Arguments: --help, --h, -h show this super helpful message and exit --imgdir path to testing directory with images --binary path to .weights directory --config path to .cfg directory --dataset path to dataset directory --labels path to labels file --backup path to backup folder --summary path to TensorBoard summaries directory --annotation path to annotation directory --threshold detection threshold --model configuration of choice --trainer training algorithm --momentum applicable for rmsprop and momentum optimizers --verbalise say out loud while building graph --train train the whole net --load how to initialize the net? Either from .weights or a checkpoint, or even from scratch --savepb save net and weight to a .pb file --gpu how much gpu (from 0.0 to 1.0) --gpuName GPU device name --lr learning rate --keep Number of most recent training results to save --batch batch size --epoch number of epoch --save save checkpoint every ? training examples --demo demo on webcam --queue process demo in batch --json Outputs bounding box information in json format. --saveVideo Records video from input video or camera --pbLoad path to .pb protobuf file (metaLoad must also be specified) --metaLoad path to .meta file generated during --savepb that corresponds to .pb file | cs |
'Capstone > 2019-1 Capstone' 카테고리의 다른 글
⑦ TCP 통신 (0) | 2019.06.21 |
---|---|
⑥ Darknet(YOLOv3) (12) | 2019.06.21 |
④ 이미지 수집 & 데이터 불리기 (0) | 2019.05.27 |
③ Docker (0) | 2019.05.20 |
② Capstone 컴퓨터 세팅 (0) | 2019.03.31 |