Python OpenCV LoadDatasetList,最后两个参数是什么?
Python OpenCV LoadDatasetList, what goes into last two parameters?
我目前正在尝试使用 OpenCV 4.2.2 训练数据集,我在网上搜索了一下,但只有 2 个参数的示例。 OpenCV 4.2.2 loadDatasetList 需要 4 个参数,但存在一些缺点,我尽力通过以下方法克服这些缺点。我首先尝试使用数组,但 loadDatasetList 抱怨该数组不可迭代,然后我继续执行下面的代码但没有成功。感谢您的帮助,感谢您的宝贵时间,并希望每个人都平安无事。
在没有iter()的情况下传入数组的先前错误
PS E:\MTCNN> python kazemi-train.py
No valid input file was given, please check the given filename.
Traceback (most recent call last):
File "kazemi-train.py", line 35, in
status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, imageFiles, annotationFiles)
TypeError: cannot unpack non-iterable bool object
当前错误为:
PS E:\MTCNN> python kazemi-train.py
Traceback (most recent call last):
File "kazemi-train.py", line 35, in
status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imageFiles), iter(annotationFiles))
SystemError: returned NULL without setting an error
import os
import time
import cv2
import numpy as np
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Training of kazemi facial landmark algorithm.')
parser.add_argument('--face_cascade', type=str, help="Path to the cascade model file for the face detector",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'models','haarcascade_frontalface_alt2.xml'))
parser.add_argument('--kazemi_model', type=str, help="Path to save the kazemi trained model file",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'models','face_landmark_model.dat'))
parser.add_argument('--kazemi_config', type=str, help="Path to the config file for training",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'models','config.xml'))
parser.add_argument('--training_images', type=str, help="Path of a text file contains the list of paths to all training images",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'train','images_train.txt'))
parser.add_argument('--training_annotations', type=str, help="Path of a text file contains the list of paths to all training annotation files",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'train','points_train.txt'))
parser.add_argument('--verbose', action='store_true')
args = parser.parse_args()
start = time.time()
facemark = cv2.face.createFacemarkKazemi()
if args.verbose:
print("Creating the facemark took {} seconds".format(time.time()-start))
start = time.time()
imageFiles = []
annotationFiles = []
for file in os.listdir("./AppendInfo"):
if file.endswith(".jpg"):
imageFiles.append(file)
if file.endswith(".txt"):
annotationFiles.append(file)
status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imageFiles), iter(annotationFiles))
assert(status == True)
if args.verbose:
print("Loading the dataset took {} seconds".format(time.time()-start))
scale = np.array([460.0, 460.0])
facemark.setParams(args.face_cascade,args.kazemi_model,args.kazemi_config,scale)
for i in range(len(images_train)):
start = time.time()
img = cv2.imread(images_train[i])
if args.verbose:
print("Loading the image took {} seconds".format(time.time()-start))
start = time.time()
status, facial_points = cv2.face.loadFacePoints(landmarks_train[i])
assert(status == True)
if args.verbose:
print("Loading the facepoints took {} seconds".format(time.time()-start))
start = time.time()
facemark.addTrainingSample(img,facial_points)
assert(status == True)
if args.verbose:
print("Adding the training sample took {} seconds".format(time.time()-start))
start = time.time()
facemark.training()
if args.verbose:
print("Training took {} seconds".format(time.time()-start))
如果我只使用 2 个参数,则会引发此错误
File "kazemi-train.py", line 37, in status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations) TypeError: loadDatasetList() missing required argument 'images' (pos 3)
如果我尝试使用 3 个参数,则会引发此错误
Traceback (most recent call last):
File "kazemi-train.py", line 37, in
status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imagePaths))
TypeError: loadDatasetList() missing required argument 'annotations' (pos 4)
关于 loadDatasetList 的文档
您提供的图参考了loadDatasetList()
的C++API,其参数在很多情况下通常不能映射到PythonAPI的参数。一个原因是 Python 函数可以 return 多个值,而 C++ 不能。在C++API中,提供了第三个和第四个参数来存储函数的输出。它们分别在imageList中读取文本文件后存储图像的路径,并在annotationList中读取另一个文本文件中的注释路径。
回到你的问题,我在 Python 中找不到该函数的任何参考。而且我相信 API 在 OpenCV 4 中发生了变化。经过多次试验,我确信 cv2.face.loadDatasetList
return 只是一个布尔值,而不是一个元组。这就是为什么你遇到第一个错误 TypeError: cannot unpack non-iterable bool object
即使你填写了四个参数。
毫无疑问,cv2.face.loadDatasetList
应该会产生两个文件路径列表。因此,第一部分的代码应如下所示:
images_train = []
landmarks_train = []
status = cv2.face.loadDatasetList(args.training_images, args.training_annotations, images_train, landmarks_train)
我希望 images_train
和 landmarks_train
应该包含图像和地标注释的文件路径,但它没有按预期工作。
理解了整个程序后,我写了一个新函数my_loadDatasetList
来替换(损坏的)cv2.face.loadDatasetList
。
def my_loadDatasetList(text_file_images, text_file_annotations):
status = False
image_paths, annotation_paths = [], []
with open(text_file_images, "r") as a_file:
for line in a_file:
line = line.strip()
if line != "":
image_paths.append(line)
with open(text_file_annotations, "r") as a_file:
for line in a_file:
line = line.strip()
if line != "":
annotation_paths.append(line)
status = len(image_paths) == len(annotation_paths)
return status, image_paths, annotation_paths
您现在可以替换
status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imageFiles), iter(annotationFiles))
来自
status, images_train, landmarks_train = my_loadDatasetList(args.training_images, args.training_annotations)
我测试过 images_train
和 landmarks_train
可以分别由 cv2.imread
和 cv2.face.loadFacePoints
使用来自 here.[=27= 的数据加载]
从文档中,我可以看到 cv2.face.loadDatasetList
returns 行只是一个布尔值,然后从参数中删除 iter
。函数 loadDatasetList 接受一个列表作为第 3 个和第 4 个参数。
所以请在您的代码中进行以下更改:
发件人:
status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imageFiles), iter(annotationFiles))
收件人:
status = cv2.face.loadDatasetList(args.training_images,args.training_annotations, imageFiles, annotationFiles)
我目前正在尝试使用 OpenCV 4.2.2 训练数据集,我在网上搜索了一下,但只有 2 个参数的示例。 OpenCV 4.2.2 loadDatasetList 需要 4 个参数,但存在一些缺点,我尽力通过以下方法克服这些缺点。我首先尝试使用数组,但 loadDatasetList 抱怨该数组不可迭代,然后我继续执行下面的代码但没有成功。感谢您的帮助,感谢您的宝贵时间,并希望每个人都平安无事。
在没有iter()的情况下传入数组的先前错误
PS E:\MTCNN> python kazemi-train.py No valid input file was given, please check the given filename. Traceback (most recent call last): File "kazemi-train.py", line 35, in status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, imageFiles, annotationFiles) TypeError: cannot unpack non-iterable bool object
当前错误为:
PS E:\MTCNN> python kazemi-train.py Traceback (most recent call last): File "kazemi-train.py", line 35, in status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imageFiles), iter(annotationFiles)) SystemError: returned NULL without setting an error
import os
import time
import cv2
import numpy as np
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Training of kazemi facial landmark algorithm.')
parser.add_argument('--face_cascade', type=str, help="Path to the cascade model file for the face detector",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'models','haarcascade_frontalface_alt2.xml'))
parser.add_argument('--kazemi_model', type=str, help="Path to save the kazemi trained model file",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'models','face_landmark_model.dat'))
parser.add_argument('--kazemi_config', type=str, help="Path to the config file for training",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'models','config.xml'))
parser.add_argument('--training_images', type=str, help="Path of a text file contains the list of paths to all training images",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'train','images_train.txt'))
parser.add_argument('--training_annotations', type=str, help="Path of a text file contains the list of paths to all training annotation files",
default=os.path.join(os.path.dirname(os.path.realpath(__file__)),'train','points_train.txt'))
parser.add_argument('--verbose', action='store_true')
args = parser.parse_args()
start = time.time()
facemark = cv2.face.createFacemarkKazemi()
if args.verbose:
print("Creating the facemark took {} seconds".format(time.time()-start))
start = time.time()
imageFiles = []
annotationFiles = []
for file in os.listdir("./AppendInfo"):
if file.endswith(".jpg"):
imageFiles.append(file)
if file.endswith(".txt"):
annotationFiles.append(file)
status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imageFiles), iter(annotationFiles))
assert(status == True)
if args.verbose:
print("Loading the dataset took {} seconds".format(time.time()-start))
scale = np.array([460.0, 460.0])
facemark.setParams(args.face_cascade,args.kazemi_model,args.kazemi_config,scale)
for i in range(len(images_train)):
start = time.time()
img = cv2.imread(images_train[i])
if args.verbose:
print("Loading the image took {} seconds".format(time.time()-start))
start = time.time()
status, facial_points = cv2.face.loadFacePoints(landmarks_train[i])
assert(status == True)
if args.verbose:
print("Loading the facepoints took {} seconds".format(time.time()-start))
start = time.time()
facemark.addTrainingSample(img,facial_points)
assert(status == True)
if args.verbose:
print("Adding the training sample took {} seconds".format(time.time()-start))
start = time.time()
facemark.training()
if args.verbose:
print("Training took {} seconds".format(time.time()-start))
如果我只使用 2 个参数,则会引发此错误
File "kazemi-train.py", line 37, in status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations) TypeError: loadDatasetList() missing required argument 'images' (pos 3)
如果我尝试使用 3 个参数,则会引发此错误
Traceback (most recent call last): File "kazemi-train.py", line 37, in status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imagePaths)) TypeError: loadDatasetList() missing required argument 'annotations' (pos 4)
关于 loadDatasetList 的文档
您提供的图参考了loadDatasetList()
的C++API,其参数在很多情况下通常不能映射到PythonAPI的参数。一个原因是 Python 函数可以 return 多个值,而 C++ 不能。在C++API中,提供了第三个和第四个参数来存储函数的输出。它们分别在imageList中读取文本文件后存储图像的路径,并在annotationList中读取另一个文本文件中的注释路径。
回到你的问题,我在 Python 中找不到该函数的任何参考。而且我相信 API 在 OpenCV 4 中发生了变化。经过多次试验,我确信 cv2.face.loadDatasetList
return 只是一个布尔值,而不是一个元组。这就是为什么你遇到第一个错误 TypeError: cannot unpack non-iterable bool object
即使你填写了四个参数。
毫无疑问,cv2.face.loadDatasetList
应该会产生两个文件路径列表。因此,第一部分的代码应如下所示:
images_train = []
landmarks_train = []
status = cv2.face.loadDatasetList(args.training_images, args.training_annotations, images_train, landmarks_train)
我希望 images_train
和 landmarks_train
应该包含图像和地标注释的文件路径,但它没有按预期工作。
理解了整个程序后,我写了一个新函数my_loadDatasetList
来替换(损坏的)cv2.face.loadDatasetList
。
def my_loadDatasetList(text_file_images, text_file_annotations):
status = False
image_paths, annotation_paths = [], []
with open(text_file_images, "r") as a_file:
for line in a_file:
line = line.strip()
if line != "":
image_paths.append(line)
with open(text_file_annotations, "r") as a_file:
for line in a_file:
line = line.strip()
if line != "":
annotation_paths.append(line)
status = len(image_paths) == len(annotation_paths)
return status, image_paths, annotation_paths
您现在可以替换
status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imageFiles), iter(annotationFiles))
来自
status, images_train, landmarks_train = my_loadDatasetList(args.training_images, args.training_annotations)
我测试过 images_train
和 landmarks_train
可以分别由 cv2.imread
和 cv2.face.loadFacePoints
使用来自 here.[=27= 的数据加载]
从文档中,我可以看到 cv2.face.loadDatasetList
returns 行只是一个布尔值,然后从参数中删除 iter
。函数 loadDatasetList 接受一个列表作为第 3 个和第 4 个参数。
所以请在您的代码中进行以下更改:
发件人:
status, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(imageFiles), iter(annotationFiles))
收件人:
status = cv2.face.loadDatasetList(args.training_images,args.training_annotations, imageFiles, annotationFiles)