First, the preface
This article mainly uses the YOLO V2 to train own license plate picture data, and can frame the license plate area which exists in the test picture, also is the license plate detection. This article refers to Bowen http://m.blog.csdn.net/qq_34484472/article/details/73135354 and http://blog.csdn.net/zhuiqiuk/article/details/72722227.
Ii. Preparatory work
First you need to download the properly configured darknet, use the./darknet detect cfg/yolo.cfg yolo.weights command to get the test results. This article is mainly to detect the license plate area, under the Darknet new Folder Plate_imgae, which holds train and Val, pic Three folders, train folder for 1296 training pictures, Val folder under 196 photos, Pic is a 236-piece image to be tested, the image format is JPG format, the training model is mainly used in the train and Val two folders.
third, the production of label documents
YOLO v2 Use VOC format data set, so here first needs to the training set and validation set of the picture to annotate, each picture can get the corresponding XML file, and then the XML file into txt tag file. Reference here http://blog.csdn.net/jesse_mx/article/details/53606897 installation Marking tool labelimg, after the installation completes. labelimg.py Open the Annotation tool, first annotate the picture in the Train folder, and create a new Train_xml folder under the Plate_image folder for the generated XML file. The resulting XML file looks like this:
In the same way, create a new Val_xml folder under the Plate_image folder and save the XML annotation file for the validation set. This is the VOC format labeled XML file, the next need to convert the XML file to TXT file, using Python conversion, the train_xml in the XML file, converted to txt saved in the folder Train_txt; Similarly, the Val_ XML files in XML are converted and saved in the Val_txt folder
Import xml.etree.ElementTree as ET import pickle import os from OS import Listdir, getcwd from Os.path import join Xml_label_dir = ' Train_xml ' #需转换的xml路径 txt_label_dir = ' train_txt/' #转换得的txt文件保存路径 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) if isn't os.path.exists (txt_label_dir): Os.makedirs (Txt_label_dir) for rootdir,dirs,files in Os.walk (Xml_label_dir): For file in files:file_name = File.split ('. ')
[0] out_file = open (txt_label_dir+ '%s.txt '% (file_name), ' w ') In_file = open ("%s/%s"% (rootdir,file)) Tree = Et.parse (in_file) root = tree.getroot () size = root.find (' size ') w = int (size. Find (' width '). text h = Int (size.find (' height '). TeXT) for obj in Root.iter (' object '): Xmlbox = Obj.find (' bndbox ') b = (Floa T (Xmlbox.find (' xmin '). Text), Float (xmlbox.find (' Xmax '). Text), Float (xmlbox.find (' ymin '). Text), Float (Xmlbox.find ( ' Ymax '). BB = Convert ((w,h), b) Out_file.write ("0" + "" + "". Join ([Str (a) for a in BB] + ' \ n ') #only one class,index 0 out_file.close ()
Then you need to get the absolute path train_imgae_path.txt of the training set picture and the absolute path val_image_path.txt of the validation set, using the following Python code
Import Xml.etree.ElementTree as ET
import pickle
import OS
from OS import Listdir, getcwd from
Os.path im Port join
traindir = '/home/jyang/darknet/plate_image/train '
out_file = open (' Train_image_path.txt ', ' W ') For
Root,dirs,files in Os.walk (traindir): For
file in Files:
out_file.write ('%s/%s\n '% (root,file))
Out_file.close ()
Yolo is to find the corresponding tag file directly by replacing the suffix name of the absolute path of the original picture. For example, the absolute path of the original picture is/home/ubuntu/data/train/1.jpg. The YOLO will directly assume that its corresponding tag file path is/home/ubuntu/data/train/1.txt. Therefore, we will be generated before the TXT file to the corresponding picture path, will be train_txt under the TXT file into the train folder, the Val_txt under TXT file into the Val folder
See what's under the Plate_image.
Iv. Modifying the configuration file
(1) Create names files
In the YOLO home directory, under the Data folder, create a. names file, the file name is arbitrary, my is myclass.names, write all categories in the file name, each class, I only detect the license plate, so only in the first line to write licence.
(2) Modify the data file
Modify the Cfg/voc.data file in the Darknet home directory, as follows:
classes= 1 #只有一个类别
train =/home/jyang/darknet/plate_image/train_image_path.txt #训练集的绝对路径
Valid =/home/jyang/darknet/plate_image/val_image_path.txt #验证集的绝对路径
names = Data/myclass.names
Backup =/home/jyang/darknet/plate_image/backup #训练得的模型保存路径
(3) Modify the CFG file
Modify the Cfg/yolo-voc.cfg in the Darknet home directory.
1.[region] Layer classes change to 1
2.[region] layer above the [convolution] layer, the number of filters is changed to (classes+coords+1) *num. I changed it to (1+4+1) *5=30.
v. Modification of SRC/YOLO.C documents
1. Change the 13th line to char *voc_names[] = {"Licence"}; If you're a class, change it, if you have multiple classes, change your own according to your needs.
2. Line No. 322 draw_detections function, the last parameter from 20 to your number of categories, I here is 1
3. In the No. 354 line of the demo function, the last third parameter is changed from 20 to your number of categories, I am here 1
4. Change the 17th line to char *train_images = "< your path >/train_imgae_path";
5. The 18th line is changed to char *backup_directory = "Your Path/backup/";
6. Change the 121th line to char *base = "Results/comp4_det_test_"
7. The 123th line is changed to list *plist = Get_paths ("< Your path >/val_image_path.txt");
8. Change the No. 209 line to char *base = "Results/comp4_det_test_"
9. The No. 210 line is changed to list *plist = Get_paths ("< Your path >/val_image_path.txt");
10. In the Src/yolo_kernels.cu file, the 62nd line draw_detections function to the last parameter from 20 to your number of categories, I am here 1.
11.scripts/voc_label.py file, the position of the 9th line changed to: classes=["licence"], because I have only one class
12. In the src/detector.c file, change the No. 372 line to list *plist = Get_paths ("< Your path >/val_image_path.txt");, line No. 542 Option_find_ The last parameter of the INT function is changed from 20 to 1.
vi. recompilation of darknet Yolo
Enter Darknet home directory, make clean after make-j8
vii. Download pre-training documents cfg/darknet19_448.conv.23
To speed up the training, download the official pre-training model and save it under the CFG. Download address for
http://pjreddie.com/media/files/darknet19_448.conv.23
Viii. Training
To run the command under the Darknet folder path:
./darknet Detector Train Cfg/voc.data cfg/yolo-voc.cfg cfg/darknet19_448.conv.23
The system defaults to iterate 45,000 times batch, if you need to modify the number of training, enter cfg/yolo_voc.cfg modify Max_batches value.
Nine, the training process output log
For reference from this article Http://blog.csdn.net/renhanchi/article/details/71077830?locationNum=13&fps=1, the following excerpt from this article
Region AVG IOU: This is the intersection of the predicted bbox and the actual callout bbox divided by their set. Obviously, the bigger the number, the better the predictions.
Avg Recall: This indicates an average recall rate, meaning that the number of objects is detected divided by the number of objects that are labeled.
Count: The number of all objects that are annotated. If Count = 6, recall = 0.66667, that means a total of 6 objects (which may contain different categories, regardless of category), then I predict 4, so recall is 4 divided by 6 = 0.66667
One line is different from the above, the first is the number of iteration, then the train loss, then the AVG train loss, then the learning rate, then a batch processing time, and then the total number of pictures have been processed. Focus on train loss and AVG train loss, these two values should be gradually reduced as the iteration increases. If the loss increases to hundreds of that is the training divergence, if loss in a period of time, it is necessary to reduce learning rate or change batch to enhance the learning effect. Of course, it may be that training is already sufficient. This needs to be judged by itself.
10. Evaluate the training model
Training for 3 days, got the iteration 30,000 weights, generated under the plate_image/backup/yolo-voc_30000.weights, of course, there are other iterations of the weights, use the following statement to test a single picture
./darknet detector Test Cfg/voc.data cfg/yolo-voc.cfg plate_image/backup/yolo-voc_30000.weights plate_image/pic/ 099999.jpg
The test results shown are
The training set is used to evaluate the test performance before the validation set is used. Use the following directives to evaluate
root@computer:/home/jyang/darknet#./darknet Detector recall Cfg/voc.data cfg/yolo-voc.cfg plate_image/backup/ Yolo-voc_30000.weights
According to the 2nd post of reference, when using this instruction, the Validate_detector_recall function in SRC/DETECTOR.C is invoked, the threshold is modified from 0.001 to 0.25, the number of boxes is not recognized, and 432 lines of code are modified as follows:
fprintf (stderr, "id:%5d correct:%5d total%5d\trps/img:%.2f\tiou:%.2f\trecall:%.2f%%\tprecision:%.2f%%\n", I,
Correct, Total, (float) proposals/(i+1), Avg_iou*100/total, 100.*correct/total, 100.*correct/proposals);
After re-make, the result is:
Visible 196 Pictures, accuracy rate of more than 97%.
Conclusion
This article only uses the YOLO v2 to examine the license plate, the follow-up to the box the license plate picture to identify, please see "YOLO V2 license plate detection Subsequent recognition character (i)"