制作VOC2007數(shù)據(jù)集常用代碼

研究背景

由于研究時(shí)常根據(jù)使用情況吹截,制作符合要求的數(shù)據(jù)集,因而將需要的代碼整理瞎抛。

數(shù)據(jù)集結(jié)構(gòu)

└── VOCdevkit #根目錄
└── VOC2012 #不同年份的數(shù)據(jù)集碑幅,這里只下載了2012的,還有2007等其它年份的
├── Annotations #存放xml文件褂萧,與JPEGImages中的圖片一一對(duì)應(yīng),解釋圖片的內(nèi)容等等
├── ImageSets #該目錄下存放的都是txt文件葵萎,txt文件中每一行包含一個(gè)圖片的名稱导犹,末尾會(huì)加上±1表示正負(fù)樣本
│ ├── Action
│ ├── Layout
│ ├── Main
│ └── Segmentation
├── JPEGImages #存放源圖片
├── SegmentationClass #存放的是圖片,分割后的效果羡忘,見下文的例子
└── SegmentationObject #存放的是圖片谎痢,分割后的效果,見下文的例子

  • Annotation文件夾存放的是xml文件卷雕,該文件是對(duì)圖片的解釋节猿,每張圖片都對(duì)于一個(gè)同名的xml文件。
  • ImageSets文件夾存放的是txt文件漫雕,這些txt將數(shù)據(jù)集的圖片分成了各種集合滨嘱。如Main下的train.txt中記錄的是用于訓(xùn)練的圖片集合
  • JPEGImages文件夾存放的是數(shù)據(jù)集的原圖片
  • SegmentationClass以及SegmentationObject文件夾存放的都是圖片,且都是圖像分割結(jié)果圖

參考鏈接制作VOC格式數(shù)據(jù)集
參考鏈接修改xml文件的節(jié)點(diǎn)值方法詳解

代碼實(shí)現(xiàn)

  • 圖片重命名保存在JPEGImages浸间,將原命名數(shù)字+12682太雨,再補(bǔ)0到6位數(shù)字。
import os
path = "/home/henry/File/URPC2018/VOC/VOC2007/JPEG/YDXJ0013"
#path1 = "/home/henry/File/URPC2018/VOC/VOC2007/JPEG/1"
filelist = os.listdir(path) #該文件夾下所有的文件(包括文件夾)
for file in filelist:   #遍歷所有文件
    Olddir=os.path.join(path,file)   #原來的文件路徑
    if os.path.isdir(Olddir):   #如果是文件夾則跳過
        continue
    filename=os.path.splitext(file)[0]   #文件名
    filetype=os.path.splitext(file)[1]   #文件擴(kuò)展名
    Newdir=os.path.join(path,str(int(filename)+12682).zfill(6)+filetype)  #用字符串函數(shù)zfill 以0補(bǔ)全所需位數(shù)
    os.rename(Olddir,Newdir)#重命名
  • VOC格式數(shù)據(jù)集從000000.jpg轉(zhuǎn)換為從1.jpg開始的自然排列魁蒜。
import os
path = "/home/henry/Files/URPC2018/UPRC2018UnderWaterDetection/cla6/JPEGImagesc"
path1 = "/home/henry/Files/URPC2018/UPRC2018UnderWaterDetection/cla6/1"
filelist = os.listdir(path) #該文件夾下所有的文件(包括文件夾)
for file in filelist:   #遍歷所有文件
    Olddir=os.path.join(path,file)   #原來的文件路徑
    if os.path.isdir(Olddir):   #如果是文件夾則跳過
        continue
    filename=os.path.splitext(file)[0]   #文件名
    filetype=os.path.splitext(file)[1]   #文件擴(kuò)展名
    Newdir=os.path.join(path1,str(int(filename)+1)+filetype) 
    os.rename(Olddir,Newdir)#重命名
  • Layout和Main文件夾所需text文檔囊扳。
    制作VOC2007數(shù)據(jù)集中的trainval.txt, train.txt 兜看, test.txt 锥咸, val.txt
    trainval占總數(shù)據(jù)集的50%,test占總數(shù)據(jù)集的50%铣减;train占trainval的50%她君,val占trainval的50%;
import os
import random

trainval_percent = 0.5
train_percent = 0.5
xmlfilepath = 'Anno/G0024173'
txtsavepath = 'test'
total_xml = os.listdir(xmlfilepath)

num=len(total_xml)
list=range(num)
tv=int(num*trainval_percent)
tr=int(tv*train_percent)
trainval= random.sample(list,tv)
train=random.sample(trainval,tr)

ftrainval = open('test\\trainval.txt', 'w')
ftest = open('test\\test.txt', 'w')
ftrain = open('test\\train.txt', 'w')
fval = open('test\\val.txt', 'w')

for i  in list:
    name=total_xml[i][:-4]+'\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftrain.write(name)
        else:
            fval.write(name)
    else:
        ftest.write(name)

ftrainval.close()
ftrain.close()
fval.close()
ftest .close()
# ! /usr/bin/python
# -*- coding:UTF-8 -*-
import os, sys
import glob
from PIL import Image

