Считывание данных из Таблицы БД

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
у меня такой вопрос, создал таблицу в БД SQLite, занес туда данные + фото. Сейчас программа считывает фото из папки, хочу реализовать, чтобы теперь после создание БД, при запуске программы, данные считывались из таблицы, а точнее имя фотографии. То есть суть программы, при запуске, включается веб камера и определяет человека, сейчас фото хранятся в папке, она все определяет прекрасно, но вот когда загрузил в бд, не могу понять, как сделать, чтобы она теперь из БД брала фото и так же сравнивала. Буду благодарен за любую помощь

Код программы:
Python:
import winsound
    import numpy as np
    import face_recognition
    import cv2
    import os
    from PIL import ImageFont, ImageDraw, Image
    import FindCloneApi
    from datetime import datetime
    
    path = 'KnownFaces'
    images = []
    classNames = []
    
    cap = cv2.VideoCapture(0)
    frequency = 2500  # Set Frequency To 2500 Hertz
    duration = 1000  # Set Duration To 1000 ms == 1 second
    winsound.Beep(frequency, duration)
    def face_detect():
        myList = os.listdir(path)
        print(myList)
    
        for cls in myList:
            curImg = cv2.imdecode(np.fromfile(f'{path}/{cls}', dtype=np.uint8), cv2.IMREAD_COLOR)
            images.append(curImg)
            classNames.append(os.path.splitext(cls)[0])
    
        print(classNames)
    
        def findEncodings(images):
            encodeList = []
            for img in images:
                img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
                encode = face_recognition.face_encodings(img)[0]
                encodeList.append(encode)
            return encodeList
    
        def markAttendance(name):
            with open("Attendance.csv", "r+") as f:
                myDataList = f.readlines()
                nameList = []
                for line in myDataList:
                    entry = line.split(',')
                    nameList.append(entry[0])
                if name not in nameList:
                    now = datetime.now()
                    dtString = now.strftime("%H:%M:%S")
                    f.writelines(f'\n{name}, {dtString}')
    
        encodeListKnown = findEncodings(images)
        print("Декодирование закончено")
    
    
    
        while True:
            success, img = cap.read()
            imgS = cv2.resize(img, (0, 0), None, 0.25, 0.25)
            imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)
    
            facesCurFrame = face_recognition.face_locations(imgS)
            encodeCurFrame = face_recognition.face_encodings(imgS, facesCurFrame)
    
            for encodeFace, faceLoc in zip(encodeCurFrame, facesCurFrame):
                matches = face_recognition.compare_faces(encodeListKnown, encodeFace)
                faceDis = face_recognition.face_distance(encodeListKnown, encodeFace)
                print(faceDis)
                matchIndex = np.argmin(faceDis)
    
                name = 'Unknown'
    
                if matches[matchIndex]:
                    name = classNames[matchIndex]
                    print(name)
                    y1, x2, y2, x1 = faceLoc
                    y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4
                    cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
                    cv2.rectangle(img, (x1, y2 - 35), (x2, y2), (0, 255, 0), cv2.FILLED)
                    cv2.putText(img, name, (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
                    markAttendance(name)
                else:
                    filename = 'KnownFaces/face.jpg'
                    cv2.imwrite(filename, img)
                    print("Лицо сохранено")
                    #find_clone(filename)
    
    
    
            cv2.imshow("WebCam", img)
            cv2.waitKey(1)
    
    def find_clone(img):
        find = FindCloneApi.FindCloneAPI()
        find.login()
        find.upload(img)
        name = 'KnownFaces/' + str(find.out()) + '.jpg'
        os.rename(img, name)
        face_detect()
    
    face_detect()


Сейчас путь указан к папке path = 'KnownFaces'

Вот код соединения и создание таблицы, все создается прекрасно, фото загружаются.

Python:
 import sqlite3
    
    conn = sqlite3.connect('rr.db')
    cur = conn.cursor()
    
    
    
    
    def convert_to_binary_data(filename):
        # Преобразование данных в двоичный формат
        with open(filename, 'rb') as file:
            blob_data = file.read()
        return blob_data
    
    def insert_blob(emp_id, name, photo, resume_file):
        try:
            sqlite_connection = sqlite3.connect('rr.db')
            cursor = sqlite_connection.cursor()
            print("Подключен к SQLite")
    
            sqlite_insert_blob_query = """INSERT INTO new_tt
                                      (id, name, photo, resume) VALUES (?, ?, ?, ?)"""
    
            emp_photo = convert_to_binary_data(photo)
            resume = convert_to_binary_data(resume_file)
            # Преобразование данных в формат кортежа
            data_tuple = (emp_id, name, emp_photo, resume)
            cursor.execute(sqlite_insert_blob_query, data_tuple)
            sqlite_connection.commit()
            print("Изображение и файл успешно вставлены как BLOB в таблиу")
            cursor.close()
    
        except sqlite3.Error as error:
            print("Ошибка при работе с SQLite", error)
        finally:
            if sqlite_connection:
                sqlite_connection.close()
                print("Соединение с SQLite закрыто")
    
    insert_blob(1, "Вадим", "Вадим.jpg", "resume_Vadim.docx")
    insert_blob(2, "Костя", "Костя.jpg", "resume_Vadim.docx")


Само создание таблицы с полями
SQL:
 CREATE TABLE new_tt
    (id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    photo BLOB NOT NULL,
    resume BLOB NOT NULL);
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Видимо потому что код из цикла должен обработать каждый кадр. Как ускорить не знаю. cv2.waitKey(1) это минимальное значение, то есть ожидание после обработки кадра составляет всего 1 миллисекунду.

Еще такой вопрос, хотелось бы реализовать такую штуку, то есть создать в базе еще столбцы, такие как Фамилия,Отчество, Город, Возраст, Пол - это все не сложно. Сейчас при запуске отображает Имя, думаю вы уже все и так знаете. Как можно сделать так, когда человека смотрит в камеру, открывается отдельное окно, в котором будет его фото из БД, так же информация из Бд, такая как Фамилия,Отчество, Город, Возраст, Пол. Чтобы как бы структура была вот такая у этого окна, как показано на рисунке. То есть чтобы он выводил информацию списком построчно. То есть чтобы была информация о человеке, который сейчас попал в обзор камеры.
Как понимаю нужна библиотека Tkinter или WTForms
 

Вложения

  • Безымянный2.png
    Безымянный2.png
    5 КБ · Просмотры: 3
Последнее редактирование:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Как можно сделать так, когда человека смотрит в камеру, открывается отдельное окно, в котором будет его фото из БД, так же информация из Бд, такая как Фамилия,Отчество, Город, Возраст, Пол. Чтобы как бы структура была вот такая у этого окна, как показано на рисунке
Нужно добавить в базу поля, потом получать их и привязывать к имени. Второе окно можно попробовать выводить также с помощью cv2.imshow() только нужно как-то определить что это все тот же человек
Как понимаю нужна библиотека Tkinter или WTForms
Окно можно и на tkinter реализовать.
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Нужно добавить в базу поля, потом получать их и привязывать к имени. Второе окно можно попробовать выводить также с помощью cv2.imshow() только нужно как-то определить что это все тот же человек

Окно можно и на tkinter реализовать.
Нужно добавить в базу поля, потом получать их и привязывать к имени - это тоже смогу сделать.
А вот это для меня будет проблема - Второе окно можно попробовать выводить также с помощью cv2.imshow() только нужно как-то определить что это все тот же человек
Даже если использовать tkinter, то там такая же проблема будет с определением этого же человека. Я конечно попробую разобраться, но без вашей помощи точно не получится. Давайте я завтра вам напишу, сюда же. Создам поля, попробую их привязать к имени, а дальше может с вашей помощью получится сделать
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Можете попробовать эти поля сначала в том же окне что и имя вывести, просто шрифт уменьшить чтобы они влезли это проще будет.
Хорошо, я завтра попробую, отпишусь, если получится скину скрин
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Можете попробовать эти поля сначала в том же окне что и имя вывести, просто шрифт уменьшить чтобы они влезли это проще будет.
Здравствуйте, создал базу с новыми полям id, name, lastname, photo, status, city, age,gender. Таблицу заполнил, все прекрасно работает.
Изменил только вместо цифр, статус поставил, студент и преподаватель, в коде тоже изменил.

Код таблицы:
SQL:
import sqlite3

conn = sqlite3.connect('last.db')
cur = conn.cursor()


cur.execute("""CREATE TABLE IF NOT EXISTS `new_test5`(
`id` INTEGER PRIMARY KEY,
`name` TEXT NOT NULL,
`lastname` TEXT NOT NULL,
`photo` BLOB NOT NULL,
`status` INT NOT NULL,
`city` TEXT NOT NULL,
`age` INT NOT NULL,
`gender` TEXT NOT NULL);
""")
cur.close()
conn.close()

def convert_to_binary_data(filename):
    # Преобразование данных в двоичный формат
    with open(filename, 'rb') as file:
        blob_data = file.read()
    return blob_data

def insert_blob(emp_id, name,lastname, photo, status, city, age, gender):
    try:
        sqlite_connection = sqlite3.connect('last.db')
        cursor = sqlite_connection.cursor()
        print("Подключен к SQLite")

        sqlite_insert_blob_query = """INSERT INTO new_test5 (id, name, lastname, photo, status, city, age, gender)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?) """

        emp_photo = convert_to_binary_data(photo)

        # Преобразование данных в формат кортежа
        data_tuple = (emp_id, name, lastname, emp_photo, status, city, age, gender)
        cursor.execute(sqlite_insert_blob_query, data_tuple)
        sqlite_connection.commit()
        print("Изображение и файл успешно вставлены как BLOB в таблиу")
        cursor.close()

    except sqlite3.Error as error:
        print("Ошибка при работе с SQLite", error)
    finally:
        if sqlite_connection:
            sqlite_connection.close()
            print("Соединение с SQLite закрыто")

#insert_blob(10, "Вадим","Гредасов" ,"Вадим.jpg", "Студент", "Миасс", "23", "М")
#insert_blob(2, "Кристина","Антонова", "Кристина.jpg","Преподаватель", "Миасс", "20", "Ж")

Код программы, где изменил:
Python:
def face_detect():
    conn = sqlite3.connect('db/last.db')
    cur = conn.cursor()
    c = cur.execute("""SELECT  name, lastname, photo, status, city, age, gender FROM new_test5""")

    data = c.fetchall()

    for name, lastname, photo, status, city, age, gender in data:
        curImg = cv2.imdecode(np.frombuffer(photo, dtype='uint8'), cv2.IMREAD_COLOR)
        images.append(curImg)
        classNames.append(name)
        # заполняем словарь {'имя': 'статус'}
        statuses[name] = status

current_status = statuses[name]
                color = (0, 255, 0)
                if current_status == "Студент":
                    color = (0, 255, 0)
                elif current_status == "Преподаватель":
                    color = (255, 0, 0)
                else:
                    color = (0, 0, 255)

Пытался привязать все к имени, если делать как вы показывали через словарь вот так и еще добавить к примеру город, так же создать словарь cities {}, и если добавить if current_city == город Миасс и color=(0, 255, 0), то рамку он меняет цветом, а как их прям привязать, не могу понять, еще и каждое поле из таблицы:
Python:
statuses = {}
statuses[name] = status
current_status = statuses[name]
                color = (0, 255, 0)
                if current_status == "Студент":
                    color = (0, 255, 0)
                elif current_status == "Преподаватель":
                    color = (255, 0, 0)
                else:
 
Последнее редактирование:

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Можно сделать вложенный словарь {'имя': {данные}}. Вот так например:
Python:
statuses[name] = {'name': name,
                  'lastname': lastname,
                  'status': status,
                  'city': city,
                  'age': age,
                  'gender': gender}
а потом красить рамку в зависимости от данных. Вот так например:
Python:
# если статус студент и город Миасс - то рамка красная
if statuses[name]['status'] == "Студент" and statuses[name]['city'] == 'Миасс':
            color = (0, 0, 255)
чтобы выводить данные на экран добавьте еще строку с выводом текста (только надо учесть координаты, чтобы текст не накладывался)
Python:
cv2.putText(img, 'Тут нужный текст', (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
Думаю рамку красить смысла нет, в зависимости от Города, в зависимости от Статуса изменяется, пусть так и остается
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Можно сделать вложенный словарь {'имя': {данные}}. Вот так например:
Python:
statuses[name] = {'name': name,
                  'lastname': lastname,
                  'status': status,
                  'city': city,
                  'age': age,
                  'gender': gender}
а потом красить рамку в зависимости от данных. Вот так например:
Python:
# если статус студент и город Миасс - то рамка красная
if statuses[name]['status'] == "Студент" and statuses[name]['city'] == 'Миасс':
            color = (0, 0, 255)
чтобы выводить данные на экран добавьте еще строку с выводом текста (только надо учесть координаты, чтобы текст не накладывался)
Python:
cv2.putText(img, 'Тут нужный текст', (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
А вот как это еще реализовать в отдельное окно, чтобы записывалась как в форму данные, вот это очень интересно, о чем вчера рассказывал. C Х и У поигрался, если делать просто списком на камере, смотрится ужасно. По этому чтобы открывал отдельное окно с формой и туда записывал данные исходя из имени, вот это было бы гораздо лучше.

Как понимаю, для начала нужно эту форму нарисовать каким-то образом? Просто в Visual studio все просто, там есть инструменты для рисования формы и тд

Если нарисую форму, то есть она будет уже с полями и тд, туда будет сложно записать данные из БД по имени? Нарисовал форму, получилось вот так, снизу можно фото вставить как раз. Может форма кривовата, может нужно подправить

Код формы:
Python:
import tkinter as tk

# Создается новое окно с заголовком "Форма информации о человеке".
window = tk.Tk()
window.title("Форма информации о человеке")

# Создается новая рамка `frm_form` для ярлыков с текстом и
# Однострочных полей для ввода информации об адресе.
frm_form = tk.Frame(relief=tk.FLAT, borderwidth=3)
# Помещает рамку на окно приложения.
frm_form.pack()

window.geometry("500x500")
# Список ярлыков полей.
labels = [
    "Имя:",
    "Фамилия:",
    "Статус:",
    "Город:",
    "Возраст:",
    "Пол:",
]

# Цикл для списка ярлыков полей.
for idx, text in enumerate(labels):
    # Создает ярлык с текстом из списка ярлыков.
    label = tk.Label(master=frm_form, text=text)
    # Создает текстовое поле которая соответствует ярлыку.
    entry = tk.Entry(master=frm_form, width=50)
    # Использует менеджер геометрии grid для размещения ярлыков и
    # текстовых полей в строку, чей индекс равен idx.
    label.grid(row=idx, column=0, sticky="e")
    entry.grid(row=idx, column=1)


# Запуск приложения.

window.mainloop()
 

Вложения

  • Безымянный77.png
    Безымянный77.png
    6,2 КБ · Просмотры: 1
Последнее редактирование:

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Если форму делать на tkinter, то она должна быть главным окном (запускаться в основном потоке), а функцию face_detect нужно будет запускать в другом потоке чтобы не блокировать отрисовку формы.
Нужно вашу форму переписать в виде класса, функцию face_detect поместить в отдельный поток (нужно будет добавить функцию для старта потока) и запускать либо со старта приложения либо по кнопке, данные между потоками можно передавать через переменные класса.
Так еще же на форму нужно данные из Бд передать, вот с потоками будет для меня сложно. Может есть еще варианты как форму сделать чтобы было по проще? Надеюсь на вашу помощь. Сейчас сделаю форму классом, скину, посмотрите, так или нет нужно было сделать
 
Последнее редактирование:

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Если форму делать на tkinter, то она должна быть главным окном (запускаться в основном потоке), а функцию face_detect нужно будет запускать в другом потоке чтобы не блокировать отрисовку формы.
Нужно вашу форму переписать в виде класса, функцию face_detect поместить в отдельный поток (нужно будет добавить функцию для старта потока) и запускать либо со старта приложения либо по кнопке, данные между потоками можно передавать через переменные класса.

Если понял вас правильно, сделать Классом форму, вот ниже код, может надо что-то изменить, буду рад если поможете.
Python:
import tkinter as tk
from tkinter import messagebox as mb

class Window:
    def __init__(self, width, height, title="MyWindow", resizable=(False, False), icon=None):
        self.root = tk.Tk()
        self.root.title(title)
        self.root.geometry("500x500+600+300")
        # self.root.resizable(resizable[0], resizable[1])


        self.name_entry = tk.Entry(self.root)
        self.lastname_entry = tk.Entry(self.root)
        self.status_entry = tk.Entry(self.root)
        self.city_entry = tk.Entry(self.root)
        self.age_entry = tk.Entry(self.root)
        self.gender_entry = tk.Entry(self.root)

    def run(self):
        self.draw_widgets()
        self.root.mainloop()

    def draw_widgets(self):
        tk.Label(self.root, text="Имя:").grid(row=0, column=0, sticky=tk.W)
        self.name_entry.grid(row=0, column=1, sticky=tk.W+tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Фамилия:").grid(row=1, column=0, sticky=tk.W)
        self.lastname_entry.grid(row=1, column=1, sticky=tk.W+tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Статус:").grid(row=2, column=0, sticky=tk.W)
        self.status_entry.grid(row=2, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Город:").grid(row=3, column=0, sticky=tk.W)
        self.city_entry.grid(row=3, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Возраст:").grid(row=4, column=0, sticky=tk.W)
        self.age_entry.grid(row=4, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Пол:").grid(row=5, column=0, sticky=tk.W)
        self.gender_entry.grid(row=5, column=1, sticky=tk.W + tk.E, padx=5, pady=5)

        tk.Button(self.root, text="Quit", width=10, command=self.exit).grid(row=6, column=1, sticky=tk.E)

    def exit(self):
        choice = mb.askyesno("Quit", "Do you want to quit?")
        if choice:
            self.root.destroy()

    def button_action(self):
        tk.Label(self.root, text="New label").pack()

if __name__ == "__main__":
    window = Window(500, 500, "TKINTER")
    window.run()


Вот результат формы:
 

Вложения

  • Безымянный77.png
    Безымянный77.png
    4,7 КБ · Просмотры: 1

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Нужно добавить в базу поля, потом получать их и привязывать к имени. Второе окно можно попробовать выводить также с помощью cv2.imshow() только нужно как-то определить что это все тот же человек

Окно можно и на tkinter реализовать.
Поставил вам плюс за ответ и пропали ваши сообщения которые оценил, не знал, что это так происходит, жду ответа от вас
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 596
461
83
Поставил вам плюс за ответ и пропали ваши сообщения которые оценил, не знал, что это так происходит, жду ответа от вас
они не пропали, они теперь на первой странице, так как вы поставили плюс и, следовательно, для вас это полезные сообщения...
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Если понял вас правильно, сделать Классом форму, вот ниже код, может надо что-то изменить, буду рад если поможете.
Форма пойдет.
Так еще же на форму нужно данные из Бд передать
Вот пример получения данных из базы и вывода их в форму по индексу. Посмотрите, разберитесь. Можете добавить вывод картинки в окно и статус бар внизу например (чтобы можно было сообщения не в консоль выводить а в него, например декодирование завершено, данные из базы получены и т. д.)
Python:
import tkinter as tk
import sqlite3
import numpy as np
import face_recognition
import cv2


class Application(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        # ---------------------Variables-------------------------
        self.root = root
        self.root.geometry("500x500+600+300")
        self.data = {}  # данные из базы {'index': {data}}
        self.images = []  # картинки из базы
        self.encodeListKnown = []  # лица с картинок из базы

        # ---------------------Widgets---------------------------
        self.name_entry = tk.Entry(self.root)
        self.lastname_entry = tk.Entry(self.root)
        self.status_entry = tk.Entry(self.root)
        self.city_entry = tk.Entry(self.root)
        self.age_entry = tk.Entry(self.root)
        self.gender_entry = tk.Entry(self.root)
        self.number = tk.StringVar()
        self.number.set("0")
        self.number_entry = tk.Entry(self.root, textvariable=self.number)

        tk.Label(self.root, text="Имя:").grid(row=0, column=0, sticky=tk.W)
        self.name_entry.grid(row=0, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Фамилия:").grid(row=1, column=0, sticky=tk.W)
        self.lastname_entry.grid(row=1, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Статус:").grid(row=2, column=0, sticky=tk.W)
        self.status_entry.grid(row=2, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Город:").grid(row=3, column=0, sticky=tk.W)
        self.city_entry.grid(row=3, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Возраст:").grid(row=4, column=0, sticky=tk.W)
        self.age_entry.grid(row=4, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Пол:").grid(row=5, column=0, sticky=tk.W)
        self.gender_entry.grid(row=5, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        
        tk.Button(self.root, text="Get data", width=10, command=self.get_data_from_db).grid(
            row=6, column=1, sticky=tk.E
        )
        tk.Button(self.root, text="Show data", width=10, command=self.show_data).grid(
            row=7, column=1, sticky=tk.E
        )       
        tk.Label(self.root, text="Номер профиля:").grid(row=8, column=0, sticky=tk.W)
        self.number_entry.grid(row=8, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Button(self.root, text="Quit", width=10, command=self.exit).grid(
            row=9, column=1, sticky=tk.E
        )
    # -----------------------------Methods-----------------------------------

    def exit(self):
        """Метод для выхода из программы"""

        self.root.destroy()

    def set_text(self, entry, text):
        """Метод для вывода текста в поле на форме"""
        entry.delete(0, tk.END)
        entry.insert(0, text)

    def show_data(self):
        """Метод для вывода данных в форму"""

        number = int(self.number.get())
        profile = self.data[number]
        self.set_text(self.name_entry, text=profile['name'])
        self.set_text(self.lastname_entry, text=profile['lastname'])
        self.set_text(self.status_entry, text=profile['status'])
        self.set_text(self.city_entry, text=profile['city'])
        self.set_text(self.age_entry, text=profile['age'])
        self.set_text(self.gender_entry, text=profile['gender'])

    def get_data_from_db(self):
        """Метод для получения данных из базы и записи в переменные класса"""

        conn = sqlite3.connect('rr.db')
        cur = conn.cursor()
        c = cur.execute("""SELECT name, lastname, photo, status, city, age, gender FROM new_tt""")
        data = c.fetchall()
        for index, (name, lastname, photo, status, city, age, gender) in enumerate(data):
            curImg = cv2.imdecode(np.frombuffer(photo, dtype='uint8'), cv2.IMREAD_COLOR)
            self.data[index] = {'name': name,
                                'lastname': lastname,
                                'status': status,
                                'city': city,
                                'age': age,
                                'gender': gender,
                                }
            self.images.append(curImg)

        conn.close()

        # это можно будет потом вынести в отдельный метод
        self.encodeListKnown = self.findEncodings(self.images)
        print("Декодирование закончено")

    def findEncodings(self, images):
        """Метод для получения списка лиц из списка картинок"""
        encodeList = []
        for img in images:
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            encode = face_recognition.face_encodings(img)[0]
            encodeList.append(encode)
        return encodeList


if __name__ == "__main__":
    root = tk.Tk()
    root.title("Форма с данными")
    root.resizable(False, False)
    Application(root)
    root.mainloop()
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Форма пойдет.

Вот пример получения данных из базы и вывода их в форму по индексу. Посмотрите, разберитесь. Можете добавить вывод картинки в окно и статус бар внизу например (чтобы можно было сообщения не в консоль выводить а в него, например декодирование завершено, данные из базы получены и т. д.)
Python:
import tkinter as tk
import sqlite3
import numpy as np
import face_recognition
import cv2


class Application(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        # ---------------------Variables-------------------------
        self.root = root
        self.root.geometry("500x500+600+300")
        self.data = {}  # данные из базы {'index': {data}}
        self.images = []  # картинки из базы
        self.encodeListKnown = []  # лица с картинок из базы

        # ---------------------Widgets---------------------------
        self.name_entry = tk.Entry(self.root)
        self.lastname_entry = tk.Entry(self.root)
        self.status_entry = tk.Entry(self.root)
        self.city_entry = tk.Entry(self.root)
        self.age_entry = tk.Entry(self.root)
        self.gender_entry = tk.Entry(self.root)
        self.number = tk.StringVar()
        self.number.set("0")
        self.number_entry = tk.Entry(self.root, textvariable=self.number)

        tk.Label(self.root, text="Имя:").grid(row=0, column=0, sticky=tk.W)
        self.name_entry.grid(row=0, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Фамилия:").grid(row=1, column=0, sticky=tk.W)
        self.lastname_entry.grid(row=1, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Статус:").grid(row=2, column=0, sticky=tk.W)
        self.status_entry.grid(row=2, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Город:").grid(row=3, column=0, sticky=tk.W)
        self.city_entry.grid(row=3, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Возраст:").grid(row=4, column=0, sticky=tk.W)
        self.age_entry.grid(row=4, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Пол:").grid(row=5, column=0, sticky=tk.W)
        self.gender_entry.grid(row=5, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
       
        tk.Button(self.root, text="Get data", width=10, command=self.get_data_from_db).grid(
            row=6, column=1, sticky=tk.E
        )
        tk.Button(self.root, text="Show data", width=10, command=self.show_data).grid(
            row=7, column=1, sticky=tk.E
        )      
        tk.Label(self.root, text="Номер профиля:").grid(row=8, column=0, sticky=tk.W)
        self.number_entry.grid(row=8, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Button(self.root, text="Quit", width=10, command=self.exit).grid(
            row=9, column=1, sticky=tk.E
        )
    # -----------------------------Methods-----------------------------------

    def exit(self):
        """Метод для выхода из программы"""

        self.root.destroy()

    def set_text(self, entry, text):
        """Метод для вывода текста в поле на форме"""
        entry.delete(0, tk.END)
        entry.insert(0, text)

    def show_data(self):
        """Метод для вывода данных в форму"""

        number = int(self.number.get())
        profile = self.data[number]
        self.set_text(self.name_entry, text=profile['name'])
        self.set_text(self.lastname_entry, text=profile['lastname'])
        self.set_text(self.status_entry, text=profile['status'])
        self.set_text(self.city_entry, text=profile['city'])
        self.set_text(self.age_entry, text=profile['age'])
        self.set_text(self.gender_entry, text=profile['gender'])

    def get_data_from_db(self):
        """Метод для получения данных из базы и записи в переменные класса"""

        conn = sqlite3.connect('rr.db')
        cur = conn.cursor()
        c = cur.execute("""SELECT name, lastname, photo, status, city, age, gender FROM new_tt""")
        data = c.fetchall()
        for index, (name, lastname, photo, status, city, age, gender) in enumerate(data):
            curImg = cv2.imdecode(np.frombuffer(photo, dtype='uint8'), cv2.IMREAD_COLOR)
            self.data[index] = {'name': name,
                                'lastname': lastname,
                                'status': status,
                                'city': city,
                                'age': age,
                                'gender': gender,
                                }
            self.images.append(curImg)

        conn.close()

        # это можно будет потом вынести в отдельный метод
        self.encodeListKnown = self.findEncodings(self.images)
        print("Декодирование закончено")

    def findEncodings(self, images):
        """Метод для получения списка лиц из списка картинок"""
        encodeList = []
        for img in images:
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            encode = face_recognition.face_encodings(img)[0]
            encodeList.append(encode)
        return encodeList


if __name__ == "__main__":
    root = tk.Tk()
    root.title("Форма с данными")
    root.resizable(False, False)
    Application(root)
    root.mainloop()
Спасибо, сейчас разберусь, отпишусь
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Форма пойдет.

Вот пример получения данных из базы и вывода их в форму по индексу. Посмотрите, разберитесь. Можете добавить вывод картинки в окно и статус бар внизу например (чтобы можно было сообщения не в консоль выводить а в него, например декодирование завершено, данные из базы получены и т. д.)
Python:
import tkinter as tk
import sqlite3
import numpy as np
import face_recognition
import cv2


class Application(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        # ---------------------Variables-------------------------
        self.root = root
        self.root.geometry("500x500+600+300")
        self.data = {}  # данные из базы {'index': {data}}
        self.images = []  # картинки из базы
        self.encodeListKnown = []  # лица с картинок из базы

        # ---------------------Widgets---------------------------
        self.name_entry = tk.Entry(self.root)
        self.lastname_entry = tk.Entry(self.root)
        self.status_entry = tk.Entry(self.root)
        self.city_entry = tk.Entry(self.root)
        self.age_entry = tk.Entry(self.root)
        self.gender_entry = tk.Entry(self.root)
        self.number = tk.StringVar()
        self.number.set("0")
        self.number_entry = tk.Entry(self.root, textvariable=self.number)

        tk.Label(self.root, text="Имя:").grid(row=0, column=0, sticky=tk.W)
        self.name_entry.grid(row=0, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Фамилия:").grid(row=1, column=0, sticky=tk.W)
        self.lastname_entry.grid(row=1, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Статус:").grid(row=2, column=0, sticky=tk.W)
        self.status_entry.grid(row=2, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Город:").grid(row=3, column=0, sticky=tk.W)
        self.city_entry.grid(row=3, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Возраст:").grid(row=4, column=0, sticky=tk.W)
        self.age_entry.grid(row=4, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Пол:").grid(row=5, column=0, sticky=tk.W)
        self.gender_entry.grid(row=5, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
  
        tk.Button(self.root, text="Get data", width=10, command=self.get_data_from_db).grid(
            row=6, column=1, sticky=tk.E
        )
        tk.Button(self.root, text="Show data", width=10, command=self.show_data).grid(
            row=7, column=1, sticky=tk.E
        ) 
        tk.Label(self.root, text="Номер профиля:").grid(row=8, column=0, sticky=tk.W)
        self.number_entry.grid(row=8, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Button(self.root, text="Quit", width=10, command=self.exit).grid(
            row=9, column=1, sticky=tk.E
        )
    # -----------------------------Methods-----------------------------------

    def exit(self):
        """Метод для выхода из программы"""

        self.root.destroy()

    def set_text(self, entry, text):
        """Метод для вывода текста в поле на форме"""
        entry.delete(0, tk.END)
        entry.insert(0, text)

    def show_data(self):
        """Метод для вывода данных в форму"""

        number = int(self.number.get())
        profile = self.data[number]
        self.set_text(self.name_entry, text=profile['name'])
        self.set_text(self.lastname_entry, text=profile['lastname'])
        self.set_text(self.status_entry, text=profile['status'])
        self.set_text(self.city_entry, text=profile['city'])
        self.set_text(self.age_entry, text=profile['age'])
        self.set_text(self.gender_entry, text=profile['gender'])

    def get_data_from_db(self):
        """Метод для получения данных из базы и записи в переменные класса"""

        conn = sqlite3.connect('rr.db')
        cur = conn.cursor()
        c = cur.execute("""SELECT name, lastname, photo, status, city, age, gender FROM new_tt""")
        data = c.fetchall()
        for index, (name, lastname, photo, status, city, age, gender) in enumerate(data):
            curImg = cv2.imdecode(np.frombuffer(photo, dtype='uint8'), cv2.IMREAD_COLOR)
            self.data[index] = {'name': name,
                                'lastname': lastname,
                                'status': status,
                                'city': city,
                                'age': age,
                                'gender': gender,
                                }
            self.images.append(curImg)

        conn.close()

        # это можно будет потом вынести в отдельный метод
        self.encodeListKnown = self.findEncodings(self.images)
        print("Декодирование закончено")

    def findEncodings(self, images):
        """Метод для получения списка лиц из списка картинок"""
        encodeList = []
        for img in images:
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            encode = face_recognition.face_encodings(img)[0]
            encodeList.append(encode)
        return encodeList


if __name__ == "__main__":
    root = tk.Tk()
    root.title("Форма с данными")
    root.resizable(False, False)
    Application(root)
    root.mainloop()

Попробовал работоспособность, получается так, при запуске файла, форму он открывает, когда нажимаю Get data, он выводит данные, но зачем поле номер профиля или Id и номер профиля разные вещи? Он же его не изменяет и если ввести туда цифру 1 например, как понимаю это Id, то он пишет что такого нет, хотя в таблице присутствует записи с Id 1, так данные выводит все правильно, вот пример сейчас скину, как выводит данные. Сколько бы раз я не нажимал Get data, данные он выводи одни и те же
Как понимаю камеру он включать и не должен в момент когда идет декодирование данных?
Как он понимает кто сидит перед ним или он переде по очереди id, если я посажу человека который есть в базе, запущу форму, нажму Get data, форма выведет его уже данные, просто сейчас нет возможности проверить другим человеком?
 

Вложения

  • Безымянный43.png
    Безымянный43.png
    14,5 КБ · Просмотры: 2
Последнее редактирование:

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Форма пойдет.

Вот пример получения данных из базы и вывода их в форму по индексу. Посмотрите, разберитесь. Можете добавить вывод картинки в окно и статус бар внизу например (чтобы можно было сообщения не в консоль выводить а в него, например декодирование завершено, данные из базы получены и т. д.)
Python:
import tkinter as tk
import sqlite3
import numpy as np
import face_recognition
import cv2


class Application(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        # ---------------------Variables-------------------------
        self.root = root
        self.root.geometry("500x500+600+300")
        self.data = {}  # данные из базы {'index': {data}}
        self.images = []  # картинки из базы
        self.encodeListKnown = []  # лица с картинок из базы

        # ---------------------Widgets---------------------------
        self.name_entry = tk.Entry(self.root)
        self.lastname_entry = tk.Entry(self.root)
        self.status_entry = tk.Entry(self.root)
        self.city_entry = tk.Entry(self.root)
        self.age_entry = tk.Entry(self.root)
        self.gender_entry = tk.Entry(self.root)
        self.number = tk.StringVar()
        self.number.set("0")
        self.number_entry = tk.Entry(self.root, textvariable=self.number)

        tk.Label(self.root, text="Имя:").grid(row=0, column=0, sticky=tk.W)
        self.name_entry.grid(row=0, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Фамилия:").grid(row=1, column=0, sticky=tk.W)
        self.lastname_entry.grid(row=1, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Статус:").grid(row=2, column=0, sticky=tk.W)
        self.status_entry.grid(row=2, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Город:").grid(row=3, column=0, sticky=tk.W)
        self.city_entry.grid(row=3, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Возраст:").grid(row=4, column=0, sticky=tk.W)
        self.age_entry.grid(row=4, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Пол:").grid(row=5, column=0, sticky=tk.W)
        self.gender_entry.grid(row=5, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
      
        tk.Button(self.root, text="Get data", width=10, command=self.get_data_from_db).grid(
            row=6, column=1, sticky=tk.E
        )
        tk.Button(self.root, text="Show data", width=10, command=self.show_data).grid(
            row=7, column=1, sticky=tk.E
        )     
        tk.Label(self.root, text="Номер профиля:").grid(row=8, column=0, sticky=tk.W)
        self.number_entry.grid(row=8, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Button(self.root, text="Quit", width=10, command=self.exit).grid(
            row=9, column=1, sticky=tk.E
        )
    # -----------------------------Methods-----------------------------------

    def exit(self):
        """Метод для выхода из программы"""

        self.root.destroy()

    def set_text(self, entry, text):
        """Метод для вывода текста в поле на форме"""
        entry.delete(0, tk.END)
        entry.insert(0, text)

    def show_data(self):
        """Метод для вывода данных в форму"""

        number = int(self.number.get())
        profile = self.data[number]
        self.set_text(self.name_entry, text=profile['name'])
        self.set_text(self.lastname_entry, text=profile['lastname'])
        self.set_text(self.status_entry, text=profile['status'])
        self.set_text(self.city_entry, text=profile['city'])
        self.set_text(self.age_entry, text=profile['age'])
        self.set_text(self.gender_entry, text=profile['gender'])

    def get_data_from_db(self):
        """Метод для получения данных из базы и записи в переменные класса"""

        conn = sqlite3.connect('rr.db')
        cur = conn.cursor()
        c = cur.execute("""SELECT name, lastname, photo, status, city, age, gender FROM new_tt""")
        data = c.fetchall()
        for index, (name, lastname, photo, status, city, age, gender) in enumerate(data):
            curImg = cv2.imdecode(np.frombuffer(photo, dtype='uint8'), cv2.IMREAD_COLOR)
            self.data[index] = {'name': name,
                                'lastname': lastname,
                                'status': status,
                                'city': city,
                                'age': age,
                                'gender': gender,
                                }
            self.images.append(curImg)

        conn.close()

        # это можно будет потом вынести в отдельный метод
        self.encodeListKnown = self.findEncodings(self.images)
        print("Декодирование закончено")

    def findEncodings(self, images):
        """Метод для получения списка лиц из списка картинок"""
        encodeList = []
        for img in images:
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            encode = face_recognition.face_encodings(img)[0]
            encodeList.append(encode)
        return encodeList


if __name__ == "__main__":
    root = tk.Tk()
    root.title("Форма с данными")
    root.resizable(False, False)
    Application(root)
    root.mainloop()

Как сделать так, чтобы теперь запускал файл, который включает камеру, определяет лицо и выводит имя и тд, вы говорили про потоки, чтобы сначала запускал камеру, а потом уже в отдельном окне запускал форму с полями. Вывод картинку на форму, тоже было бы не плохо реализовать
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
опробовал работоспособность, получается так, при запуске файла, форму он открывает, когда нажимаю Get data, он выводит данные, но зачем поле номер профиля или Id и номер профиля разные вещи
Номер профиля это просто порядковый номер записи из базы. Программа подключается к базе, достает записи и записывает их в словарь. Ключ словаря это и есть номер профиля.
Как понимаю камеру он включать и не должен в момент когда идет декодирование данных?
Не должен, декодирование это обработка картинок из базы и получение из них картинок лиц.
Как он понимает кто сидит перед ним или он переде по очереди id
камера пока в программе не задействована
Как сделать так, чтобы теперь запускал файл, который включает камеру, определяет лицо и выводит имя и тд
не нужно запускать отдельный файл - нужно в класс добавить 2 метода (старт потока и поток). Это пока не добавил.
Просто вчера вы спрашивали как из базы получить данные - эта программа пример получения данных (и перебора по индексу).
Вывод картинку на форму, тоже было бы не плохо реализовать
это не сложно - вы и сами сможете (добавить в виджеты canvas), а выводить в него картинку по нужному индексу из массива картинок.
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Номер профиля это просто порядковый номер записи из базы. Программа подключается к базе, достает записи и записывает их в словарь. Ключ словаря это и есть номер профиля.

Не должен, декодирование это обработка картинок из базы и получение из них картинок лиц.

камера пока в программе не задействована

не нужно запускать отдельный файл - нужно в класс добавить 2 метода (старт потока и поток). Это пока не добавил.
Просто вчера вы спрашивали как из базы получить данные - эта программа пример получения данных (и перебора по индексу).

это не сложно - вы и сами сможете (добавить в виджеты canvas), а выводить в него картинку по нужному индексу из массива картинок.
Хорошо, попробую добавить вывод картинки. Но почему он при Get_date выводит всегда одну запись, методы потоков если сможете, было бы супер, честно что-то запутался. Как понимаю нужно реализовать потоки, вывод картинки?
 
Последнее редактирование:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Как понимаю нужно реализовать потоки, вывод картинки?
Вывод картинки реализуйте
методы потоков если сможете, было бы супер
Вот добавил распознавание лиц с камеры в потоке:
Python:
import tkinter as tk
import sqlite3
import numpy as np
import face_recognition
import cv2
import threading
import time


class Application(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        # ---------------------Variables-------------------------
        self.root = root
        self.root.geometry("500x500+600+300")
        self.data = {}  # данные из базы {'index': {data}}
        self.images = []  # картинки из базы
        self.encodeListKnown = []  # лица с картинок из базы
        self.run = False

        self.profile = {}
        self.profile_unknown = {'name': 'Неизвестно',
                                'lastname': 'Неизвестно',
                                'status': 'Неизвестно',
                                'city': 'Неизвестно',
                                'age': 'Неизвестно',
                                'gender': 'Неизвестно',
                                }
        self.last_profile = {}

        # ---------------------Widgets---------------------------
        self.name_entry = tk.Entry(self.root)
        self.lastname_entry = tk.Entry(self.root)
        self.status_entry = tk.Entry(self.root)
        self.city_entry = tk.Entry(self.root)
        self.age_entry = tk.Entry(self.root)
        self.gender_entry = tk.Entry(self.root)

        tk.Label(self.root, text="Имя:").grid(row=0, column=0, sticky=tk.W)
        self.name_entry.grid(row=0, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Фамилия:").grid(row=1, column=0, sticky=tk.W)
        self.lastname_entry.grid(row=1, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Статус:").grid(row=2, column=0, sticky=tk.W)
        self.status_entry.grid(row=2, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Город:").grid(row=3, column=0, sticky=tk.W)
        self.city_entry.grid(row=3, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Возраст:").grid(row=4, column=0, sticky=tk.W)
        self.age_entry.grid(row=4, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Пол:").grid(row=5, column=0, sticky=tk.W)
        self.gender_entry.grid(row=5, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Button(self.root, text="Get data", width=10, command=self.get_data_from_db).grid(
            row=6, column=1, sticky=tk.E
        )
        tk.Button(self.root, text="Start", width=10, command=self.start_face_detect).grid(
            row=7, column=1, sticky=tk.E
        )
        tk.Button(self.root, text="Quit", width=10, command=self.exit).grid(
            row=8, column=1, sticky=tk.E
        )
    # -----------------------------Methods-----------------------------------

    def start_face_detect(self):
        """Метод для запуска потока распознавания лиц"""

        if not self.run:
            self.run = True
            t1 = threading.Thread(target=self.face_detect)
            t1.start()

    def face_detect(self):
        """Метод для определения лица (запускает в отдельном потоке)"""
        cap = cv2.VideoCapture(0)
        while True:
            # остановка потока при завершении программы
            if not self.run:
                break

            success, frame = cap.read()

            # если нет видео с камеры - выход
            if not success:
                break

            # уменьшение кадра для ускорения
            rframe = cv2.resize(frame, (0, 0), None, 0.25, 0.25)
            # изменение цветов кадра BGR -> RGB
            rgb_frame = cv2.cvtColor(rframe, cv2.COLOR_BGR2RGB)

            # поиск лиц и их координат
            face_locations = face_recognition.face_locations(rgb_frame)
            face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)


            for encodeFace, faceLoc in zip(face_encodings, face_locations):

                # поиск совпадений
                match = face_recognition.compare_faces(self.encodeListKnown, encodeFace)
                faceDis = face_recognition.face_distance(self.encodeListKnown, encodeFace)

                matchIndex = np.argmin(faceDis)

                # если есть совпадение
                if match[matchIndex]:
                    # получаем профиль
                    self.profile = self.data[matchIndex]

                    # если он изменился - то выводим
                    # если не изменился - то нет смысла выводить
                    if self.profile != self.last_profile:
                        self.last_profile = self.profile
                        self.show_data()

                    y1, x2, y2, x1 = faceLoc
                    y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4

                    # Рисуем рамку
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
                    cv2.rectangle(frame, (x1, y2 - 35), (x2, y2), (0, 255, 0), cv2.FILLED)
                    # Выводим имя на экран
                    cv2.putText(frame, self.profile['name'], (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_DUPLEX, 1, (255, 255, 255), 1)
               
                # если совпадений нет
                else:
                    # меняем профиль на неизвестный профиль
                    self.profile = self.profile_unknown
                    # если на форму был выведен другой профиль
                    # то выводим неизвестный
                    if self.profile != self.last_profile:
                        self.last_profile = self.profile
                        self.show_data()

                    # координаты лица
                    y1, x2, y2, x1 = faceLoc
                    y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4

                    # рисуем рамку
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2)  
                    cv2.rectangle(frame, (x1, y2 - 35), (x2, y2), (0, 0, 255), cv2.FILLED)
                    # Выводим на экран Unknown
                    cv2.putText(frame, 'Unknown', (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 1)
               

            cv2.imshow("WebCam", frame)
            cv2.waitKey(1)

    def exit(self):
        """Метод для выхода из программы"""
        self.run = False
        time.sleep(.1)
        self.root.destroy()

    def set_text(self, entry, text):
        """Метод для вывода текста в поле на форме"""
        entry.delete(0, tk.END)
        entry.insert(0, text)

    def show_data(self):
        """Метод для вывода данных в форму"""

        self.set_text(self.name_entry, text=self.profile['name'])
        self.set_text(self.lastname_entry, text=self.profile['lastname'])
        self.set_text(self.status_entry, text=self.profile['status'])
        self.set_text(self.city_entry, text=self.profile['city'])
        self.set_text(self.age_entry, text=self.profile['age'])
        self.set_text(self.gender_entry, text=self.profile['gender'])

    def get_data_from_db(self):
        """Метод для получения данных из базы и записи в переменные класса"""

        conn = sqlite3.connect('rr.db')
        cur = conn.cursor()
        c = cur.execute("""SELECT name, lastname, photo, status, city, age, gender FROM new_tt""")
        data = c.fetchall()
        for index, (name, lastname, photo, status, city, age, gender) in enumerate(data):
            curImg = cv2.imdecode(np.frombuffer(photo, dtype='uint8'), cv2.IMREAD_COLOR)
            self.data[index] = {'name': name,
                                'lastname': lastname,
                                'status': status,
                                'city': city,
                                'age': age,
                                'gender': gender,
                                }
            self.images.append(curImg)

        conn.close()

        # это можно будет потом вынести в отдельный метод
        self.encodeListKnown = self.findEncodings(self.images)
        print("Декодирование закончено")

    def findEncodings(self, images):
        """Метод для получения списка лиц из списка картинок"""
        encodeList = []
        for img in images:
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            encode = face_recognition.face_encodings(img)[0]
            encodeList.append(encode)
        return encodeList


if __name__ == "__main__":
    root = tk.Tk()
    root.title("Форма с данными")
    root.resizable(False, False)
    Application(root)
    root.mainloop()
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Вывод картинки реализуйте

Вот добавил распознавание лиц с камеры в потоке:
Python:
import tkinter as tk
import sqlite3
import numpy as np
import face_recognition
import cv2
import threading
import time


class Application(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        # ---------------------Variables-------------------------
        self.root = root
        self.root.geometry("500x500+600+300")
        self.data = {}  # данные из базы {'index': {data}}
        self.images = []  # картинки из базы
        self.encodeListKnown = []  # лица с картинок из базы
        self.run = False

        self.profile = {}
        self.profile_unknown = {'name': 'Неизвестно',
                                'lastname': 'Неизвестно',
                                'status': 'Неизвестно',
                                'city': 'Неизвестно',
                                'age': 'Неизвестно',
                                'gender': 'Неизвестно',
                                }
        self.last_profile = {}

        # ---------------------Widgets---------------------------
        self.name_entry = tk.Entry(self.root)
        self.lastname_entry = tk.Entry(self.root)
        self.status_entry = tk.Entry(self.root)
        self.city_entry = tk.Entry(self.root)
        self.age_entry = tk.Entry(self.root)
        self.gender_entry = tk.Entry(self.root)

        tk.Label(self.root, text="Имя:").grid(row=0, column=0, sticky=tk.W)
        self.name_entry.grid(row=0, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Фамилия:").grid(row=1, column=0, sticky=tk.W)
        self.lastname_entry.grid(row=1, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Статус:").grid(row=2, column=0, sticky=tk.W)
        self.status_entry.grid(row=2, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Город:").grid(row=3, column=0, sticky=tk.W)
        self.city_entry.grid(row=3, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Возраст:").grid(row=4, column=0, sticky=tk.W)
        self.age_entry.grid(row=4, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Label(self.root, text="Пол:").grid(row=5, column=0, sticky=tk.W)
        self.gender_entry.grid(row=5, column=1, sticky=tk.W + tk.E, padx=5, pady=5)
        tk.Button(self.root, text="Get data", width=10, command=self.get_data_from_db).grid(
            row=6, column=1, sticky=tk.E
        )
        tk.Button(self.root, text="Start", width=10, command=self.start_face_detect).grid(
            row=7, column=1, sticky=tk.E
        )
        tk.Button(self.root, text="Quit", width=10, command=self.exit).grid(
            row=8, column=1, sticky=tk.E
        )
    # -----------------------------Methods-----------------------------------

    def start_face_detect(self):
        """Метод для запуска потока распознавания лиц"""

        if not self.run:
            self.run = True
            t1 = threading.Thread(target=self.face_detect)
            t1.start()

    def face_detect(self):
        """Метод для определения лица (запускает в отдельном потоке)"""
        cap = cv2.VideoCapture(0)
        while True:
            # остановка потока при завершении программы
            if not self.run:
                break

            success, frame = cap.read()

            # если нет видео с камеры - выход
            if not success:
                break

            # уменьшение кадра для ускорения
            rframe = cv2.resize(frame, (0, 0), None, 0.25, 0.25)
            # изменение цветов кадра BGR -> RGB
            rgb_frame = cv2.cvtColor(rframe, cv2.COLOR_BGR2RGB)

            # поиск лиц и их координат
            face_locations = face_recognition.face_locations(rgb_frame)
            face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)


            for encodeFace, faceLoc in zip(face_encodings, face_locations):

                # поиск совпадений
                match = face_recognition.compare_faces(self.encodeListKnown, encodeFace)
                faceDis = face_recognition.face_distance(self.encodeListKnown, encodeFace)

                matchIndex = np.argmin(faceDis)

                # если есть совпадение
                if match[matchIndex]:
                    # получаем профиль
                    self.profile = self.data[matchIndex]

                    # если он изменился - то выводим
                    # если не изменился - то нет смысла выводить
                    if self.profile != self.last_profile:
                        self.last_profile = self.profile
                        self.show_data()

                    y1, x2, y2, x1 = faceLoc
                    y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4

                    # Рисуем рамку
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
                    cv2.rectangle(frame, (x1, y2 - 35), (x2, y2), (0, 255, 0), cv2.FILLED)
                    # Выводим имя на экран
                    cv2.putText(frame, self.profile['name'], (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_DUPLEX, 1, (255, 255, 255), 1)
          
                # если совпадений нет
                else:
                    # меняем профиль на неизвестный профиль
                    self.profile = self.profile_unknown
                    # если на форму был выведен другой профиль
                    # то выводим неизвестный
                    if self.profile != self.last_profile:
                        self.last_profile = self.profile
                        self.show_data()

                    # координаты лица
                    y1, x2, y2, x1 = faceLoc
                    y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4

                    # рисуем рамку
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2)
                    cv2.rectangle(frame, (x1, y2 - 35), (x2, y2), (0, 0, 255), cv2.FILLED)
                    # Выводим на экран Unknown
                    cv2.putText(frame, 'Unknown', (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 1)
          

            cv2.imshow("WebCam", frame)
            cv2.waitKey(1)

    def exit(self):
        """Метод для выхода из программы"""
        self.run = False
        time.sleep(.1)
        self.root.destroy()

    def set_text(self, entry, text):
        """Метод для вывода текста в поле на форме"""
        entry.delete(0, tk.END)
        entry.insert(0, text)

    def show_data(self):
        """Метод для вывода данных в форму"""

        self.set_text(self.name_entry, text=self.profile['name'])
        self.set_text(self.lastname_entry, text=self.profile['lastname'])
        self.set_text(self.status_entry, text=self.profile['status'])
        self.set_text(self.city_entry, text=self.profile['city'])
        self.set_text(self.age_entry, text=self.profile['age'])
        self.set_text(self.gender_entry, text=self.profile['gender'])

    def get_data_from_db(self):
        """Метод для получения данных из базы и записи в переменные класса"""

        conn = sqlite3.connect('rr.db')
        cur = conn.cursor()
        c = cur.execute("""SELECT name, lastname, photo, status, city, age, gender FROM new_tt""")
        data = c.fetchall()
        for index, (name, lastname, photo, status, city, age, gender) in enumerate(data):
            curImg = cv2.imdecode(np.frombuffer(photo, dtype='uint8'), cv2.IMREAD_COLOR)
            self.data[index] = {'name': name,
                                'lastname': lastname,
                                'status': status,
                                'city': city,
                                'age': age,
                                'gender': gender,
                                }
            self.images.append(curImg)

        conn.close()

        # это можно будет потом вынести в отдельный метод
        self.encodeListKnown = self.findEncodings(self.images)
        print("Декодирование закончено")

    def findEncodings(self, images):
        """Метод для получения списка лиц из списка картинок"""
        encodeList = []
        for img in images:
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            encode = face_recognition.face_encodings(img)[0]
            encodeList.append(encode)
        return encodeList


if __name__ == "__main__":
    root = tk.Tk()
    root.title("Форма с данными")
    root.resizable(False, False)
    Application(root)
    root.mainloop()
Разобрался, сначала Get data нажимаем, он берет все данные из базы, затем кнопка Start, включается камера, он заполняет форму, если направит на другого человека он обновляет форму, все прекрасно, но вот имя выводит почему-то вопросами, как на скрине. Еще такой вопрос, цвет рамки в зависимости от статусу что бы опять изменялся?
 

Вложения

  • Безымянный123.png
    Безымянный123.png
    305,8 КБ · Просмотры: 3
Последнее редактирование:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
но вот имя выводит почему-то вопросами
Возможно проблема в шрифте (у вас его нет на компьютере).
Попробуйте заменить
Python:
cv2.FONT_HERSHEY_DUPLEX
на
Код:
cv2.FONT_HERSHEY_COMPLEX
Еще такой вопрос, цвет рамки в зависимости от статусу что бы опять изменялся?
Это можно сделать также как и раньше с помощью переменной и условий. Статус хранится в self.profile['status']
 

Форум IT Специалистов