#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
Комментарии:
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)