# VEDAI 圖像存儲(chǔ)位置
src_img_dir = os.path.abspath('.')+'/13'
# VEDAI 圖像的 ground truth 的 xml 文件存放位置
src_xml_dir = '/home/henry/File/URPC2018/all_train_data_0829/111'


# 遍歷目錄讀取圖片
img_Lists = []
def get_img_list(dir_path):
    if os.path.isdir(dir_path):
        for x in os.listdir(dir_path):
            get_img_list(os.path.join(dir_path, x))
    elif os.path.isfile(dir_path) and dir_path.split('.')[-1] == 'jpg':
        img_Lists.append(dir_path)

get_img_list(src_img_dir)
img_Lists.sort(key=lambda x:x[-10:])
# for i in img_Lists:
#     print(i)

# 創(chuàng)建xml文件缔刹,存入圖片信息
for img_item in img_Lists:
    im = Image.open(img_item)  #打開圖片 為了記錄圖片的長(zhǎng)寬數(shù)據(jù)
    img = os.path.split(img_item)[1].split('.')[0]
    width, height = im.size

    # write in xml file
    # os.mknod(src_xml_dir + '/' + img + '.xml')
    xml_file = open((src_xml_dir + '/' + img + '.xml'), 'w')
    xml_file.write('<annotation>\n')
    xml_file.write('    <folder>VOC2007</folder>\n')
    xml_file.write('    <filename>' + str(img) + '.jpg' + '</filename>\n')
    xml_file.write('    <size>\n')
    xml_file.write('        <width>' + str(width) + '</width>\n')
    xml_file.write('        <height>' + str(height) + '</height>\n')
    xml_file.write('        <depth>3</depth>\n')
    xml_file.write('    </size>\n')
    xml_file.close()
# 讀取全部信息
txt_file = open('YDXJ0013.txt')

for line in txt_file.readlines():
    gt = line.splitlines()
    # print(gt)
#     gt = txt_file.readline().splitlines()
#     # gt = open(src_txt_dir + '/gt_' + img + '.txt').read().splitlines()

    # write the region of image on xml file
    for img_each_label in gt:
        spt = img_each_label.split(' ')  # 這里如果txt里面是以逗號(hào)‘球涛,’隔開的,那么就改為spt = img_each_label.split(',')校镐。

        # 判斷是否需要寫入xml
        if spt[6] == '0':
            # print (gt)

            # 打開相應(yīng)xml文件
            # print(spt[5].zfill(6))
            xml_file = open((src_xml_dir + '/' + spt[5].zfill(6) + '.xml'), 'a')
            xml_file.write('    <object>\n')
            xml_file.write('        <name>' + str(spt[9]) + '</name>\n')
            xml_file.write('        <pose>Unspecified</pose>\n')
            xml_file.write('        <truncated>0</truncated>\n')
            xml_file.write('        <difficult>0</difficult>\n')
            xml_file.write('        <bndbox>\n')
            xml_file.write('            <xmin>' + str(spt[1]) + '</xmin>\n')
            xml_file.write('            <ymin>' + str(spt[2]) + '</ymin>\n')
            xml_file.write('            <xmax>' + str(spt[3]) + '</xmax>\n')
            xml_file.write('            <ymax>' + str(spt[4]) + '</ymax>\n')
            xml_file.write('        </bndbox>\n')
            xml_file.write('    </object>\n')
            xml_file.close()

# 補(bǔ)上結(jié)尾
for i in range(4500):
    xml_file = open((src_xml_dir + '/' + str(i).zfill(6) + '.xml'), 'a')
    xml_file.write('</annotation>')
    xml_file.close()

生產(chǎn)xml文檔格式亿扁,以000017.xml為例

