содержание
Установка этикетировочного инструмента Labelme.
Данные в формате VOC обратно преобразуются в набор данных с аннотациями Labelme.
Преобразуйте данные, аннотированные Labelme, в набор данных в формате txt.
Для наборов данных, помеченных в формате txt, реализовать поворот на 90, 180 и 270 градусов.
Установка этикетировочного инструмента Labelme.
установить pyqt
pip install PyQt5
Установите пакет PIL
pip install Pillow
установить лейбл
1. Официальная команда установки.
pip install labelme
Официальный лейбл не поддерживает открытие больших изображений, таких как изображения дистанционного зондирования. Если вы столкнулись с ситуацией, когда изображение не открывается, вы можете использовать метку, которую я изменил.
labelme-master (модифицирован для поддержки больших изображений).zip
download.CSDN.net/download/Хе-хе…
Данные в формате VOC обратно преобразуются в набор данных с аннотациями Labelme.
import sys
import os.path as osp
import io
from labelme.logger import logger
from labelme import PY2
from labelme import QT4
import PIL.Image
import base64
from labelme import utils
import os
import cv2
import xml.etree.ElementTree as ET
module_path = os.path.abspath(os.path.join( '..' ))
if module_path not in sys.path:
sys.path.append(module_path)
import json
from PIL import Image
Image.MAX_IMAGE_PIXELS = None
imageroot = 'RSOD/'
listDir = [ 'aircraft' , 'oiltank' ]
def load_image_file(filename):
try:
image_pil = PIL.Image.open(filename)
except IOError:
logger.error( 'Failed opening image file: {}' .format(filename))
return
# apply orientation to image according to exif
image_pil = utils.apply_exif_orientation(image_pil)
with io.BytesIO() as f:
ext = osp.splitext(filename)[1].lower()
if PY2 and QT4:
format = **'PNG'
**elif ext in [ '.jpg' , '.jpeg' ]:
format = **'JPEG'
**else:
format = **'PNG'
**image_pil.save(f, format=format)
f.seek(0)
return f.read()
def dict_json(flags, imageData, shapes, imagePath, fillColor=None, lineColor=None, imageHeight=100, imageWidth=100):
'''
:param imageData: str
:param shapes: list
:param imagePath: str
:param fillColor: list
:param lineColor: list
:return: dict
'''
return { "version" : "3.16.4" , "flags" : flags, "shapes" : shapes, 'lineColor' : lineColor, "fillColor" : fillColor,
'imagePath' : imagePath.split( '/' )[1], "imageData" : imageData, 'imageHeight' : imageHeight,
'imageWidth' : imageWidth}
data = json.load(open( '1.json' ))
for subPath in listDir:
xmlpathName = imageroot + subPath + **'/Annotation/xml'
**imagepath = imageroot + subPath + **'/JPEGImages'
**resultFile = os.listdir(xmlpathName)
for file in resultFile:
print(file)
imagePH = imagepath + '/' + file.split( '.' )[0] + **'.jpg'
**print(imagePH)
tree = ET.parse(xmlpathName + '/' + file)
image = cv2.imread(imagePH)
shapes = data[ "shapes" ]
version = data[ "version" ]
flags = data[ "flags" ]
lineColor = data[ "lineColor" ]
fillColor = data[ 'fillColor' ]
newshapes = []
for elem in tree.iter():
if 'object' in elem.tag:
name = **''
**xminNode = 0
yminNode = 0
xmaxNode = 0
ymaxNode = 0
for attr in list(elem):
if 'name' in attr.tag:
name = attr.text
if 'bndbox' in attr.tag:
for dim in list(attr):
if 'xmin' in dim.tag:
xminNode = int(round(float(dim.text)))
if 'ymin' in dim.tag:
yminNode = int(round(float(dim.text)))
if 'xmax' in dim.tag:
xmaxNode = int(round(float(dim.text)))
if 'ymax' in dim.tag:
ymaxNode = int(round(float(dim.text)))
line_color = None
fill_color = None
newPoints = [[float(xminNode), float(yminNode)], [float(xmaxNode), float(ymaxNode)]]
shape_type = **'rectangle'
**flags = flags
newshapes.append(
{ "label" : name, "line_color" : line_color, "fill_color" : fill_color, "points" : newPoints,
"shape_type" : shape_type, "flags" : flags})
imageData_90 = load_image_file(imagePH)
imageData_90 = base64.b64encode(imageData_90).decode( 'utf-8' )
imageHeight = image.shape[0]
imageWidth = image.shape[1]
data_90 = dict_json(flags, imageData_90, newshapes, imagePH, fillColor, lineColor, imageHeight, imageWidth)
json_file = imagePH[:-4] + **'.json'
**json.dump(data_90, open(json_file, 'w' ))
- Набор данных, помеченный Labelme, преобразуется в набор данных в формате VOC2007.
Описание папки данных VOC2007
1) Папка Jpegimages
Папка содержит тренировочные картинки и тестовые картинки, смешанные между собой
2) Папка с аннотациями
В папке хранятся файлы этикеток в формате xml, каждому файлу xml соответствует картинка в папке JPEGImages
3) Папка ImageSets
Action хранит действия людей, они нам пока не нужны
Данные о частях человеческого тела хранятся в Layout. нам не нужно
Main хранит данные распознавания объектов изображения.В Main находятся test.txt,train.txt,val.txt,trainval.txt.Эти четыре файла мы сгенерируем позже.
XML-описание
<?xml version="1.0" encoding="utf-8"?>
<annotation>
<source>
<image>optic rs image</image>
<annotation>Lmars RSDS2016</annotation>
<flickrid>0</flickrid>
<database>Lmars Detection Dataset of RS</database>
</source>
<object>
<bndbox>
<xmin>690</xmin>
<ymin>618</ymin>
<ymax>678</ymax>
<xmax>748</xmax>
</bndbox>
<difficult>0</difficult>
<pose>Left</pose>
<name>aircraft</name>
<truncated>1</truncated>
</object>
<filename>aircraft_773.jpg</filename>
<segmented>0</segmented>
<owner>
<name>Lmars, Wuhan University</name>
<flickrid>I do not know</flickrid>
</owner>
<folder>RSDS2016</folder>
<size>
<width>1044</width>
<depth>3</depth>
<height>915</height>
</size>
</annotation>
Полный код:
import os
from typing import List, Any
import numpy as np
import codecs
import json
from glob import glob
import cv2
import shutil
from sklearn.model_selection import train_test_split
# 1.标签路径
labelme_path = "LabelmeData/" # 原始labelme标注数据路径
saved_path = "VOC2007/" # 保存路径
isUseTest=True#是否创建test集
# 2.创建要求文件夹
if not os.path.exists(saved_path + "Annotations"):
os.makedirs(saved_path + "Annotations")
if not os.path.exists(saved_path + "JPEGImages/"):
os.makedirs(saved_path + "JPEGImages/")
if not os.path.exists(saved_path + "ImageSets/Main/"):
os.makedirs(saved_path + "ImageSets/Main/")
# 3.获取待处理文件
files = glob(labelme_path + "*.json")
files = [i.replace("\\","/").split("/")[-1].split(".json")[0] for i in files]
print(files)
# 4.读取标注信息并写入 xml
for json_file_ in files:
json_filename = labelme_path + json_file_ + ".json"
json_file = json.load(open(json_filename, "r", encoding="utf-8"))
height, width, channels = cv2.imread(labelme_path + json_file_ + ".jpg").shape
with codecs.open(saved_path + "Annotations/" + json_file_ + ".xml", "w", "utf-8") as xml:
xml.write('<annotation>\n')
xml.write('\t<folder>' + 'WH_data' + '</folder>\n')
xml.write('\t<filename>' + json_file_ + ".jpg" + '</filename>\n')
xml.write('\t<source>\n')
xml.write('\t\t<database>WH Data</database>\n')
xml.write('\t\t<annotation>WH</annotation>\n')
xml.write('\t\t<image>flickr</image>\n')
xml.write('\t\t<flickrid>NULL</flickrid>\n')
xml.write('\t</source>\n')
xml.write('\t<owner>\n')
xml.write('\t\t<flickrid>NULL</flickrid>\n')
xml.write('\t\t<name>WH</name>\n')
xml.write('\t</owner>\n')
xml.write('\t<size>\n')
xml.write('\t\t<width>' + str(width) + '</width>\n')
xml.write('\t\t<height>' + str(height) + '</height>\n')
xml.write('\t\t<depth>' + str(channels) + '</depth>\n')
xml.write('\t</size>\n')
xml.write('\t\t<segmented>0</segmented>\n')
for multi in json_file["shapes"]:
points = np.array(multi["points"])
labelName=multi["label"]
xmin = min(points[:, 0])
xmax = max(points[:, 0])
ymin = min(points[:, 1])
ymax = max(points[:, 1])
label = multi["label"]
if xmax <= xmin:
pass
elif ymax <= ymin:
pass
else:
xml.write('\t<object>\n')
xml.write('\t\t<name>' + labelName+ '</name>\n')
xml.write('\t\t<pose>Unspecified</pose>\n')
xml.write('\t\t<truncated>1</truncated>\n')
xml.write('\t\t<difficult>0</difficult>\n')
xml.write('\t\t<bndbox>\n')
xml.write('\t\t\t<xmin>' + str(int(xmin)) + '</xmin>\n')
xml.write('\t\t\t<ymin>' + str(int(ymin)) + '</ymin>\n')
xml.write('\t\t\t<xmax>' + str(int(xmax)) + '</xmax>\n')
xml.write('\t\t\t<ymax>' + str(int(ymax)) + '</ymax>\n')
xml.write('\t\t</bndbox>\n')
xml.write('\t</object>\n')
print(json_filename, xmin, ymin, xmax, ymax, label)
xml.write('</annotation>')
# 5.复制图片到 VOC2007/JPEGImages/下
image_files = glob(labelme_path + "*.jpg")
print("copy image files to VOC007/JPEGImages/")
for image in image_files:
shutil.copy(image, saved_path + "JPEGImages/")
# 6.split files for txt
txtsavepath = saved_path + "ImageSets/Main/"
ftrainval = open(txtsavepath + '/trainval.txt', 'w')
ftest = open(txtsavepath + '/test.txt', 'w')
ftrain = open(txtsavepath + '/train.txt', 'w')
fval = open(txtsavepath + '/val.txt', 'w')
total_files = glob("./VOC2007/Annotations/*.xml")
total_files = [i.replace("\\","/").split("/")[-1].split(".xml")[0] for i in total_files]
trainval_files=[]
test_files=[]
if isUseTest:
trainval_files, test_files = train_test_split(total_files, test_size=0.15, random_state=55)
else:
trainval_files=total_files
for file in trainval_files:
ftrainval.write(file + "\n")
# split
train_files, val_files = train_test_split(trainval_files, test_size=0.15, random_state=55)
# train
for file in train_files:
ftrain.write(file + "\n")
# val
for file in val_files:
fval.write(file + "\n")
for file in test_files:
print(file)
ftest.write(file + "\n")
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
Примечание. Набор для обучения и набор для проверки разделены sklearn.model_selection.train_test_split.
Labelme преобразует данные в VOC, генерирует тестовый набор из немаркированных данных и подсчитывает количество каждой категории.
Статистика по размеченным данным.
Поместите непомеченные данные в тестовую папку.
import os
import numpy as np
import codecs
import json
from glob import glob
import cv2
import shutil
from sklearn.model_selection import train_test_split
dicImg={}
imgLis=[]
# 1. Путь метки
labelme_path = "USA/"# Исходный путь к данным аннотации labelme
saved_path = "VOC2007/"# сохранить маршрут
# 2. Создайте папку требований
if not os.path.exists(saved_path + "Annotations" ):
os.makedirs(saved_path + "Annotations" )
if not os.path.exists(saved_path + "JPEGImages/" ):
os.makedirs(saved_path + "JPEGImages/" )
if not os.path.exists(saved_path + "test/" ):
os.makedirs(saved_path + "test/" )
if not os.path.exists(saved_path + "ImageSets/Main/" ):
os.makedirs(saved_path + "ImageSets/Main/" )
# 3. Получить ожидающий файл
files = glob(labelme_path + "*.json" )
files = [i.replace( " \\ " , "/" ).split( "/" )[-1].split( ".json" )[0] for i in files]
print(files)
# 4. Читаем аннотационную информацию и записываем в xml
for json_file_ in files:
json_filename = labelme_path + json_file_ + **".json"
**json_file = json.load(open(json_filename, "r" , encoding= "utf-8" ))
height, width, channels = cv2.imread(labelme_path + json_file_ + ".jpg" ).shape
with codecs.open(saved_path + "Annotations/" + json_file_ + ".xml" , "w" , "utf-8" ) as xml:
xml.write( '<annotation> \n ' )
xml.write( ' \t <folder>' + 'UAV_data' + '</folder> \n ' )
xml.write( ' \t <filename>' + json_file_ + ".jpg" + '</filename> \n ' )
xml.write( ' \t <source> \n ' )
xml.write( ' \t\t <database>The UAV autolanding</database> \n ' )
xml.write( ' \t\t <annotation>UAV AutoLanding</annotation> \n ' )
xml.write( ' \t\t <image>flickr</image> \n ' )
xml.write( ' \t\t <flickrid>NULL</flickrid> \n ' )
xml.write( ' \t </source> \n ' )
xml.write( ' \t <owner> \n ' )
xml.write( ' \t\t <flickrid>NULL</flickrid> \n ' )
xml.write( ' \t\t <name>wanghao</name> \n ' )
xml.write( ' \t </owner> \n ' )
xml.write( ' \t <size> \n ' )
xml.write( ' \t\t <width>' + str(width) + '</width> \n ' )
xml.write( ' \t\t <height>' + str(height) + '</height> \n ' )
xml.write( ' \t\t <depth>' + str(channels) + '</depth> \n ' )
xml.write( ' \t </size> \n ' )
xml.write( ' \t\t <segmented>0</segmented> \n ' )
for multi in json_file[ "shapes" ]:
points = np.array(multi[ "points" ])
labelName=multi[ "label" ].lower()
if labelName in dicImg:
count=dicImg[labelName]
count=count+1;
dicImg[labelName]=count
else:
dicImg[labelName]=1
xmin = min(points[:, 0])
xmax = max(points[:, 0])
ymin = min(points[:, 1])
ymax = max(points[:, 1])
label = multi[ "label" ]
if xmax <= xmin:
pass
elif ymax <= ymin:
pass
else:
xml.write( ' \t <object> \n ' )
xml.write( ' \t\t <name>' + labelName+ '</name> \n ' )
xml.write( ' \t\t <pose>Unspecified</pose> \n ' )
xml.write( ' \t\t <truncated>1</truncated> \n ' )
xml.write( ' \t\t <difficult>0</difficult> \n ' )
xml.write( ' \t\t <bndbox> \n ' )
xml.write( ' \t\t\t <xmin>' + str(int(xmin)) + '</xmin> \n ' )
xml.write( ' \t\t\t <ymin>' + str(int(ymin)) + '</ymin> \n ' )
xml.write( ' \t\t\t <xmax>' + str(int(xmax)) + '</xmax> \n ' )
xml.write( ' \t\t\t <ymax>' + str(int(ymax)) + '</ymax> \n ' )
xml.write( ' \t\t </bndbox> \n ' )
xml.write( ' \t </object> \n ' )
print(json_filename, xmin, ymin, xmax, ymax, label)
xml.write( '</annotation>' )
imgLis.append(json_file_+ '.jpg' )
shutil.copy(labelme_path+json_file_+ '.jpg' , saved_path + "JPEGImages/" )
print(imgLis)
# 5. Копируем изображение в VOC2007/JPEGImages/
image_files = glob(labelme_path + "*.jpg" )
txtsavepath = saved_path + "ImageSets/Main/"
print( "copy image files to VOC007/JPEGImages/" )
ftest = open(txtsavepath + '/test.txt' , 'w' )
for image in image_files:
if image.split( ' \\ ' )[1] not in imgLis:
print(image)
shutil.copy(image, saved_path + "test/" )
ftest.write(image.replace( " \\ " , "/" ).split( "/" )[-1].split( ".jpg" )[0] + " \n " )
# 6.split files for txt
ftrainval = open(txtsavepath + '/trainval.txt' , 'w' )
ftrain = open(txtsavepath + '/train.txt' , 'w' )
fval = open(txtsavepath + '/val.txt' , 'w' )
total_files = glob( "./VOC2007/Annotations/*.xml" )
total_files = [i.replace( " \\ " , "/" ).split( "/" )[-1].split( ".xml" )[0] for i in total_files]
for file in total_files:
ftrainval.write(file + " \n " )
# split
train_files, val_files = train_test_split(total_files, test_size=0.15, random_state=42)
# train
for file in train_files:
ftrain.write(file + " \n " )
# val
for file in val_files:
fval.write(file + " \n " )
ftrainval.close()
ftrain.close()
fval.close()
print(dicImg)
ftest.close()
Преобразуйте данные, аннотированные Labelme, в набор данных в формате txt.
Изображение соответствует txt, и каждая строка в txt соответствует отмеченному объекту.
Формат: категория xmin ymin xmax ymax
import json
import os
from glob import glob
import shutil
# convert labelme json to DOTA txt format
def custombasename(fullname):
return os.path.basename(os.path.splitext(fullname)[0])
IN_PATH = 'USA'
OUT_PATH = 'labeltxt'
if not os.path.exists(OUT_PATH):
os.makedirs(OUT_PATH)
file_list = glob(IN_PATH + '/*.json' )
for i in range(len(file_list)):
with open(file_list[i]) as f:
label_str = f.read()
label_dict = json.loads(label_str) # файл json считывается в dict
imgepath=file_list[i].split( '.' )[0]+ **'.jpg'
**# путь к выходному текстовому файлу
out_file = OUT_PATH + '/' + custombasename(file_list[i]) + **'.txt'
**shutil.copy(imgepath, OUT_PATH)
# Запись четырехточечных полигональных координат и метки
fout = open(out_file, 'w' )
out_str = **''
**for shape_dict in label_dict[ 'shapes' ]:
out_str += shape_dict[ 'label' ] + **' '
**points = shape_dict[ 'points' ]
for p in points:
out_str += (str(p[0]) + ' ' + str(p[1]) + ' ' )
out_str += ' \n **'
**fout.write(out_str)
fout.close()
print( '%d/%d' % (i + 1, len(file_list)))
Для изображений, помеченных Labelme, поверните их на 90, 180 и 270, чтобы реализовать расширение помеченных данных.
При создании набора данных обнаружения объектов изображения дистанционного зондирования все объекты в изображении дистанционного зондирования являются плоскими и имеют проблемы с углом.
Обнаруженные объекты можно поворачивать под разными углами, обогащая набор данных и уменьшая нагрузку на маркировку.
Например, в плоскости на картинке выше ориентация носа наклонена вниз.В реальности плоскость может иметь различную ориентацию.Если ее не поворачивать, обнаружительная способность модели будет снижена. На следующем изображении показан эффект поворота на 90 градусов.
Пакеты, которые необходимо установить:
labelme
версия scipy1.0.0
pyqt5
Самая большая сложность при вращении заключается в том, что после поворота отмеченные точки нужно пересчитывать, чтобы не перепутать отмеченные координаты.
После поворота на 90 градусов координаты преобразуются:
points=shapelabel[ 'points']#Получить начальные координаты.
newPoints = [[float(points[0][1]), w-float(points[1][0])],
[float(points[1][1]), w-float(points[0][0])]]#Повернуть на 90 градусов и пересоответствовать координатам. w представляет ширину исходного изображения.
После выбора поворота на 180 градусов координаты преобразуются:
points = shapelabel[ 'points' ]
newPoints = [[w-float(points[1][0]), h - float(points[1][1])],
[w-float(points[0][0]), h - float(points[0][1])]] #Поворот на 180 градусов и повторное соответствие координатам. h представляет собой высоту исходного изображения.
Поворот на 270 градусов, преобразование координат:
points = shapelabel[ 'points' ]
newPoints = [[h - float(points[1][1]), float(points[0][0])],
[h - float(points[0][1]), float(points[1][0])]]
Полный код выглядит следующим образом:
#scipy的版本为1.0.0
import scipy
from scipy import misc
import os
import glob
import PIL.Image
from labelme.logger import logger
from labelme import PY2
from labelme import QT4
import io
import json
import os.path as osp
import PIL.Image
from scipy import ndimage
import base64
from labelme import utils
def load_image_file(filename):
try:
image_pil = PIL.Image.open(filename)
except IOError:
logger.error( 'Failed opening image file: {}' .format(filename))
return
# apply orientation to image according to exif
image_pil = utils.apply_exif_orientation(image_pil)
with io.BytesIO() as f:
ext = osp.splitext(filename)[1].lower()
if PY2 and QT4:
format = **'PNG'
**elif ext in [ '.jpg' , '.jpeg' ]:
format = **'JPEG'
**else:
format = **'PNG'
**image_pil.save(f, format=format)
f.seek(0)
return f.read()
def dict_json(flags,imageData,shapes,imagePath,fillColor=None,lineColor=None,imageHeight=100,imageWidth=100):
'''
:param imageData: str
:param shapes: list
:param imagePath: str
:param fillColor: list
:param lineColor: list
:return: dict
'''
return { "version" : "3.16.4" , "flags" :flags, "shapes" :shapes, 'lineColor' :lineColor, "fillColor" :fillColor, 'imagePath' :imagePath.split( ' \\ ' )[1], "imageData" :imageData, 'imageHeight' :imageHeight, 'imageWidth' :imageWidth}
def get_image_paths(folder):
return glob.glob(os.path.join(folder, '*.jpg' ))
def create_read_img(filename):
data = json.load(open(filename.split( '.' )[0]+ '.json' ))
shapes = data[ "shapes" ]
version = data[ "version" ]
flags = data[ "flags" ]
lineColor = data[ "lineColor" ]
fillColor = data[ 'fillColor' ]
newshapes = []
im = misc.imread(filename)
h,w,d=im.shape
img_rote_90 = ndimage.rotate(im, 90)
img_path_90=filename[:-4]+ **'_90.jpg'
**scipy.misc.imsave(img_path_90,img_rote_90)
imageData_90 = load_image_file(img_path_90)
imageData_90 = base64.b64encode(imageData_90).decode( 'utf-8' )
imageHeight =w
imageWidth = h
for shapelabel in shapes:
newLabel=shapelabel[ 'label' ]
newline_color=shapelabel[ 'line_color' ]
newfill_color=shapelabel[ 'fill_color' ]
points=shapelabel[ 'points' ]
newPoints = [[float(points[0][1]), w-float(points[1][0])],
[float(points[1][1]), w-float(points[0][0])]]
newshape_type=shapelabel[ 'shape_type' ]
newflags=shapelabel[ 'flags' ] newshapes.append({ 'label' :newLabel, 'line_color' :newline_color, 'fill_color' :newfill_color, 'points' :newPoints, 'shape_type' :newshape_type, 'flags' :newflags})
data_90 = dict_json(flags, imageData_90, newshapes, img_path_90, fillColor, lineColor, imageHeight, imageWidth)
json_file = img_path_90[:-4] + **'.json'
**json.dump(data_90, open(json_file, 'w' ))
img_rote_180 = ndimage.rotate(im, 180)
img_path_180=filename[:-4]+ **'_180.jpg'
**scipy.misc.imsave(img_path_180,img_rote_180)
imageData_180 = load_image_file(img_path_180)
imageData_180 = base64.b64encode(imageData_180).decode( 'utf-8' )
imageHeight = h
imageWidth = w
newshapes = []
for shapelabel in shapes:
newLabel = shapelabel[ 'label' ]
newline_color = shapelabel[ 'line_color' ]
newfill_color = shapelabel[ 'fill_color' ]
points = shapelabel[ 'points' ]
newPoints = [[w-float(points[1][0]), h - float(points[1][1])],
[w-float(points[0][0]), h - float(points[0][1])]]
newshape_type = shapelabel[ 'shape_type' ]
newflags = shapelabel[ 'flags' ]
newshapes.append(
{ 'label' : newLabel, 'line_color' : newline_color, 'fill_color' : newfill_color, 'points' : newPoints,
'shape_type' : newshape_type, 'flags' : newflags})
data_180 = dict_json(flags, imageData_180, newshapes, img_path_180, fillColor, lineColor, imageHeight, imageWidth)
json_file = img_path_180[:-4] + **'.json'
**json.dump(data_180, open(json_file, 'w' ))
img_rote_270 = ndimage.rotate(im, 270)
img_path_270=filename[:-4]+ **'_270.jpg'
**scipy.misc.imsave(img_path_270,img_rote_270)
imageData_270 = load_image_file(img_path_270)
imageData_270 = base64.b64encode(imageData_270).decode( 'utf-8' )
imageHeight = w
imageWidth = h
newshapes = []
for shapelabel in shapes:
newLabel = shapelabel[ 'label' ]
newline_color = shapelabel[ 'line_color' ]
newfill_color = shapelabel[ 'fill_color' ]
points = shapelabel[ 'points' ]
newPoints = [[h - float(points[1][1]), float(points[0][0])],
[h - float(points[0][1]), float(points[1][0])]]
newshape_type = shapelabel[ 'shape_type' ]
newflags = shapelabel[ 'flags' ]
newshapes.append(
{ 'label' : newLabel, 'line_color' : newline_color, 'fill_color' : newfill_color, 'points' : newPoints,
'shape_type' : newshape_type, 'flags' : newflags})
data_270 = dict_json(flags, imageData_270, newshapes, img_path_270, fillColor, lineColor, imageHeight, imageWidth)
json_file = img_path_270[:-4] + **'.json'
**json.dump(data_270, open(json_file, 'w' ))
print(filename)
img_path = 'USA'#Этот путь, где находятся все изображения
imgs = get_image_paths(img_path)
print (imgs)
for i in imgs:
create_read_img(i)
Для наборов данных, помеченных в формате txt, реализовать поворот на 90, 180 и 270 градусов.
#scipy的版本为1.0.0
import scipy
from scipy import misc
import os
import glob
from scipy import ndimage
def get_image_paths(folder):
return glob.glob(os.path.join(folder, '*.jpg'))
def create_read_img(filename):
objectList = []
with open(filename.split('.')[0] + ".txt") as f:
for line in f.readlines():
for aa in line.split(' '):
if aa!='\n':
objectList.append(aa)
im = misc.imread(filename)
h,w,d=im.shape
img_rote_90 = ndimage.rotate(im, 90)
img_path_90=filename[:-4]+'_90.jpg'
scipy.misc.imsave(img_path_90,img_rote_90)
img_path_90_txt=img_path_90[:-4]+'.txt'
outLable = ''
for i in range(int(len(objectList)/5)):
object_label = objectList[i * 5]
outLable+=object_label+' '
object_x1 = objectList[i * 5 + 1]
object_y1 = objectList[i * 5 + 2]
object_x2 = objectList[i * 5 + 3]
object_y2 = objectList[i * 5 + 4]
outLable += object_y1 + ' '
outLable += str(w-float(object_x2)) + ' '
outLable += object_y2 + ' '
outLable += str(w-float(object_x1)) + '\n'
fout = open(img_path_90_txt, 'w')
fout.write(outLable)
fout.close()
img_rote_180 = ndimage.rotate(im, 180)
img_path_180=filename[:-4]+'_180.jpg'
scipy.misc.imsave(img_path_180,img_rote_180)
img_path_180_txt = img_path_180[:-4] + '.txt'
outLable = ''
for i in range(int(len(objectList) / 5)):
object_label = objectList[i * 5]
outLable += object_label + ' '
object_x1 = objectList[i * 5 + 1]
object_y1 = objectList[i * 5 + 2]
object_x2 = objectList[i * 5 + 3]
object_y2 = objectList[i * 5 + 4]
outLable += str(w-float(object_x2)) + ' '
outLable += str(h-float(object_y2) )+ ' '
outLable += str(w-float(object_x1)) + ' '
outLable += str(h - float(object_y1)) + '\n'
fout = open(img_path_180_txt, 'w')
fout.write(outLable)
fout.close()
img_rote_270 = ndimage.rotate(im, 270)
img_path_270=filename[:-4]+'_270.jpg'
scipy.misc.imsave(img_path_270,img_rote_270)
img_path_270_txt = img_path_270[:-4] + '.txt'
outLable = ''
for i in range(int(len(objectList) / 5)):
object_label = objectList[i * 5]
outLable += object_label + ' '
object_x1 = objectList[i * 5 + 1]
object_y1 = objectList[i * 5 + 2]
object_x2 = objectList[i * 5 + 3]
object_y2 = objectList[i * 5 + 4]
outLable += str(h-float(object_y2)) + ' '
outLable += (object_x1) + ' '
outLable +=str (h-float(object_y1)) + ' '
outLable += (object_x2) + '\n'
fout = open(img_path_270_txt, 'w')
fout.write(outLable)
fout.close()
print(filename)
img_path = 'CutResult' #这个路径是所有图片在的位置
imgs = get_image_paths(img_path)
print (imgs)
for i in imgs:
create_read_img(i)