Python OpenCV LoadDatasetList, что входит в последние два параметра?

#python #opencv4

#python #opencv

Вопрос:

В настоящее время я пытаюсь обучить набор данных с помощью OpenCV 4.2.2, я просмотрел веб, но есть только примеры для 2 параметров. Для OpenCV 4.2.2 loadDatasetList требуется 4 параметра, но были недостатки, которые я сделал все возможное, чтобы преодолеть с помощью следующего. Сначала я попробовал с массивом, но loadDatasetList пожаловался, что массив не поддается итерации, затем я безуспешно перешел к приведенному ниже коду. Любая помощь приветствуется спасибо за ваше время, и надеюсь, что все в безопасности и хорошо.

Предыдущая ошибка, передаваемая в массив без iter()

PS E:MTCNN > python kazemi-train.py Не было задано ни одного допустимого входного файла, пожалуйста, проверьте указанное имя файла. Трассировка (последний последний вызов): Файл «kazemi-train.py «, строка 35, в статусе, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, imageFiles, annotationFiles) Ошибка типа: не удается распаковать не итерируемый объект bool

Текущая ошибка:

PS E:MTCNN > python kazemi-train.py Трассировка (последний последний вызов): Файл «kazemi-train.py «, строка 35, в статусе, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(файлы изображений), iter(файлы аннотаций)) 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', 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 параметра, возникает эта ошибка

Файл «kazemi-train.py «, строка 37, в статусе, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations) Ошибка типа: в loadDatasetList() отсутствует обязательный аргумент ‘images’ (позиция 3)

Если я попытаюсь использовать 3 параметра, возникает эта ошибка

Трассировка (последний последний вызов): Файл «kazemi-train.py «, строка 37, в статусе, images_train, landmarks_train = cv2.face.loadDatasetList(args.training_images,args.training_annotations, iter(пути к изображениям)) Ошибка типа: в loadDatasetList() отсутствует обязательный аргумент «аннотации» (позиция 4)

Документация по loadDatasetList

Документация OpenCV по loadDatasetList

Комментарии:

1. проверьте форму

2. вам нужно предоставить только обучающие изображения и аннотации

3. я удаляю свой ответ, поскольку он не работает

4. rcvaram, я ценю помощь.

Ответ №1:

Предоставленная вами цифра относится к C API of loadDatasetList() , параметры которого обычно не могут быть сопоставлены с параметрами 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_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 , соответственно, использовать данные отсюда.

Комментарии:

1. Спасибо, я наградил вас наградой за подробное объяснение и поднял планку в ответе. Я более чем уверен, что это поможет многим другим прийти.

Ответ №2:

Из документации я вижу, что строка cv2.face.loadDatasetList возвращает только логическое значение, во-вторых, удалить 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)