<annotation>
<folder>VOC2007</folder>
<filename>000017.jpg</filename>
<size>                        //圖像尺寸(長(zhǎng)寬以及通道數(shù))
<width>720</width>
<height>405</height>
<depth>3</depth></size>
<object>           //檢測(cè)到的物體
<name>"scallop"</name>       //物體類別
<pose>Unspecified</pose>    //拍攝角度
<truncated>0</truncated>      //是否被截?cái)啵?表示完整)
<difficult>0</difficult>             //目標(biāo)是否難以識(shí)別(0表示容易識(shí)別)
<bndbox>                               //bounding-box  目標(biāo)框坐標(biāo)
<xmin>690</xmin>   左上角x
<ymin>299</ymin>   左上角y
<xmax>718</xmax>  右下角x
<ymax>356</ymax>  右下角y
</bndbox>
</object>                                //檢測(cè)到多個(gè)物體
<object>
<name>"scallop"</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>472</xmin>
<ymin>296</ymin>
<xmax>709</xmax>
<ymax>403</ymax>
</bndbox>
</object>
<object>
<name>"scallop"</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>674</xmin>
<ymin>89</ymin>
<xmax>717</xmax>
<ymax>155</ymax>
</bndbox>
</object>
<object>
<name>"seaurchin"</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>663</xmin>
<ymin>12</ymin>
<xmax>716</xmax>
<ymax>67</ymax>
</bndbox>
</object>
<object>
<name>"scallop"</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>507</xmin>
<ymin>110</ymin>
<xmax>647</xmax>
<ymax>210</ymax>
</bndbox></object>
<object>
<name>"seaurchin"</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>576</xmin>
<ymin>173</ymin>
<xmax>714</xmax>
<ymax>297</ymax>
</bndbox></object>
<object>
<name>"scallop"</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>90</xmin>
<ymin>122</ymin>
<xmax>199</xmax>
<ymax>187</ymax>
</bndbox>
</object>
<object>
<name>"scallop"</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>202</xmin>
<ymin>76</ymin>
<xmax>303</xmax>
<ymax>138</ymax>
</bndbox>
</object>
<object>
<name>"scallop"</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>201</xmin>
<ymin>170</ymin>
<xmax>366</xmax>
<ymax>294</ymax>
</bndbox>
</object>
<object>
<name>"seaurchin"</name>   
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>52</xmin>
<ymin>137</ymin>
<xmax>189</xmax>
<ymax>279</ymax>
</bndbox></object>
<object>
<name>"seacucumber"</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>36</xmin>
<ymin>234</ymin>
<xmax>137</xmax>
<ymax>373</ymax>
</bndbox>
</object>
</annotation>
  • 修改xml文件,frame改filename鸟廓。
from xml.etree import ElementTree
import os, sys
import glob
from PIL import Image

path = "/media/leequens/File/YOLO/test/xml/11"
filelist = os.listdir(path)
for file in filelist:
    filename = os.path.splitext(file)[0]  # 文件名
    filetype = os.path.splitext(file)[1]  # 文件擴(kuò)展名
    xmldoc = ElementTree.parse('/media/leequens/File/YOLO/test/xml/rebox/'+str(int(filename)).zfill(6)+'.xml')
    root = xmldoc.getroot()

    for child in root:
        if child.tag == 'frame':
            temp_node = 'filename'
            child.tag = temp_node
            break   
    xmldoc.write('/media/leequens/File/YOLO/test/xml/'+str(int(filename)).zfill(6)+'.xml')
  • 根據(jù)xml框出圖片物體
import os
import os.path
import numpy as np
import xml.etree.ElementTree as xmlET
from PIL import Image, ImageDraw

classes = ('__background__', # always index 0
           '"seacucumber"', '"seaurchin"', '"scallop"', 'boat',
           'bottle', 'bus', 'car', 'cat', 'chair',
           'cow', 'diningtable', 'dog', 'horse',
           'motorbike', 'person', 'pottedplant',
           'sheep', 'sofa', 'train', 'tvmonitor')

file_path_img = '/home/henry/File/URPC2018/all_train_data_0829/13'
file_path_xml = '/home/henry/File/URPC2018/all_train_data_0829/111'
save_file_path = '/home/henry/File/URPC2018/all_train_data_0829/test'

pathDir = os.listdir(file_path_xml)
for idx in range(len(pathDir)):  
    filename = pathDir[idx]
    tree = xmlET.parse(os.path.join(file_path_xml, filename))
    objs = tree.findall('object')        
    num_objs = len(objs)
    boxes = np.zeros((num_objs, 5), dtype=np.uint16)

    for ix, obj in enumerate(objs):
        bbox = obj.find('bndbox')
        # Make pixel indexes 0-based
        x1 = float(bbox.find('xmin').text) - 1
        y1 = float(bbox.find('ymin').text) - 1
        x2 = float(bbox.find('xmax').text) - 1
        y2 = float(bbox.find('ymax').text) - 1

        cla = obj.find('name').text
        label = classes.index(cla)  

        boxes[ix, 0:4] = [x1, y1, x2, y2]
        boxes[ix, 4] = label

    image_name = os.path.splitext(filename)[0]
    img = Image.open(os.path.join(file_path_img, image_name + '.jpg')) 

    draw = ImageDraw.Draw(img)
    for ix in range(len(boxes)):
        xmin = int(boxes[ix, 0])
        ymin = int(boxes[ix, 1])
        xmax = int(boxes[ix, 2])
        ymax = int(boxes[ix, 3])
        draw.rectangle([xmin, ymin, xmax, ymax], outline=(255, 0, 0))
        draw.text([xmin, ymin],classes[boxes[ix, 4]], (255, 0, 0))

    img.save(os.path.join(save_file_path, image_name + '.jpg'))
  • 生成/VOCdevkit/VOC2007/ImageSets/Layout/train.txt从祝,含圖片路徑,目前圖片保存在/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173路徑引谜,在終端運(yùn)行下面命令牍陌,txt文檔生成到根目錄~。其他txt文件類似處理员咽。
