Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Python
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.02.2020, 21:49   #1
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию Обработка растровых изображений с применением библиотеки OpenCV: проблемы с LBPHFaceRecognizer и библиотекой pillow

Добрый вечер, форумчане! Я пытаюсь сделать программу для обнаружения лиц по инструкциям на этом сайте
https://robotos.in/uroki/obnaruzheni...itsa-na-python
но на этапе тренировки возникли проблемы. Все папки созданы, xml-образы лежат на своих местах и библиотека pillow уже стоит, но почему-то PyCharm ругается на отсутствие атрибута face в библиотеке cv2. Сможете показать, где и что нужно исправить, нужна ли точка с запятой после создания объекта CascadeClassifier и как правильно ставить pillow на анаконду? Использую Anaconda 2019 Prompt, PyCharm Community, OpenCV 4.1.2 и Python 3.7.

Исходный код:
Код:
import cv2
import numpy as np
from PIL import Image
import os
 
# Path for face image database
path = 'dataset'
 
recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");
 
# function to get the images and label data
def getImagesAndLabels(path):
    imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
    faceSamples=[]
    ids = []
    for imagePath in imagePaths:
        PIL_img = Image.open(imagePath).convert('L')
        # convert it to grayscale
        img_numpy = np.array(PIL_img, 'uint8')
        id = int(os.path.split(imagePath)[-1].split(".")[1])
        faces = detector.detectMultiScale(img_numpy)
        for (x, y, w, h) in faces:
            faceSamples.append(img_numpy[y:y+h, x:x+w])
            ids.append(id)
    return faceSamples, ids
 
print ("\n [INFO] Training faces. It will take a few seconds. Wait ...")
faces, ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))
 
# Save the model into trainer/trainer.yml
recognizer.write('trainer/trainer.yml')
# recognizer.save() worked on Mac, but not on Pi
 
# Print the numer of faces trained and end program
print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))
Ошибки:
Код:
D:\Python\python.exe C:/demo4/opencv_demo4.py
Traceback (most recent call last):
  File "C:/demo4/opencv_demo4.py", line 9, in <module>
    recognizer = cv2.face.LBPHFaceRecognizer_create()
AttributeError: module 'cv2' has no attribute 'face'
 
Process finished with exit code 1
Убрал face - пошли жалобы на отсутствие такого класса
VolodyaBuzin вне форума Ответить с цитированием
Старый 03.02.2020, 21:52   #2
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Вот ошибка без face:
Код:
D:\Python\python.exe C:/demo4/opencv_demo4.py
Traceback (most recent call last):
  File "C:/demo4/opencv_demo4.py", line 9, in <module>
    recognizer = cv2.LBPHFaceRecognizer_create()
AttributeError: module 'cv2' has no attribute 'LBPHFaceRecognizer_create'
 
Process finished with exit code 1
Изображения
Тип файла: jpg папки-проекта.jpg (41.5 Кб, 0 просмотров)
Тип файла: jpg dir_dataset.jpg (85.9 Кб, 0 просмотров)
Тип файла: jpg install_pillow.jpg (36.6 Кб, 0 просмотров)
Тип файла: jpg User.Vladimir.1.jpg (10.6 Кб, 23 просмотров)
Тип файла: jpg User.Vladimir.2.jpg (8.6 Кб, 23 просмотров)
VolodyaBuzin вне форума Ответить с цитированием
Старый 03.02.2020, 23:10   #3
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Доустановите opencv-contrib
Код:
pip install opencv-contrib-python
Black Fregat вне форума Ответить с цитированием
Старый 04.02.2020, 07:16   #4
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Библиотеку поставил, но пошли другие ошибки, связанные с 29 и 21 строками:
Код:
D:\Python\python.exe C:/demo4/opencv_demo4.py
 
 [INFO] Training faces. It will take a few seconds. Wait ...
Traceback (most recent call last):
  File "C:/demo4/opencv_demo4.py", line 29, in <module>
    faces, ids = getImagesAndLabels(path)
  File "C:/demo4/opencv_demo4.py", line 21, in getImagesAndLabels
    id = int(os.path.split(imagePath)[-1].split(".")[1])
ValueError: invalid literal for int() with base 10: 'Vladimir'
 
Process finished with exit code 1
Код программы:
Код:
import cv2
import numpy as np
from PIL import Image
import os
 
# Path for face image database
path = 'dataset'
 
recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");
 
