预测部分代码
# /=== === === ===> 3:预测stage-start <=== === === ===\
# /=== ===> 1)测试准备,提取特征,预测 <=== ===\
def predict_stage(test_feat_path):
shutil.rmtree(test_feat_path)
mkdir_test()
extra_feat_test() # 获取测试特征并保存在文件夹
# nk_predict() # 多张图片的预测,非实时
clf = joblib.load(model_path + 'model') # 直接进行加载模型 不进行训练 joblib.load.predict
nk_predict()
# \=== ===> 1)测试准备,提取特征,测试 <=== ===/
# /=== ===> 2)提取特征 <=== ===\test
def extra_feat_test():
t_extra0 = time.time()
test_name, test_label = get_name_label(test_label_path)
test_image = get_image_list(test_image_path, test_name)
get_feat(test_image, test_name, test_label, test_feat_path)
t_extra1 = time.time()
print('测试特征提取结束,', '特征提取耗时是 : %f' % (t_extra1 - t_extra0) + '\n')
# =>下面部分: 与上面训练部分同, 因而注释掉
# =>从txt获得'图片名称list',对应的'类别list'
'''
def get_name_label(file_path): # file_path = train_label_path = image\train.txt
print("read label from ", file_path)
name_list = [] # 用于存储名字的列表
label_list = [] # 用于存储标签的列表
with open(file_path) as f:
for line in f.readlines():
# 一般是name label 三部分,所以至少长度为3 所以可以通过这个方法来忽略空白行
if len(line) >= 3:
name_list.append(line.split(' ')[0]) # 以空格划分为两部分,前面部分为[0], 后面为[1]
label_list.append(line.split(' ')[1].replace('\n', '').replace('\r', ''))
# \r代表回车,\n代表换行, 都替换成'', 也就是去掉
if not str(label_list[-1]).isdigit():
# 因为[-1]是最后一个, 而每次append的最后一个都是最新的,检查它如果不是数字就报错
print("label必须为数字,得到的是:", label_list[-1], "程序终止,请检查文件")
exit(1)
return name_list, label_list
# 得到了两个列表,分别对应顺序放置 名字,标签 也是就是形如:
# name_list=['tbj1.jpg', 'tbj2.jpg',..., 'dw1.jpg']
# label_list=[1,1,...,2]
'''
# =>获得'图片list'
'''
def get_image_list(filePath, nameList):
# x1: filePath = train_image_path = image\
# x2: nameList = train_name = name_list 也就是上一个函数的第一个返回值, name_list=['tbj1.jpg', 'tbj2.jpg',..., 'dw1.jpg']
print('read image from ', filePath)
img_list = []
for name in nameList:
temp = Image.open(os.path.join(filePath, name)) # 形成一个完整的具体图片路径image\tbj1, 然后用Image打开
# print('测试是否有后缀.jpg', os.path.join(filePath, name)) # txt文件在起名字的时候就要写成dw1.jpg
# 测试是否有后缀.jpg image/337-4.jpg
# 这里我为了统计4个人一个人有几个照片起名方式为:337-4.jpg, 4表示第4个人zjc, 337表示这个人的第337个照片,上面列表dw1.jpg只是示意
img_list.append(temp.copy()) # 把这个图片copy出来,送进列表
temp.close() # 关掉这个,进行下一个图片的copy
# print('img_list[0]里面内容的格式', type(img_list[0]))
# img_list[0]里面内容的格式 <class 'PIL.Image.Image'>
# img_list = [<class 'PIL.Image.Image'>,...,<class 'PIL.Image.Image'>]
return img_list
'''
# =>提取特征并保存
'''
def get_feat(image_list, name_list, label_list, savePath):
# x1: image_list = train_image = img_list
# 也就上一个函数def get_image_list 的返回值list放到是<class 'PIL.Image.Image'>格式的图片
# x2: name_list = train_name 是def get_name_label的第一个返回值name_list=['tbj1.jpg', 'tbj2.jpg',..., 'dw1.jpg']
# x3: label_list = train_label 是def get_name_label的第二个返回值label_list = [1,1,...,2]
# x4: savePath = train_feat_path = train/ 特征被保存在这里
i = 0
for image in image_list:
try:
image = image.resize((64, 128)) # 调整图片大小,因为人高近似是宽的2倍
# 如果是灰度图片 把3改为-1
image = np.reshape(image, (image_height, image_width, 3))
except:
print('发送了异常,图片大小size不满足要求:', name_list[i])
continue
gray = rgb2gray(image) / 255.0
# 提取hog特征, 根据需求改, 这句话根据你的尺寸改改
fd = hog(gray, orientations=12, block_norm='L1', pixels_per_cell=[8, 8], cells_per_block=[4, 4],
visualize=False,
transform_sqrt=True)
# =>fd就是后面 ===> 3)训练 <=== 里面的data = job.lib.load()
# 将image_list里面<class 'PIL.Image.Image'>格式图片resize, np.reshape之后与label_list = [1,1,...,2]对应
fd_name = name_list[i] + '.feat' # 对应名字name_list=['tbj1.jpg', 'tbj2.jpg',..., 'dw1.jpg']加后缀
fd_path = os.path.join(savePath, fd_name) # 前面加train/保存路径 = train/dw1.jpg.feat
# print('fd_path', fd_path) # train/001-1.jpg.feat
joblib.dump(fd, fd_path) # =>把相应的特征fd保存在对应的train/dw1.jpg.feat文件里面, 通过joblib的dump可以将模型保存到本地
i += 1
print("Test features are extracted and saved.")
'''
# =>变成灰度图片
'''
def rgb2gray(im):
gray = im[:, :, 0] * 0.2989 + im[:, :, 1] * 0.5870 + im[:, :, 2] * 0.1140
return gray
'''
# \=== ===> 2)提取特征 <=== ===/
# /=== ===> 3)预测 <=== ===\
def nk_predict():
correct_number = 0
total = 0
clf = joblib.load(model_path + 'model') # 直接进行加载模型 不进行训练
t_predict0 = time.time()
result_list = []
for feat_path in glob.glob(os.path.join(test_feat_path, '*.feat')):
total += 1
if platform.system() == 'Windows':
symbol = '\\'
else:
symbol = '/'
image_name = feat_path.split(symbol)[1].split('.feat')[0]
data_test = joblib.load(feat_path)
data_test_feat = data_test[:-1].reshape((1, -1)).astype(np.float64)
result = clf.predict(data_test_feat)
result_list.append(image_name + ' ' + label_map[int(result[0])] + '\n')
if int(result[0]) == int(data_test[-1]):
correct_number += 1
write_to_txt(result_list)
rate = float(correct_number) / total
t_predict1 = time.time()
print('准确率是: %f' % rate + ' ', '预测耗时是 : %f' % (t_predict1 - t_predict0))
# \=== ===> 3)预测 <=== ===/
# /=== ===> 4)txt记录 <=== ===\
def write_to_txt(list):
with open('result.txt', 'w') as f:
f.writelines(list)
print('每张图片的识别结果存放在result.txt里面' + '\n')
# \=== ===> 4)txt记录 <=== ===/