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

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);
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Создам поля, попробую их привязать к имени, а дальше может с вашей помощью получится сделать
Можете попробовать эти поля сначала в том же окне что и имя вывести, просто шрифт уменьшить чтобы они влезли это проще будет.
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
как их прям привязать, не могу понять, еще и каждое поле из таблицы:
Можно сделать вложенный словарь {'имя': {данные}}. Вот так например:
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)
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
А вот как это еще реализовать в отдельное окно, чтобы записывалась как в форму данные
Если форму делать на tkinter, то она должна быть главным окном (запускаться в основном потоке), а функцию face_detect нужно будет запускать в другом потоке чтобы не блокировать отрисовку формы.
Нужно вашу форму переписать в виде класса, функцию face_detect поместить в отдельный поток (нужно будет добавить функцию для старта потока) и запускать либо со старта приложения либо по кнопке, данные между потоками можно передавать через переменные класса.
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
хочу реализовать, чтобы теперь после создание БД, при запуске программы, данные считывались из таблицы, а точнее имя фотографии
У вас в коде (в начале функции face_detect) картинки и имена записываются в два списка images и classNames. Эти списки заполняются на основе файлов из папки. Чтобы они заполнялись из базы можно изменить эту часть кода:

Python:
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)
на такую:
Python:
def face_detect():
    conn = sqlite3.connect('rr.db')
    cur = conn.cursor()
    c = cur.execute("""SELECT name, photo FROM new_tt""")

    data = c.fetchall()

    for name, photo in data:
        curImg = cv2.imdecode(np.frombuffer(photo, dtype='uint8'), cv2.IMREAD_COLOR)
        images.append(curImg)
        classNames.append(name)

    print(classNames)
    print(images)

    conn.close()
а также добавить импорт:
Python:
import sqlite3
 
Последнее редактирование:

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
У вас в коде (в начале функции face_detect) картинки и имена записываются в два списка images и classNames. Эти списки заполняются на основе файлов из папки. Чтобы они заполнялись из базы можно изменить эту часть кода:

Python:
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)
на такую:
Python:
def face_detect():
    conn = sqlite3.connect('rr.db')
    cur = conn.cursor()
    c = cur.execute("""SELECT name, photo FROM new_tt""")

    data = c.fetchall()

    for name, photo in data:
        curImg = cv2.imdecode(np.frombuffer(photo, dtype='uint8'), cv2.IMREAD_COLOR)
        images.append(curImg)
        classNames.append(name)

    print(classNames)
    print(images)

    conn.close()
а также добавить импорт:
Python:
import sqlite3



c = cur.execute("""SELECT name, photo FROM new_tt""")
sqlite3.OperationalError: no such table: new_tt

Странно, пишет, что такой таблице нет, хотя она и есть и в ней есть 3 записи, не могу понять почему пишет, что нет таблицы, сейчас добавил еще одну запись, все прекрасно добавилось в таблицу

insert_blob(4, "Кристина", "Кристина.jpg", "resume_Vadim.docx") - в файл db.py, добавил запись и в таблицу все добавилось
 
Последнее редактирование:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Странно, пишет, что такой таблице нет, хотя она и есть и в ней есть 3 записи
Таблицу нужно создать. У вас в коде она только заполняется, но не создается.
Вот пример:
Python:
import sqlite3

conn = sqlite3.connect('rr.db')
cur = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS `new_tt` (`id` INTEGER PRIMARY KEY, `name` TEXT NOT NULL, `photo` BLOB NOT NULL, `resume` BLOB NOT NULL);")
cursor.close()
conn.close()
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Таблицу нужно создать. У вас в коде она только заполняется, но не создается.
Вот пример:
Python:
import sqlite3

conn = sqlite3.connect('rr.db')
cur = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS `new_tt` (`id` INTEGER PRIMARY KEY, `name` TEXT NOT NULL, `photo` BLOB NOT NULL, `resume` BLOB NOT NULL);")
cursor.close()
conn.close()


Создал таблицу в файле db.py

SQL:
cur.execute("""CREATE TABLE IF NOT EXISTS `new_tt`(
`id` INTEGER PRIMARY KEY,
`name` TEXT NOT NULL,
`photo` BLOB NOT NULL,
`resume` BLOB NOT NULL);
""")
cur.close()
conn.close()

Ошибка та же, так же не может найти таблицу new_tt

c = cur.execute("""SELECT name, photo FROM new_tt""")
sqlite3.OperationalError: no such table: new_tt

Или таблицу нужно создать в face_detect?
 
