目录
一、数据集相关
-
批量修改文件名
"""
批量修改文件名,给文件名加-加序号
将路径下的文件以序号命名
"""
import os
def rename_number():
count = 1
path = 'D:/rec_datasets/shan'
filename = os.listdir(path) # 获取当前路径下的文件的文件名
for files in filename:
Olddir = os.path.join(path, files) # 获取当前文件的绝对路径和名称生成绝对路径名
if os.path.isdir(Olddir):
continue
filename = os.path.splitext(files)[0] # 获取当前文件的名称
filetype = os.path.splitext(files)[1] # 获取当前文件的后缀名
if filetype == '.py':
continue # 忽略.py结尾的文件
Newdir = os.path.join(path, filename + "_" + str(count) + filetype) # 根据count编号给文件新命名
os.rename(Olddir, Newdir) # 用新的名称替换之前的名称
count += 1 # 计数加1
rename_number()
-
数据集格式转换json转txt
'''
labelme标注车牌四个点,转换成label x y w h x1 y1 x2 y2 x3 y3 x4 y4
'''
import json
import os
import numpy as np
from copy import deepcopy
import cv2
def allFilePath(rootPath,allFIleList):
fileList = os.listdir(rootPath)
for temp in fileList:
if os.path.isfile(os.path.join(rootPath,temp)):
allFIleList.append(os.path.join(rootPath,temp))
else:
allFilePath(os.path.join(rootPath,temp),allFIleList)
def xywh2yolo(rect,landmarks_sort,img):
h,w,c =img.shape
rect[0] = max(0, rect[0])
rect[1] = max(0, rect[1])
rect[2] = min(w - 1, rect[2]-rect[0])
rect[3] = min(h - 1, rect[3]-rect[1])
annotation = np.zeros((1, 12))
annotation[0, 0] = (rect[0] + rect[2] / 2) / w # cx
annotation[0, 1] = (rect[1] + rect[3] / 2) / h # cy
annotation[0, 2] = rect[2] / w # w
annotation[0, 3] = rect[3] / h # h
annotation[0, 4] = landmarks_sort[0][0] / w # l0_x
annotation[0, 5] = landmarks_sort[0][1] / h # l0_y
annotation[0, 6] = landmarks_sort[1][0] / w # l1_x
annotation[0, 7] = landmarks_sort[1][1] / h # l1_y
annotation[0, 8] = landmarks_sort[2][0] / w # l2_x
annotation[0, 9] = landmarks_sort[2][1] / h # l2_y
annotation[0, 10] = landmarks_sort[3][0] / w # l3_x
annotation[0, 11] = landmarks_sort[3][1] / h # l3_y
# annotation[0, 12] = (landmarks_sort[0][0]+landmarks_sort[1][0])/2 / w # l4_x
# annotation[0, 13] = (landmarks_sort[0][1]+landmarks_sort[1][1])/2 / h # l4_y
return annotation
def order_points(pts):
rect = np.zeros((4, 2), dtype = "float32")
s = pts.sum(axis = 1)
rect[0] = pts[np.argmin(s)]
rect[2] = pts[np.argmax(s)]
diff = np.diff(pts, axis = 1)
rect[1] = pts[np.argmin(diff)]
rect[3] = pts[np.argmax(diff)]
# return the ordered coordinates
return rect
def four_point_transform(image, pts):
rect = order_points(pts)
(tl, tr, br, bl) = rect
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max(int(widthA), int(widthB))
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max(int(heightA), int(heightB))
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, maxHeight - 1],
[0, maxHeight - 1]], dtype = "float32")
M = cv2.getPerspectiveTransform(rect, dst)
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
# return the warped image
return warped
if __name__ == "__main__":
pic_file_list = []
pic_file = r"E:/License_Plate_Recognition/datasets/own_datasets/pic"
save_small_path = "small"
#label_file = ['single','double']
label_file = ['carplate']
allFilePath(pic_file,pic_file_list)
count=0
index = 0
for pic_ in pic_file_list:
if not pic_.endswith(".jpg"):
continue
count+=1
img = cv2.imread(pic_)
img_name = os.path.basename(pic_)
txt_name = img_name.replace(".jpg",".txt")
txt_path = os.path.join(pic_file,txt_name)
json_file_ = pic_.replace(".jpg",".json")
if not os.path.exists(json_file_):
continue
with open(json_file_, 'r',encoding='utf-8') as a:
data_dict = json.load(a)
# print(data_dict['shapes'])
with open(txt_path,"w") as f:
for data_message in data_dict['shapes']:
index+=1
label=data_message['label']
points = data_message['points']
pts = np.array(points)
pts=order_points(pts)
new_img = four_point_transform(img,pts)
roi_img_name = label+"_"+str(index)+".jpg"
save_path=os.path.join(save_small_path,roi_img_name)
# cv2.imwrite(save_path,new_img)
x_max,y_max = np.max(pts,axis=0)
x_min,y_min = np.min(pts,axis=0)
rect = [x_min,y_min,x_max,y_max]
rect1=deepcopy(rect)
annotation=xywh2yolo(rect1,pts,img)
print(data_message)
label = data_message['label']
str_label = label_file.index(label)
# str_label = "0 "
str_label = str(str_label)+" "
for i in range(len(annotation[0])):
str_label = str_label + " " + str(annotation[0][i])
str_label = str_label.replace('[', '').replace(']', '')
str_label = str_label.replace(',', '') + '\n'
f.write(str_label)
print(count,img_name)
# point=data_message[points]
-
制作车牌检测数据集
import os
import glob
import cv2
from pathlib import Path
import numpy as np
root_dir="" #图片文件
txt_dir="" #标签文件
# 文件名命名和CCPD相同
use_landmarks=True #用于车牌定位,如MTCNN、YOLO5Face,cls,x,y,w,h,four points
use_xywh=False #用于车牌检测,如YOLO等 cls,x,y,w,h
use_ocr=False #用于识别 车牌号
os.makedirs(txt_dir,exist_ok=True)
#返回中心点坐标、宽、高以及四个顶点的位置信息共12个信息,可用于mtcnn或yolo5Face检测定位车牌
def ccpd_landmarks(points_list,imgw,imgh):
'''
Args:
points_list: 车牌四个顶点的位置信息
imgw: 图片宽度
imgh: 图片高度
Returns:
'''
annotation=np.zeros((1,12))
points_list_=[]
#得到四个端点
for points in points_list.split("_"):
points_=list(map(int,points.split("&")))
points_list_.append(points_)
points_list_=np.array(points_list_)
#获的box的坐标
xmin=min(points_list_[:,0])
xmax=max(points_list_[:,0])
ymin=min(points_list_[:,1])
ymax=max(points_list_[:,1])
dw=1./imgw
dh=1./imgh
w,h=xmax-xmin,ymax-ymin
#生成对应的信息列表
annotation[0,0]=((xmin+xmax)/2.-1)*dw #cx
annotation[0,1]=((ymin+ymax)/2.-1)*dh #cy
annotation[0,2]=w*dw #w
annotation[0,3]=h*dh #h
annotation[0,4]=points_list_[2][0]/imgw #左上x
annotation[0,5]=points_list_[2][1]/imgh #左上y
annotation[0,6]=points_list_[3][0]/imgw #右上x
annotation[0,7]=points_list_[3][1]/imgh #右上y
annotation[0,8]=points_list_[0][0]/imgw #右下x
annotation[0,9]=points_list_[0][1]/imgh #右上y
annotation[0,10]=points_list_[1][0]/imgw #左下x
annotation[0,11]=points_list_[1][1]/imgh #左下y
return annotation
#仅返回图片的中心点坐标以及宽高信息,可用于YOLO系列检测车牌
def ccpd_xywh(points_list,imgw,imgh):
'''
Args:
points_list: 车牌四个顶点的位置信息
imgw: 图片宽度
imgh: 图片高度
Returns:
'''
annotation = np.zeros((1, 4))
points_list_ = []
# 得到四个端点
for points in points_list.split("_"):
points_ = list(map(int, points.split("&")))
points_list_.append(points_)
points_list_ = np.array(points_list_)
#获的box的坐标
xmin=min(points_list_[:,0])
xmax=max(points_list_[:,0])
ymin=min(points_list_[:,1])
ymax=max(points_list_[:,1])
dw=1./imgw
dh=1./imgh
w,h=xmax-xmin,ymax-ymin
# 生成对应的信息列表
annotation[0, 0] = ((xmin + xmax) / 2. - 1) * dw # cx
annotation[0, 1] = ((ymin + ymax) / 2. - 1) * dh # cy
annotation[0, 2] = w * dw # w
annotation[0, 3] = h * dh # h
return annotation
#返回对应的文本信息,可用于ocr识别车牌
def ccpd_ocr(plate):
'''
Args:
plate: 文件名中的数字
Returns:
'''
#车牌字典
#省
provinces = ["皖", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑", "苏", "浙", "京", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤",
"桂", "琼", "川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新", "警", "学", "O"]
#具体信息
word_lists = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W','X', 'Y', 'Z', 'O', '1', '2', '3', '4', '5', '6', '7', '8', '9','0']
label_list=plate.split("_")
print(len(label_list))
result=""
result+=provinces[int(label_list[0])]
result+=word_lists[int(label_list[1])]
result+=word_lists[int(label_list[2])]+word_lists[int(label_list[3])]+word_lists[int(label_list[4])]+\
word_lists[int(label_list[5])]+word_lists[int(label_list[6])]
return result
def ccpd2label(all_list):
for imgpath in all_list:
img=cv2.imread(imgpath)
h,w=img.shape[:2]
imgname=Path(imgpath).name
points_list,plate_list=imgname.split("-")[3],imgname.split("-")[4]#四个关键点的坐标[右下、左下、左上、右上],车牌号映射表
if use_landmarks:
annotation=ccpd_landmarks(points_list,w,h) #获得要写入txt的信息
txtname = imgname.replace(".jpg", ".txt")
txt_path = os.path.join(txt_dir, txtname)
str_label = "0" # 类别默认为0
with open(txt_path, "a+") as fw:
for i in range(len(annotation[0])):
str_label = str_label + " " + str(annotation[0][i])
fw.write(str_label)
elif use_xywh:
annotation=ccpd_xywh(points_list,w,h) #获得要写入txt的信息
txtname = imgname.replace(".jpg", ".txt")
txt_path = os.path.join(txt_dir, txtname)
str_label = "0" # 类别默认为0
with open(txt_path, "a+") as fw:
for i in range(len(annotation[0])):
str_label = str_label + " " + str(annotation[0][i])
fw.write(str_label)
elif use_ocr:
ocr_label=ccpd_ocr(plate_list)
txtname=imgname.replace(".jpg",".txt")
txt_path=os.path.join(txt_dir,txtname)
with open(txt_path,"a+") as fw:
fw.write(ocr_label)
if __name__ == '__main__':
image_list=glob.glob(root_dir+os.sep+"*.jpg")
ccpd2label(image_list)
-
制作车牌识别数据集
'''
透射并裁剪车牌区域
'''
import numpy as np
import cv2
import os
words_list = [
"A", "B", "C", "D", "E",
"F", "G", "H", "J", "K",
"L", "M", "N", "P", "Q",
"R", "S", "T", "U", "V",
"W", "X", "Y", "Z", "0",
"1", "2", "3", "4", "5",
"6", "7", "8", "9"
]
con_list = [
"皖", "沪", "津", "渝", "冀",
"晋", "蒙", "辽", "吉", "黑",
"苏", "浙", "京", "闽", "赣",
"鲁", "豫", "鄂", "湘", "粤",
"桂", "琼", "川", "贵", "云",
"西", "陕", "甘", "青", "宁",
"新"
]
def order_points(pts):
# 初始化坐标点
rect = np.zeros((4, 2), dtype='float32')
# 获取左上角和右下角坐标点
s = pts.sum(axis=1) # 每行像素值进行相加;若axis=0,每列像素值相加
rect[0] = pts[np.argmin(s)] # top_left,返回s首个最小值索引,eg.[1,0,2,0],返回值为1
rect[2] = pts[np.argmax(s)] # bottom_left,返回s首个最大值索引,eg.[1,0,2,0],返回值为2
# 分别计算左上角和右下角的离散差值
diff = np.diff(pts, axis=1) # 第i+1列减第i列
rect[1] = pts[np.argmin(diff)]
rect[3] = pts[np.argmax(diff)]
return rect
def four_point_transform(image, pts):
# 获取坐标点,并将它们分离开来
rect = order_points(pts)
(tl, tr, br, bl) = rect
# 计算新图片的宽度值,选取水平差值的最大值
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max(int(widthA), int(widthB))
# 计算新图片的高度值,选取垂直差值的最大值
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max(int(heightA), int(heightB))
# 构建新图片的4个坐标点,左上角为原点
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, maxHeight - 1],
[0, maxHeight - 1]], dtype="float32")
# 获取透视变换矩阵并应用它
M = cv2.getPerspectiveTransform(rect, dst)
# 进行透视变换
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
# 返回变换后的结果
return warped
if __name__ == "__main__":
global points
total = []
for filename in os.listdir(os.path.join('E:/License_Plate_Recognition/datasets/CCPD2019/ccpd_rotate/')):
img = cv2.imread('E:/License_Plate_Recognition/datasets/CCPD2019/ccpd_rotate/' + filename)
_, _, bbox, points, label, _, _ = filename.split('-')
# 提取四个点坐标
points = points.split('_')
tmp = points
points = []
for _ in tmp:
points.append([int(_.split('&')[0]), int(_.split('&')[1])])
# print(points)
# 提取车牌号
label = label.split('_')
con = con_list[int(label[0])]
words = [words_list[int(_)] for _ in label[1:]]
label = con + ''.join(words)
line = filename + '\t' + label
line = line[:] + '\n'
total.append(line)
# 还原像素位置
points = np.array(points, dtype=np.float32)
warped = four_point_transform(img, points)
# save_path = os.path.join('E:/License_Plate_Recognition/datasets/own_datasets/images_roi', filename)
# cv2.imwrite(save_path, warped)
cv2.imencode('.jpg', warped)[1].tofile(
r"E:/License_Plate_Recognition/datasets/CCPD2019/ccpd_tilt_roi/{}.jpg".format(label))
with open('E:/License_Plate_Recognition/datasets/CCPD2019/' + 'ccpd_rotate.txt', 'w', encoding='UTF-8') as f:
for line in total:
f.write(line)
-
识别数据集标签crnn
import cv2
import imageio
import numpy as np
import os
import shutil
import argparse
# from alphabets import plate_chr
def allFileList(rootfile,allFile):
folder =os.listdir(rootfile)
for temp in folder:
fileName = os.path.join(rootfile,temp)
if os.path.isfile(fileName):
allFile.append(fileName)
else:
allFileList(fileName,allFile)
def is_str_right(plate_name):
for str_ in plate_name:
if str_ not in palteStr:
return False
return True
if __name__=="__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--image_path', type=str, default="E:\License_Plate_Recognition\datasets\own_datasets/rec", help='source')
parser.add_argument('--label_file', type=str, default='E:\License_Plate_Recognition\datasets\own_datasets/rec/labels.txt', help='model.pt path(s)')
opt = parser.parse_args()
rootPath = opt.image_path
labelFile = opt.label_file
# palteStr=r"#京沪津渝冀晋蒙辽吉黑苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云藏陕甘青宁新学警港澳挂使领民深危险品0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
plate_chr="#京沪津渝冀晋蒙辽吉黑苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云藏陕甘青宁新学警港澳挂使领民航危0123456789ABCDEFGHJKLMNPQRSTUVWXYZ险品"
palteStr=plate_chr
print(len(palteStr))
plateDict ={}
for i in range(len(list(palteStr))):
plateDict[palteStr[i]]=i
fp = open(labelFile,"w",encoding="utf-8")
file =[]
allFileList(rootPath,file)
picNum = 0
for jpgFile in file:
print(jpgFile)
jpgName = os.path.basename(jpgFile)
name =jpgName.split("_")[0]
if " " in name:
continue
labelStr=" "
if not is_str_right(name):
continue
strList = list(name)
for i in range(len(strList)):
labelStr+=str(plateDict[strList[i]])+" "
# while i<7:
# labelStr+=str(0)+" "
# i+=1
picNum+=1
# print(jpgFile+labelStr)
fp.write(jpgFile+labelStr+"\n")
fp.close()
-
统计训练数据集中各省份数量分布
import os
import shutil
def allFilePath(rootPath,allFIleList):
fileList = os.listdir(rootPath)
for temp in fileList:
if os.path.isfile(os.path.join(rootPath,temp)):
allFIleList.append(os.path.join(rootPath,temp))
else:
allFilePath(os.path.join(rootPath,temp),allFIleList)
if __name__=="__main__":
# palteStr=r"京沪津渝冀晋蒙辽吉黑苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云藏陕甘青宁新学警港澳挂使领民"
palteStr = r"京沪津渝冀晋蒙辽吉黑苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云藏陕甘青宁新" #31省
file_path =r"D:/rec_datasets/train_new_balance"
file_list=[]
pro_dict={}
for province in palteStr:
pro_dict[province]=0
# print(pro_dict)
save_folder="save_train"
allFilePath(file_path,file_list)
index=0
error=0
for file in file_list:
index+=1
try:
plate_name=os.path.basename(file).split("_")[0]
pro_dict.get(plate_name[-1],0)
if plate_name[-1] in ["警","港","澳","学","挂","领"]:
pro_dict[plate_name[-1]]+=1
else:
pro_dict[plate_name[0]]+=1
except:
error+=1
# print(plate_name,"error")
a = sorted(pro_dict.items(), key=lambda x: x[1],reverse=True)
# print(a)
for key in a:
print(key)