ls -R /home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/*.jpg >train.txt

/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/000000.jpg
/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/000001.jpg
/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/000002.jpg
/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/000003.jpg
/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/000004.jpg
/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/000005.jpg
/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/000006.jpg
/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/000007.jpg
/home/henry/File/URPC2018/VOC/VOC2007/JPEGImages/G0024173/000008.jpg

  • 生成/VOCdevkit/VOC2007/test/train.txt毒涧,不含圖片路徑,代碼應(yīng)在VOC2007文件夾下運(yùn)行贝室,圖片從000000.jpg到001800.jpg契讲。
import os
import random

file = open('/test/train.txt', 'w')
for i in range(0, 1800):
    file.write(str("%06d" % i) + '\n')
file.close()
c=0;for i in *.jpg;do mv -f $i $((c+=1)).jpg;done

23456789
23456789
23456789

終端在tmp.txt路徑下運(yùn)行

sed -i 's/$/.jpg&/g' tmp.txt

23456789.jpg
23456789.jpg
23456789.jpg

刪除共同后綴,可以用查找替換方法峡迷。

  • 去掉文件名前導(dǎo)0方法
rename "s/^0{1,2}//g" *

Linux文件批量改名/排序總結(jié)(rename银伟,sort等)

  • 將比賽用的test_list.txt保存為字典,并將測(cè)試結(jié)果result.txt按照字典方式對(duì)應(yīng)為凉当。
    test_list.txt內(nèi)容

CHN083846_0000 1
CHN083846_0043 2
CHN083846_0076 3
CHN083846_0099 4
CHN083846_0124 5
CHN083846_0182 6
CHN083846_0237 7
CHN083846_0257 8
CHN083846_0262 9
CHN083846_0268 10
CHN083846_0276 11
CHN083846_0286 12
CHN083846_0290 13
CHN083846_0300 14
CHN083846_0308 15
CHN083846_0311 16
CHN083846_0321 17
CHN083846_0324 18
CHN083846_0326 19
CHN083846_0334 20

result.txt內(nèi)容

CHN083846_0000.jpg 2 0.99687284 311 234 389 304
CHN083846_0000.jpg 2 0.9967654 379 105 464 184
CHN083846_0000.jpg 2 0.99383944 394 219 465 294
CHN083846_0000.jpg 2 0.993507 366 99 416 157
CHN083846_0000.jpg 2 0.98956084 498 164 571 238
CHN083846_0000.jpg 2 0.9875843 491 370 584 474
CHN083846_0000.jpg 2 0.98697644 373 178 430 232
CHN083846_0000.jpg 2 0.9807468 316 201 383 250
CHN083846_0043.jpg 2 0.99795675 325 120 404 198
CHN083846_0043.jpg 2 0.9977519 228 219 305 288
CHN083846_0043.jpg 2 0.9969998 309 111 359 156
CHN083846_0043.jpg 2 0.99581474 427 193 495 270
CHN083846_0043.jpg 2 0.9956038 304 229 374 302
CHN083846_0043.jpg 2 0.9946083 543 405 585 457
CHN083846_0043.jpg 2 0.9940837 372 394 466 479
CHN083846_0043.jpg 2 0.9934238 295 183 360 240
CHN083846_0043.jpg 2 0.99061626 233 188 307 249
CHN083846_0043.jpg 2 0.9718845 552 86 585 130
CHN083846_0076.jpg 2 0.99764097 293 227 363 295
CHN083846_0076.jpg 2 0.9971411 217 198 289 255
CHN083846_0076.jpg 2 0.9971004 548 27 585 72
CHN083846_0076.jpg 2 0.99674976 282 171 358 243

轉(zhuǎn)換需要的代碼convertxt-zidian.py:

f = open('test_list.txt', 'r')                  
result = {}
for line in f.readlines():
    line = line.strip()   # 去除首尾空格
    if not len(line):
        continue
    result[line.split(' ')[0]] = line.split(' ')[1]

input_file = open(r'/home/henry/Files/URPC2018/常用pythoncodes/result3.txt',"r").read();
for key,value in result.items():
  input_file=input_file.replace(key,value);
print(input_file)
with open('text_trans.txt','w+') as filetwo:  
        filetwo.writelines(input_file)

test_list.txt保存在當(dāng)前路徑下枣申,與convertxt-zidian.py放在一起,result.txt放在/home/henry/Files/URPC2018/常用pythoncodes/result3.txt看杭,生成的文件為text_trans.txt,內(nèi)容如下:

1 2 0.99687284 311 234 389 304
1 2 0.9967654 379 105 464 184
1 2 0.99383944 394 219 465 294
1 2 0.993507 366 99 416 157
1 2 0.98956084 498 164 571 238
1 2 0.9875843 491 370 584 474
1 2 0.98697644 373 178 430 232
1 2 0.9807468 316 201 383 250
2 2 0.99795675 325 120 404 198
2 2 0.9977519 228 219 305 288
2 2 0.9969998 309 111 359 156
2 2 0.99581474 427 193 495 270
2 2 0.9956038 304 229 374 302
2 2 0.9946083 543 405 585 457
2 2 0.9940837 372 394 466 479
2 2 0.9934238 295 183 360 240
2 2 0.99061626 233 188 307 249
2 2 0.9718845 552 86 585 130

  • 圖片格式轉(zhuǎn)換將* .png轉(zhuǎn)換為* .jpg
henry@henry-Rev-1-0:~/Files/URPC2018/UPRC2018UnderWaterDetection/enhanced0815/B6
2 (復(fù)件)$ for i in *.png;do convert ${i} ${i%png}jpg;done
henry@henry-Rev-1-0:~/Files/URPC2018/UPRC2018UnderWaterDetection/enhanced0815/B6
2 (復(fù)件)$ rm -rf *.png

  • 圖片批量修改格式.sh文件挟伙,將當(dāng)前目錄中* .png圖片轉(zhuǎn)換為*.jpg圖片楼雹,并刪除.png圖片
for i in *.png;do convert ${i} ${i%bmp}jpg;done
rm -rf *.png
  • comm命令進(jìn)行文本編輯操作

多文本排序

sort A.txt -o A.txt; sort B.txt -o B.txt 

兩文本比較并輸出至2.txt

comm train.txt test.txt>2.txt

參考資料comm比較兩個(gè)文件的異同

  • diff命令進(jìn)行文本內(nèi)容比較操作

文件1中有,文件2中沒有輸出到_1_not_in_2.txt,文件2中有

diff -u a.txt b.txt|grep '^-' |grep -v '^---' > '_1_not_in_2.txt'

文件1中沒有的輸出到_2_not_in_1.txt

diff -u a.txt b.txt|grep '^+' |grep -v '^+++' > '_2_not_in_1.txt'

文件1和文件2都是每行一串字符尖阔,要選出相同的行輸出到same.txt

diff -u a.txt b.txt|grep '^ ' > same.txt
  • python批量修改xml屬性

修改xml文件贮缅,將其filename部分與自身*.xml對(duì)應(yīng)

#coding=utf-8
import os
import os.path
import xml.dom.minidom
 
path="./7"
files=os.listdir(path)  #得到文件夾下所有文件名稱
s=[]
for xmlFile in files:
    #遍歷文件夾
    portion = os.path.splitext(xmlFile)
    if not os.path.isdir(xmlFile):
        #判斷是否是文件夾,不是文件夾才打開
        # print (xmlFile)
 
        #xml文件讀取操作
 
        #將獲取的xml文件名送入到dom解析
        dom=xml.dom.minidom.parse(os.path.join(path,xmlFile))
        ###最核心的部分os.path.join(path,xmlFile),路徑拼接,輸入的是具體路徑
        root=dom.documentElement
        name=root.getElementsByTagName('frame')
            #pose=root.getElementsByTagName('pose')
            #重命名class name
        for i in range(len(name)):
            # print (name[i].firstChild.data)
            print(xmlFile)
            if portion[1] ==".xml":           
                newname = portion[0]+".jpg"
                print(newname)
            name[i].firstChild.data=newname
            print (name[i].firstChild.data)
 
            #保存修改到xml文件中
        with open(os.path.join(path,xmlFile),'w',encoding='UTF-8') as fh:
            dom.writexml(fh)
            print('修改filename OK!')

參考資料python批量修改xml屬性

  • python批量修改xml的bounding box數(shù)值,修改為圖片鏡像翻轉(zhuǎn)之后的包圍框坐標(biāo)介却。
# coding:utf-8
import cv2
import math
import numpy as np
import xml.etree.ElementTree as ET
import os

xmlpath = './5801xml/'          
imgpath = './imgs/'         
rotated_imgpath = './rotatedimg/'
rotated_xmlpath = './rotatedxml/'
for i in os.listdir(xmlpath):
     a, b = os.path.splitext(i)
     print(str(i))
     tree = ET.parse(xmlpath + a + '.xml')
     root = tree.getroot()
     for chi in root.iter('size'):
         width=int(chi.find('width').text)
     for box in root.iter('bndbox'):
         xmin = int(box.find('xmin').text)
         ymin = int(box.find('ymin').text)
         xmax = int(box.find('xmax').text)
         ymax = int(box.find('ymax').text)
            
         box.find('xmin').text = str(width-xmax)
         box.find('ymin').text = str(ymin)
         box.find('xmax').text = str(width-xmin)
         box.find('ymax').text = str(ymax)
         tree.write(rotated_xmlpath + a + '.xml')
         print(str(a) + '.xml has been rotated for  '+'°')
  • 腳本批量修改圖片大小尺寸和翻轉(zhuǎn)操作
    修改圖片大小谴供,將當(dāng)前文件夾中圖片原地修改為256x256
set -e  # or use "set -o errexit" to quit on error.
set -x  # or use "set -o xtrace" to print the statement before you execute it.

FILES=*.jpg
for f in $FILES
do
        echo "$f"
        convert $f -resize 256x256! $f
done

在當(dāng)前文件夾中對(duì)圖片鏡像翻轉(zhuǎn)

set -e  # or use "set -o errexit" to quit on error.
set -x  # or use "set -o xtrace" to print the statement before you execute it.

FILES=*.jpg
for f in $FILES
do
        echo "$f"
        convert $f -flop $f
done
  • 讀取圖像的尺寸大小
import cv2
import os

dirfile = './copy'
filenames = os.listdir(dirfile)
filenames.sort()
f = open('image_shape1.txt','a+')

for filename in filenames:

    path = dirfile+'/'+filename

    print(dirfile + '/' + filename)

    img = cv2.imread(path)   # read image.jpg from dirfile
    # img = cv2.cv.LoadImage(path)
    size = img.shape
    size_output = str(size)
    print(size)

    f.writelines(filename + ' '+ size_output+'\n')
f.close()

  • 由csv制作xml文件
import os
from utilscsv import *
from lxml.etree import Element, SubElement, tostring
from xml.dom.minidom import parseString
import cv2

countnum = 0

def save_xml(image_name, bbox_class, save_dir='./VOC2007/Annotations', width=1609, height=500, channel=3):


  global countnum

  path = './JPEGImages/'+ image_name + '.jpg'

  img = cv2.imread(path)  # read image.jpg from dirfile
  size = img.shape
  width = size[1]
  height = size[0]
  channel = size[2]

  node_root = Element('annotation')
  node_folder = SubElement(node_root, 'folder')
  node_folder.text = 'JPEGImages'

  node_filename = SubElement(node_root, 'filename')
  node_filename.text = image_name + '.jpg'

  node_size = SubElement(node_root, 'size')
  node_width = SubElement(node_size, 'width')
  node_width.text = '%s' % width
  node_height = SubElement(node_size, 'height')
  node_height.text = '%s' % height
  node_depth = SubElement(node_size, 'depth')
  node_depth.text = '%s' % channel

  print("bbox_class: ",bbox_class)

  # for i in range(len(bbox_class)):
  if int(bbox_class[0]) <6 or abs(int(bbox_class[0])-width)<6:  # x coordiante near boundary

        if int(bbox_class[1]) <6 or abs(int(bbox_class[1])-height)<6:  # y coordiante near boundary
           print("x near bbox_class[1]: ",int(bbox_class[1]))
           # left is minimum
           if int(bbox_class[0]) ==1:
               left = int(bbox_class[0])
           else:
               left = int(bbox_class[0])-1

           top = int(bbox_class[1])-1

           # right is maxmium
           if int(bbox_class[0]) == width:
              right = int(bbox_class[0])
           else:
              right = int(bbox_class[0])+1

           bottom = int(bbox_class[1]) + 1

        else:                                                     # y coordiante away from boundary
            print("x near y away bbox_class[0]: ", int(bbox_class[0]))
            left = int(bbox_class[0]) - 1
            top = int(bbox_class[1]) - 1
            right = int(bbox_class[0]) + 1
            bottom = int(bbox_class[1]) + 1

  elif int(bbox_class[1]) <6 or abs(int(bbox_class[1])-height)<6:  # y coordiante near boundary
           print("y near bbox_class[1]: ",int(bbox_class[1]))
           left = int(bbox_class[0])-1
           top = int(bbox_class[1])-1
           right = int(bbox_class[0])+1
           bottom = int(bbox_class[1]) + 1

  else:
         left, top, right, bottom = int(bbox_class[0])-5, int(bbox_class[1])-5, int(bbox_class[0]) + 5, int(bbox_class[1]) + 5

  if (left >=1 and left <= width) and (top >=1 and top <= height) and (right >=1 and right <= width) and (bottom >=1 and bottom <= height):
        countnum += 1
        print("lefttop and rightbottom are in the range!", countnum)
        node_object = SubElement(node_root, 'object')
        node_name = SubElement(node_object, 'name')
        node_name.text = '%s' % bbox_class[2]
        node_difficult = SubElement(node_object, 'difficult')
        node_difficult.text = '0'
        node_bndbox = SubElement(node_object, 'bndbox')
        node_xmin = SubElement(node_bndbox, 'xmin')
        node_xmin.text = '%s' % left
        node_ymin = SubElement(node_bndbox, 'ymin')
        node_ymin.text = '%s' % top
        node_xmax = SubElement(node_bndbox, 'xmax')
        node_xmax.text = '%s' % right
        node_ymax = SubElement(node_bndbox, 'ymax')
        node_ymax.text = '%s' % bottom

  else:
        print("There is an error: ",node_filename.text)
        file_object = open('log.txt', 'a+')
        file_object.writelines("There is an error: "+ node_filename.text + '\t')
        file_object.writelines(str(left)+' '+str(top)+' '+str(right)+' '+ str(bottom)+'\n')
        file_object.close()


  xml = tostring(node_root, pretty_print=True)
  dom = parseString(xml)

  save_xml = os.path.join(save_dir, node_filename.text.replace('jpg', 'xml'))
  with open(save_xml, 'wb') as f:
        f.write(xml)

  return

def change2xml(label_dict={}):
    for image in label_dict.keys():
        image_name = os.path.split(image)[-1]
        bbox_object = label_dict.get(image, [])
        save_xml(image_name, bbox_object)
    return


if __name__ == '__main__':
    label_dict = read_csv(csv_path=r'./list.csv',
                                pre_dir=r'./JPEGImages')
    change2xml(label_dict)

  • 相關(guān)配置文件

import csv
import os

def read_csv(csv_path, pre_dir):

    label_dict = {}
    with open(csv_path, "r") as f:
        reader = csv.reader(f)
        header = True
        for line in reader:
            
            if header:
                header = False
                continue
           
            image_path = os.path.join(pre_dir, line[0])
            
            bbox_object = []

            for i in range(1,4):
              bbox_object.append(line[i])

           
            label_dict.setdefault(image_path, bbox_object)
    return label_dict


def write_csv(result_dict, out_path='out.csv'):

    with open(out_path, 'w', newline='') as f:
        writer = csv.writer(f)
        
        writer.writerow(['name', 'coordinate'])

        for image in result_dict.keys():
            image_name = os.path.split(image)[-1]
            bbox = result_dict.get(image, [])
            bbox_rs = ';'.join(['_'.join(str(int(id)) for id in i) for i in bbox])
            writer.writerow([image_name, bbox_rs])


if __name__ == '__main__':
    label_dict = read_csv(csv_path=r'./train_b.csv',
                             pre_dir=r'/home/matthew/dataset')
    write_csv(label_dict)

  • 讀取csv文件并保存到txt文件中
import csv
import os

def read_csv(csv_path, pre_dir):
    
    label_dict = {}
    with open(csv_path, "r") as f:
        reader = csv.reader(f)
        header = True
        for line in reader:
           
            if header:
                header = False
                continue
           
            image_path = os.path.join(pre_dir, line[0])
            
            bbox_object = []
           
            for i in range(1,4):
              bbox_object.append(line[i])

            
            label_dict.setdefault(image_path, bbox_object)
    return label_dict


def write_csv(result_dict, out_path='out.csv'):

    with open(out_path, 'w', newline='') as f:
        writer = csv.writer(f)
        
        writer.writerow(['name', 'coordinate'])

        for image in result_dict.keys():
            image_name = os.path.split(image)[-1]
            bbox = result_dict.get(image, [])
            bbox_rs = ';'.join(['_'.join(str(int(id)) for id in i) for i in bbox])
            writer.writerow([image_name, bbox_rs])

if __name__ == '__main__':
    label_dict = read_csv(csv_path=r'./train_b.csv',
                             pre_dir=r'/home/matthew/dataset')
    write_csv(label_dict)

  • 從txt中讀取符合要求的文件到指定目錄
import os
import shutil

srcimage_dir_path = "./VOC2007_6280/VOC_nova_all/JPEGImages"
srcxml_dir_path = "./VOC2007_6280/VOC_nova_all/Annotations_2class_0401"

imageto_dir_path = "./VOC2007_6280/all_star/copy_star_image/"
xmlto_dir_path = "./VOC2007_6280/all_star/copy_star_xml/"

txt_path = './csv_reader.txt'

key = '_a'

count = 0

if not os.path.exists(imageto_dir_path):
    print("to_dir_path not exist,so create the dir")
    os.mkdir(imageto_dir_path)

if not os.path.exists(xmlto_dir_path):
    print("to_dir_path not exist,so create the dir")
    os.mkdir(xmlto_dir_path)


# if os.path.exists(src_dir_path):
#    print("src_dir_path exitst")

fr = open(txt_path)
stringClass = [line.strip().split('\t') for line in fr.readlines()]
# print("stringClass: ",stringClass)

for i in range(len(stringClass)):
    if stringClass[i][3] == 'newtarget' or stringClass[i][3] == 'isstar' or stringClass[i][3] == 'asteroid' or stringClass[i][3] == 'isnova' or stringClass[i][3] == 'known':
        image_name = stringClass[i][0] + '.jpg'
        xml_name = stringClass[i][0] + '.xml'
        count +=1
        print(image_name,' ',count)
        shutil.copy(srcimage_dir_path+'/'+image_name,imageto_dir_path+image_name)
        shutil.copy(srcxml_dir_path + '/' + xml_name, xmlto_dir_path + xml_name)
  • 對(duì)圖像進(jìn)行鏡像翻轉(zhuǎn)操作,擴(kuò)充訓(xùn)練集同時(shí)齿坷,增加正樣本數(shù)量
import cv2
import copy
import os

"""
#水平鏡像可按公式
#I = i
#J = N - j + 1
#垂直鏡像可按公式
#I = M - i + 1
#J = j
#對(duì)角鏡像可按公式
#I = M - i + 1
#J = N - j + 1
"""

def mirror_imgs(imgs_path, save_path):
  for name in os.listdir(imgs_path):
    print(name)
    image = cv2.imread(os.path.join(imgs_path, name), 1);
    height = image.shape[0]
    width = image.shape[1]
    # channels = image.shape[2]
    iLR = copy.deepcopy(image)  # 獲得一個(gè)和原始圖像相同的圖像桂肌,注意這里要使用深度復(fù)制

    for i in range(height):
      for j in range(width):
        iLR[i, width - 1 - j] = image[i, j]
    # cv2.imshow('image', image)
    # cv2.imshow('iLR', iLR)
    save_name = name[:-4]+'_zym'+'.jpg'

    cv2.imwrite(os.path.join(save_path, save_name), iLR,
                [int(cv2.IMWRITE_JPEG_QUALITY), 100])  # 保存圖片
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()

def horizontal_mirror_imgs(imgs_path, save_path):
  for name in os.listdir(imgs_path):
    print(name)
    image = cv2.imread(os.path.join(imgs_path, name), 1);
    height = image.shape[0]
    width = image.shape[1]
    # channels = image.shape[2]
    iLR = copy.deepcopy(image)  # 獲得一個(gè)和原始圖像相同的圖像数焊,注意這里要使用深度復(fù)制

    for i in range(height):
      for j in range(width):
        iLR[i, width - 1 - j] = image[i, j]
    # cv2.imshow('image', image)
    # cv2.imshow('iLR', iLR)
    save_name = name[:-4]+'_zym'+'.jpg'

    cv2.imwrite(os.path.join(save_path, save_name), iLR,
                [int(cv2.IMWRITE_JPEG_QUALITY), 100])  # 保存圖片
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()

def vertical_mirror_imgs(imgs_path, save_path):
  for name in os.listdir(imgs_path):
    print(name)
    image = cv2.imread(os.path.join(imgs_path, name), 1);
    height = image.shape[0]
    width = image.shape[1]
    # channels = image.shape[2]
    iLR = copy.deepcopy(image)  # 獲得一個(gè)和原始圖像相同的圖像,注意這里要使用深度復(fù)制

    for i in range(height):
      for j in range(width):
        iLR[height - 1 - i, j] = image[i, j]
    # cv2.imshow('image', image)
    # cv2.imshow('iLR', iLR)
    save_name = name[:-4]+'_sxm'+'.jpg'

    cv2.imwrite(os.path.join(save_path, save_name), iLR,
                [int(cv2.IMWRITE_JPEG_QUALITY), 100])  # 保存圖片
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()


imgs_path = '/home/henry/Files/FutureAi/VOC2007_6280/all_star/copy_star_image'
save_path = "/home/henry/Files/FutureAi/VOC2007_6280/all_star/copy_star_image_mirror"

if not os.path.exists(save_path):
    os.makedirs(save_path)
#mirror_imgs(imgs_path, save_path)

horizontal_mirror_imgs(imgs_path,save_path)
# vertical_mirror_imgs
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末崎场,一起剝皮案震驚了整個(gè)濱河市佩耳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谭跨,老刑警劉巖干厚,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異螃宙,居然都是意外死亡蛮瞄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門谆扎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來十办,“玉大人,你說我怎么就攤上這事躲雅÷访模” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵苗缩,是天一觀的道長(zhǎng)饵蒂。 經(jīng)常有香客問我,道長(zhǎng)酱讶,這世上最難降的妖魔是什么退盯? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮泻肯,結(jié)果婚禮上渊迁,老公的妹妹穿的比我還像新娘。我一直安慰自己灶挟,他們只是感情好琉朽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著稚铣,像睡著了一般箱叁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惕医,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天耕漱,我揣著相機(jī)與錄音,去河邊找鬼抬伺。 笑死螟够,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妓笙,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼若河,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了给郊?” 一聲冷哼從身側(cè)響起牡肉,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎淆九,沒想到半個(gè)月后统锤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炭庙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年饲窿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焕蹄。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逾雄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腻脏,到底是詐尸還是另有隱情鸦泳,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布永品,位于F島的核電站做鹰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鼎姐。R本人自食惡果不足惜钾麸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炕桨。 院中可真熱鬧饭尝,春花似錦、人聲如沸献宫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)姊途。三九已至帖池,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吭净,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工肴甸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寂殉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓原在,卻偏偏與公主長(zhǎng)得像友扰,于是被迫代替她去往敵國(guó)和親彤叉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 刪掉重新來一次吧村怪,記得改那個(gè)腳本修改 /home/ubuntu/eos/scripts/install_depen...
    盧衍泓閱讀 1,137評(píng)論 0 1
  • 小作者:宋慧麗 我不由得看呆了眼秽浇。 在那一方黃土上,承載著一抹綠甚负。近了一看柬焕,原那綠竟是一片竹。這...
    陜縣2942賈娟娟閱讀 256評(píng)論 0 1
  • 文/ 祥銳(汾陽(yáng)) 中秋又送年輪步梭域,不老月斑举,長(zhǎng)生兔。洗澈冰盤懸玉樹病涨,寒清漫灑富玷,細(xì)凝霜霧,映徹云山路既穆。 稀星猶記權(quán)衡...
    祥鋭閱讀 935評(píng)論 23 57
  • 題目一 題目二
    蘇瑾_01d5閱讀 96評(píng)論 0 0