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

标签 python opencv

我目前正在尝试使用 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 的文档

OpenCV documentation on loadDatasetList

最佳答案

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

回到您的问题,我在 Python 中找不到该函数的任何引用。而且我相信 API 在 OpenCV 4 中发生了变化。经过多次试验,我确信 cv2.face.loadDatasetList 只返回一个 bool 值,而不是一个元组。这就是为什么您遇到第一个错误 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, 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_trainlandmarks_train 可以通过 cv2.imreadcv2.face.loadFacePoints 加载> 分别使用来自 here 的数据.

关于Python OpenCV LoadDatasetList,最后两个参数是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64165147/

相关文章:

opencv - 为什么在 OpenCV 中没有 MaskPredicate::operator=(const MaskPredicate&) 的定义?

matlab - 用于图像处理/计算机视觉的良好且兼容的网络摄像头?

python - Python Pandas 中的日期字段之间的差异不需要 'days' 部分

python - Django 中的自动更新缓存

python - 使用 BeautifulSoup 和 Python 抓取格式不良的表中的一列

opencv - 为什么 pyplot.imshow() 改变数组中的颜色 channel

opencv - 是否有将 3 channel 垫拆分为三个 3 channel 垫而不是分成三个 1 channel 垫的内置函数?

python - 在 os.path.isfile() 中使用通配符

javascript - 如何将音频 Blob 传递到 Django 后端和服务器?

ios - OpenCV:解决PnP检测问题