# function to get the images and label data
def getImagesAndLabels(path):
    imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
    faceSamples=[]
    ids = []
    for imagePath in imagePaths:
        PIL_img = Image.open(imagePath).convert('L')
        # convert it to grayscale
        img_numpy = np.array(PIL_img, 'uint8')
        id = int(os.path.split(imagePath)[-1].split(".")[1])
        faces = detector.detectMultiScale(img_numpy)
        for (x, y, w, h) in faces:
            faceSamples.append(img_numpy[y:y+h, x:x+w])
            ids.append(id)
    return faceSamples, ids
 
print ("\n [INFO] Training faces. It will take a few seconds. Wait ...")
faces, ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))
 
# Save the model into trainer/trainer.yml
recognizer.write('trainer/trainer.yml')
# recognizer.save() worked on Mac, but not on Pi
 
# Print the numer of faces trained and end program
print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))
Vladimir - это имя человека, фотографии которого помещаются в dataset на предыдущем шаге.
VolodyaBuzin вне форума Ответить с цитированием
Старый 04.02.2020, 13:16   #5
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Ура! При id=7 yml-образ создался!
VolodyaBuzin вне форума Ответить с цитированием
Старый 04.02.2020, 13:19   #6
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Но как сделать, чтобы выводимое над зелёной рамкой имя бралось из учётной записи Microsoft или локальной записи пользователя Windows 10?
VolodyaBuzin вне форума Ответить с цитированием
Старый 05.02.2020, 06:28   #7
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Я пробовал getuser из библиотеки getpass, но, скорее всего, компилятор не смог считать имя пользователя, потому что оно кириллическое (над рамкой появились вопросительные знаки). Когда написал на седьмом месте в массиве Vladimir - имя вывелось нормально. Есть ли в Python функция, включающая русскую раскладку подобно сишной setlocale из библиотеки <locale.h>?

Код программы:
Код:
import getpass
import cv2
import numpy as np
import os
 
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);
 
font = cv2.FONT_HERSHEY_SIMPLEX
 
# iniciate id counter
id = 0
 
# names related to ids: example ==> Marcelo: id=1,  etc
names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z', 'W', 'Oksana', getpass.getuser()]
 
# Initialize and start realtime video capture
cam = cv2.VideoCapture(0)
cam.set(3, 640)  # set video widht
cam.set(4, 480)  # set video height
 
# Define min window size to be recognized as a face
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)
 
while True:
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.2,
        minNeighbors=5,
        minSize=(int(minW), int(minH)),
    )
 
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
        id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
 
        # Check if confidence is less them 100 ==> "0" is perfect match
        if (confidence < 100):
            id = names[id]
            confidence = "  {0}%".format(round(100 - confidence))
        else:
            id = "unknown"
            confidence = "  {0}%".format(round(100 - confidence))
 
        cv2.putText(img, str(id), (x + 5, y - 5), font, 1, (255, 255, 255), 2)
        cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (255, 255, 0), 1)
 
    cv2.imshow('camera', img)
 
    k = cv2.waitKey(10) & 0xff  # Press 'ESC' for exiting video
    if k == 27:
        break
 
# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()
Изображения
Тип файла: jpg результат-1.jpg (65.7 Кб, 1 просмотров)
Тип файла: jpg результат-2.jpg (68.2 Кб, 1 просмотров)
VolodyaBuzin вне форума Ответить с цитированием
Старый 05.02.2020, 07:07   #8
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Ещё я попробовал пример в этих лекциях
https://www.intuit.ru/studies/course...e/17985?page=2
Но столкнулся с тем, что подмодуль cv и константа CV_HAAR_SCALE_IMAGE были удалены из OpenCV 3.0. Попробовал CASCADE_SCALE_IMAGE, но не помогло ни с одинарным, ни с удвоенным cv. Какой аналог этих констант есть в OpenCV 4.1.2?

Код программы:
Код:
import sys, cv2 as cv
 
cap = cv.VideoCapture(0)
cascade = cv.CascadeClassifier(
    "lbpcascade_frontalface.xml")
# Загрузка обученного каскадного классификатора
while True:
    ok, img = cap.read()
    if not ok:
        break
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    sf = min(640. / img.shape[1], 480. / img.shape[0])
    gray = cv.resize(gray, (0, 0), None, sf, sf)
    # Масштабирование
    rects = cascade.detectMultiScale(gray, scaleFactor=1.3,
                                     minNeighbors=4, minSize=(40, 40),
                                     flags=cv.CASCADE_SCALE_IMAGE)
    #Детектирование
    gray = cv.GaussianBlur(gray, (3, 3), 1.1)
    # Размываем
    edges = cv.Canny(gray, 5, 50)  # Детектируем ребра
 
    out = cv.cvtColor(edges, cv.COLOR_GRAY2BGR)
    for x, y, w, h in rects:
        cv.rectangle(out, (x, y), (x + w, y + h), (0, 0, 255), 2)
        # Вокруг найденного лица
        # рисуем красный прямоугольник
    cv.imshow("edges+face", out)
    if cv.waitKey(30) > 0:
        break
