Python OpenCV LoadDatasetList,后两个参数是什么?

问题描述

我目前正在尝试使用OpenCV 4.2.2训练数据集,我在网上进行了搜索,但是只有两个参数的示例。 OpenCV 4.2.2 loadDatasetList需要4个参数,但是有一些缺点,我会尽力克服以下缺点。我最初尝试使用数组,但是loadDatasetList抱怨该数组不可迭代,然后我走了下面的代码,但运气不佳。感谢您的宝贵协助,希望所有帮助对您有所帮助。

在没有iter()的数组中传递的先前错误

PS E:\ MTCNN> python kazemi-train.py 没有提供有效的输入文件,请检查给定的文件名。 追溯(最近一次通话): 在第35行的文件“ kazemi-train.py”中 状态,images_train,landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations,imageFiles,annotationFiles) TypeError:无法解压不可迭代的布尔对象

当前错误是:

PS E:\ MTCNN> python kazemi-train.py 追溯(最近一次通话): 在第35行的文件“ kazemi-train.py”中 状态,images_train,landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations,iter(imageFiles),iter(annotationFiles)) SystemError:未设置错误就返回NULL

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',help="Path to save the kazemi trained model file",'face_landmark_model.dat'))
    parser.add_argument('--kazemi_config',help="Path to the config file for training",'config.xml'))
    parser.add_argument('--training_images',help="Path of a text file contains the list of paths to all training images",'train','images_train.txt'))
    parser.add_argument('--training_annotations',help="Path of a text file contains the list of paths to all training annotation files",'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个参数,则会引发此错误

文件“ kazemi-train.py”,第37行,状态为images_train,landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations)TypeError:loadDatasetList()缺少必需的参数“ images”(位置3) )

如果我尝试使用3个参数,则会引发此错误

回溯(最近通话最近): 在第37行的文件“ kazemi-train.py”中 状态,images_train,landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations,iter(imagePaths)) TypeError:loadDatasetList()缺少必需的参数“注释”(位置4)

loadDatasetList上的文档

OpenCV documentation on loadDatasetList

解决方法

您提供的图形涉及loadDatasetList()的C ++ API,在许多情况下,其参数通常无法映射到Python API的参数。原因之一是Python函数可以返回多个值,而C ++无法。在C ++ API中,提供了第3个和第4个参数来存储函数的输出。它们分别从imageList的文本文件中读取图像后存储图像的路径,并分别从annotationList的另一个文本文件中存储注释的路径。

回到您的问题,我在Python中找不到该函数的任何参考。而且我相信该API在OpenCV 4中已更改。经过多次试验,我确信cv2.face.loadDatasetList仅返回一个布尔值,而不返回一个元组。因此,即使您填写了四个参数,您仍然遇到了第一个错误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_trainlandmarks_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,landmarks_train = cv2.face.loadDatasetList(args.training_images,iter(imageFiles),iter(annotationFiles))

作者

status,landmarks_train = my_loadDatasetList(args.training_images,args.training_annotations)

我测试了images_trainlandmarks_train可以分别使用here中的数据加载cv2.imreadcv2.face.loadFacePoints

,

从文档中可以看到,行cv2.face.loadDatasetList仅返回布尔值,其次从参数中删除iter。函数loadDatasetList接受一个列表作为第3个和第4个参数。

所以请在您的代码中进行以下更改:

发件人:

status,iter(annotationFiles))

收件人:

status = cv2.face.loadDatasetList(args.training_images,imageFiles,annotationFiles)