Последнее редактирование:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Ошибка та же, так же не может найти таблицу new_tt
Возможно вы создаете таблицу в другой базе. Так как если таблица есть в базе - запрос к ней должен работать.
Попробуйте удалить базу, создать новую, создать там таблицу, заполнить ее и попробовать к ней подключиться.
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Возможно вы создаете таблицу в другой базе. Так как если таблица есть в базе - запрос к ней должен работать.
Попробуйте удалить базу, создать новую, создать там таблицу, заполнить ее и попробовать к ней подключиться.
Таблицу же нужно создать в db.py? Где код соединения с базой
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Возможно вы создаете таблицу в другой базе. Так как если таблица есть в базе - запрос к ней должен работать.
Попробуйте удалить базу, создать новую, создать там таблицу, заполнить ее и попробовать к ней подключиться.
Сейчас в выводе пишет:

[]
[]
Декодирование закончено
[]

File "C:\Pychar\FaceRecognition.py", line 75, in face_detect
matchIndex = np.argmin(faceDis)

File "<__array_function__ internals>", line 5, in argmin
File "C:\Pychar\venv\lib\site-packages\numpy\core\fromnumeric.py", line 1276, in argmin
return _wrapfunc(a, 'argmin', axis=axis, out=out)

File "C:\Pychar\venv\lib\site-packages\numpy\core\fromnumeric.py", line 57, in _wrapfunc
return bound(*args, **kwds)
ValueError: attempt to get argmin of an empty sequence
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Сейчас в выводе пишет:

[]
[]
Декодирование закончено
[]

File "C:\Pychar\FaceRecognition.py", line 75, in face_detect
matchIndex = np.argmin(faceDis)

File "<__array_function__ internals>", line 5, in argmin
File "C:\Pychar\venv\lib\site-packages\numpy\core\fromnumeric.py", line 1276, in argmin
return _wrapfunc(a, 'argmin', axis=axis, out=out)

File "C:\Pychar\venv\lib\site-packages\numpy\core\fromnumeric.py", line 57, in _wrapfunc
return bound(*args, **kwds)
ValueError: attempt to get argmin of an empty sequence


Он включает камеру, когда идет декодирование, но экрана трансляции видео нет, и сразу же выключает и получаю ошибки, которые уже написал)
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Таблицу же нужно создать в db.py? Где код соединения с базой
Таблицу нужно создавать в базе rr.db.
Вот так:
Python:
import sqlite3

conn = sqlite3.connect('rr.db')
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS `new_tt` (`id` INTEGER PRIMARY KEY, `name` TEXT NOT NULL, `photo` BLOB NOT NULL, `resume` BLOB NOT NULL);")
cur.close()
conn.close()
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
ValueError: attempt to get argmin of an empty sequence
Видимо в таблице в базе пока нет данных.
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Тогда вот еще вопрос, то что у меня база в отдельной папке, вот как на скрине. То есть в папке db, в файле db.py там код
Python:
import sqlite3

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


cur.execute("""CREATE TABLE IF NOT EXISTS `new_tt`(
`id` INTEGER PRIMARY KEY,
`name` TEXT NOT NULL,
`photo` BLOB NOT NULL,
`resume` BLOB 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, 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(6, "Кристина", "Кристина.jpg", "resume_Vadim.docx")

И как понимаю теперь еще создалась база rr.db. Запутался в этих базах, то есть вторую базу он создал исходя из этого кода
Python:
def face_detect():
    conn = sqlite3.connect('rr.db')
    cur = conn.cursor()
    c = cur.execute("""SELECT  name, photo FROM new_tt""")
Которая где main, FindClone и тд
Безымянный.png
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Сейчас проверил, если я удаляю базу rr.db где main, FindClone и тд, и запускай Основной файл FaceRecognition, то он снова создает rd.db где main и тд пишет, что опять таблица не найдена
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Тогда вот еще вопрос, то что у меня база в отдельной папке, вот как на скрине
Тогда нужно к ней подключаться:
Python:
conn = sqlite3.connect('db/rr.db')
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Тогда нужно к ней подключаться:
Python:
conn = sqlite3.connect('db/rr.db')
Спасибо, теперь работает)
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Тогда нужно к ней подключаться:
Python:
conn = sqlite3.connect('db/rr.db')
У меня уже очень поздно, можно я завтра вам сюда же задам еще вопрос?
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
У меня уже очень поздно, можно я завтра вам сюда же задам еще вопрос?
Конечно.
 

vadimppp

Новичок
Пользователь
Сен 30, 2021
48
0
6
Спасибо, буду ждать завтра ответа от вас
 

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