Ошибка для одинарного cv:
Код:
D:\Python\python.exe C:/demo5/opencv_demo5.py
Traceback (most recent call last):
  File "C:/demo5/opencv_demo5.py", line 17, in <module>
    flags=cv.CASCADE_SCALE_IMAGE)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\objdetect\src\cascadedetect.cpp:1689: error: (-215:Assertion failed) !empty() in function 'cv::CascadeClassifier::detectMultiScale'
 
[ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (674) SourceReaderCB::~SourceReaderCB terminating async callback
 
Process finished with exit code 1
Ошибка для двойного cv:
Код:
D:\Python\python.exe C:/demo5/opencv_demo5.py
Traceback (most recent call last):
  File "C:/demo5/opencv_demo5.py", line 17, in <module>
    flags=cv.cv.CASCADE_SCALE_IMAGE)
AttributeError: module 'cv2.cv2' has no attribute 'cv'
[ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (674) SourceReaderCB::~SourceReaderCB terminating async callback
 
Process finished with exit code 1
VolodyaBuzin вне форума Ответить с цитированием
Старый 05.02.2020, 07:15   #9
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Всё сработало, просто забыл перекинуть в проект нужный xml.
Изображения
Тип файла: jpg результат-3.jpg (91.7 Кб, 1 просмотров)
VolodyaBuzin вне форума Ответить с цитированием
Старый 09.02.2020, 18:10   #10
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Я решил написать вторую версию распознавателя, где данные берутся из MySQL, и сделал её с использованием pymysql, но знания pymysql и OpenCV 3.0+ хромают. Я подгонял под нужную мне СУБД и версию OpenCV коды с этого сайта:
https://dev.to/pranay749254/simple-f...hon-and-opencv
Причём, первые два благополучно создали фотки и yml-образ, но на этапе распознавания начались проблемы с выводом данных на экран: программа чуть-чуть подвигалась, а потом зависла и выдала ошибки, связанные с putText и индексами строки profile. Сначала попробовал ключи, соответствующие названиям столбцов, на что компилятор "сказал", что нужны значения числового, а не кортежного типа, потом попробовал индексы с цифрами, как в примерах, но появилась ошибка, причину которой я не знаю. Как правильно из БД извлечь строки и разбить их по нужным ключам, а потом передать их в putText?

insert_or_update.py
Код:
import cv2
import numpy as np
import pymysql
from pymysql.cursors import DictCursor
 
faceDetect = cv2.CascadeClassifier('haarcascade_frontalface_default.xml');
cam = cv2.VideoCapture(0);
 
def insertOrUpdate(Id, Name, Age, Gen, CR):
    conn = pymysql.connect(host='localhost', user='root', password='', db='facebase', charset='utf8mb4', cursorclass=DictCursor)
    with conn.cursor() as cursor:
        cmd = "SELECT * FROM people WHERE ID=%s"
        cursor.execute(cmd, Id)
        count_row = cursor.rowcount
 
    if (count_row > 0):
        with conn.cursor() as cursor:
            cmd = "UPDATE people SET Name=%s, Age=%s, Gender=%s, CR=%s WHERE ID=%s"
            cursor.execute(cmd, (Name, Age, Gen, CR, Id))
            conn.commit()
    else:
        with conn.cursor() as cursor:
            cmd = "INSERT INTO people(ID, Name, Age, Gender, CR) Values(%s, %s, %s, %s, %s)"
            cursor.execute(cmd, (Id, Name, Age, Gen, CR))
            conn.commit()
 
    conn.close()
 
Id = input('Enter User Id')
name = input('Enter User Name')
age = input('Enter User Age')
gen = input('Enter User Gender')
cr = input('Enter User Criminal Records')
insertOrUpdate(Id, name, age, gen, cr)
sampleNum = 0
while(True):
    ret, img = cam.read();
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = faceDetect.detectMultiScale(gray, 1.3, 5);
    for(x, y, w, h) in faces:
        sampleNum = sampleNum + 1;
        cv2.imwrite("dataSet/User." + str(Id) + "." + str(sampleNum) + ".jpg", gray[y:y+h, x:x+w])
        cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
        cv2.waitKey(100);
    cv2.imshow("Face", img);
    cv2.waitKey(1);
    if(sampleNum > 20):
        break;
 
cam.release()
cv2.destroyAllWindows()
training.py
Код:
import os
import cv2
import numpy as np
from PIL import Image
 
recognizer = cv2.face.LBPHFaceRecognizer_create();
path = 'dataSet'
 
def getImagesWithID(path):
    imagepaths = [os.path.join(path, f) for f in os.listdir(path)]
    faces=[]
    IDs=[]
    for imagepath in imagepaths:
        faceImg = Image.open(imagepath).convert('L');
        faceNp = np.array(faceImg, 'uint8')
        ID = int(os.path.split(imagepath)[-1].split('.')[1])
        faces.append(faceNp)
        IDs.append(ID)
        cv2.imshow("training", faceNp)
        cv2.waitKey(10)
    return np.array(IDs), faces
 
IDs, faces = getImagesWithID(path)
recognizer.train(faces, IDs)
recognizer.write('recognizer/trainningData.yml')
cv2.destroyAllWindows()
recognition.py
Код:
import cv2
import numpy as np
import os
import pymysql
from pymysql.cursors import DictCursor
 
faceDetect = cv2.CascadeClassifier('haarcascade_frontalface_default.xml');
cam = cv2.VideoCapture(0);
rec = cv2.face.LBPHFaceRecognizer_create();
rec.read("recognizer/trainningData.yml")
font = cv2.FONT_HERSHEY_SIMPLEX
 
def getProfile(id):
    conn = pymysql.connect(host='localhost', user='root', password='', db='facebase', charset='utf8mb4', cursorclass=DictCursor)
    with conn.cursor() as cursor:
        cmd = "SELECT * FROM people WHERE ID=%s"
        cursor.execute(cmd, id)
        rows = cursor.fetchall()
        profile = None
        for row in rows:
            profile = row
    conn.close()
    return profile
 
while(True):
    ret, img = cam.read();
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = faceDetect.detectMultiScale(gray, 1.3, 5);
    for(x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
        id, conf = rec.predict(gray[y:y+h, x:x+w])
        profile = getProfile(id)
        if(profile != None):
            cv2.putText(img, "Name : " + str(profile[1]), (x, y+h+20), font, (0, 255, 0), 2);
            cv2.putText(img, "Age : " + str(profile[2]), (x, y+h+45), font, (0, 255, 0), 2);
            cv2.putText(img, "Gender : " + str(profile[3]), (x, y+h+70), font, (0, 255, 0), 2);
            cv2.putText(img, "Criminal Records : " + str(profile[4]), (x, y+h+95), font, (0, 0, 255), 2);
    cv2.imshow("Face", img);
    if(cv2.waitKey(1)==ord('q')):
        break;
cam.release()
cv2.destroyAllWindows()
Ошибки:
Код:
D:\Python\python.exe C:/face_detection_mysql/recognition.py
Traceback (most recent call last):
  File "C:/face_detection_mysql/recognition.py", line 34, in <module>
    cv2.putText(img, "Name : " + str(profile[1]), (x, y+h+20), font, (0, 255, 0), 2);
KeyError: 1
[ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (674) SourceReaderCB::~SourceReaderCB terminating async callback
 
Process finished with exit code -805306369 (0xCFFFFFFF)
Изображения
Тип файла: jpg User.1.1.jpg (11.3 Кб, 12 просмотров)
Тип файла: jpg phpmyadmin.jpg (74.4 Кб, 1 просмотров)
Тип файла: jpg папка-проекта.jpg (49.8 Кб, 1 просмотров)
Тип файла: jpg dataset.jpg (70.1 Кб, 1 просмотров)
Тип файла: jpg recognizer.jpg (41.2 Кб, 0 просмотров)
VolodyaBuzin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обработка растровых изображений с применением библиотеки OpenCV: проблемы с апроксимацией и нахождением вершин фигуры VolodyaBuzin Python 4 29.01.2020 07:41
Движение растровых изображений в делфи Katerina_K Помощь студентам 2 25.10.2013 14:24
Обработка растровых изображений и анимация в C++ Kravanet Visual C++ 0 01.12.2011 23:31
Какие форматы файлов растровых изображений нецелочисленные пиксели? Shuraken13 Помощь студентам 0 18.05.2011 14:23
Разработать программу для обработки растровых изображений, хранящихся в файлах формата BMP (BitMaP). yeskin Фриланс 5 19.12.2010 15:06