#python-3.x #face-recognition #image-recognition
Вопрос:
извините за мой плохой английский. Я пытаюсь сравнить два лица, используя модуль python3 «распознавание лиц»
вот пример вычисления евклидова расстояния в python
pdist([вектор1, вектор2], «евклидово»)
Я хочу вычислить евклидово расстояние только в SQL-запросе, потому что все грани(их векторы) будут храниться в моей базе данных, но я не знаю, как это сделать с помощью SQL-запроса.
Информация:
Версия MariaDB: 10.5.11
Python: 3.9.2
#!/usr/bin/env python3
import cv2
import face_recognition
import mysql.connector as mysql
def get_image_hash(image):
# Open image
img = face_recognition.load_image_file(image)
# Save as black
#img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Get vector
vector = face_recognition.face_encodings(img)[0]
vector = (str(vector),)
return vector
# Open DB
conn = mysql.connect(
host = '127.0.0.1',
user = 'user',
passwd = 'password'
)
cur = conn.cursor()
cur.execute("SHOW DATABASES")
# Check if db 'test' already exist
db_found = False
for db in cur:
if 'test' in db:
db_found = True
if not db_found:
cur.execute("CREATE DATABASE IF NOT EXISTS test;")
conn.commit()
cur.execute("USE test;")
cur.execute("""CREATE TABLE IF NOT EXISTS faces(id_face BIGINT PRIMARY KEY NOT NULL AUTO_INCREMENT, face_hash TEXT)""")
new_image = get_image_hash('test.jpg')
# Add face(array) in DB
cur.execute('''INSERT INTO faces (face_hash) VALUES(%s)''', new_image)
conn.commit()
# Upload a picture for search
find_me_image = get_image_hash('findme.jpg')
#print('d: ', find_me_image[0])
# How should i compare these two arrays in my SQL query to find a similar face?
cur.execute("SELECT * FROM faces WHERE ..... ;")
cur.close()
print('find_me_image: ', str(find_me_image))
print('new_image: ', str(new_image))
Результат:
Find_me_image: ('[-0.04221933 0.04460172 0.10287622 -0.14319997 -0.13808066 0.00552465n -0.04414323 -0.07157505 0.23200855 -0.12091423 0.16892464 -0.16992114n -0.2487883 0.09141497 -0.14198568 0.1824664 -0.11484738 -0.1130986n -0.14396232 -0.06075872 -0.00201617 0.07473749 -0.01706937 0.05610432n -0.11021845 -0.30173326 -0.02712429 -0.10394925 -0.05155517 -0.21909578n 0.03083897 0.16680503 -0.09715255 -0.0407755 -0.01714687 0.08432341n -0.01913652 -0.13662203 0.21924476 0.04394831 -0.20848413 -0.03259828n 0.04784738 0.30321479 0.22730266 -0.02372641 -0.01165112 -0.12765107n 0.13877977 -0.3403039 0.0424962 0.10813272 0.0511388 0.12078771n 0.04942191 -0.13038178 0.02736722 0.15339687 -0.24367541 0.10453884n 0.13450858 -0.09997959 0.01744595 -0.10602434 0.2614505 0.10681546n -0.12075276 -0.12065229 0.195976 -0.11606392 -0.0447496 0.08198876n -0.13573587 -0.18409243 -0.19127932 0.01680213 0.35644779 0.16652581n -0.12988403 -0.00341757 -0.15569599 -0.09128557 -0.03799717 0.09235845n 0.06296059 -0.07972728 0.00744779 0.07452074 0.23394027 -0.0726112n -0.00072305 0.2978259 -0.01452125 -0.06529554 -0.08694689 0.01903715n -0.14941891 0.10714116 -0.1096215 0.00143995 0.00146057 0.00348109n 0.06795555 0.10826397 -0.18627991 0.21965174 -0.04136307 -0.01491791n 0.03774849 -0.07495191 -0.03808937 -0.02331351 0.29242265 -0.23740929n 0.13265632 0.1274993 0.17672779 0.11845816 0.01477844 0.07670261n 0.11437597 -0.03779818 -0.21296507 0.03480547 0.06180557 -0.01749492n -0.023851 0.11586148]',)
New_image: ('[-0.04221933 0.04460172 0.10287622 -0.14319997 -0.13808066 0.00552465n -0.04414323 -0.07157505 0.23200855 -0.12091423 0.16892464 -0.16992114n -0.2487883 0.09141497 -0.14198568 0.1824664 -0.11484738 -0.1130986n -0.14396232 -0.06075872 -0.00201617 0.07473749 -0.01706937 0.05610432n -0.11021845 -0.30173326 -0.02712429 -0.10394925 -0.05155517 -0.21909578n 0.03083897 0.16680503 -0.09715255 -0.0407755 -0.01714687 0.08432341n -0.01913652 -0.13662203 0.21924476 0.04394831 -0.20848413 -0.03259828n 0.04784738 0.30321479 0.22730266 -0.02372641 -0.01165112 -0.12765107n 0.13877977 -0.3403039 0.0424962 0.10813272 0.0511388 0.12078771n 0.04942191 -0.13038178 0.02736722 0.15339687 -0.24367541 0.10453884n 0.13450858 -0.09997959 0.01744595 -0.10602434 0.2614505 0.10681546n -0.12075276 -0.12065229 0.195976 -0.11606392 -0.0447496 0.08198876n -0.13573587 -0.18409243 -0.19127932 0.01680213 0.35644779 0.16652581n -0.12988403 -0.00341757 -0.15569599 -0.09128557 -0.03799717 0.09235845n 0.06296059 -0.07972728 0.00744779 0.07452074 0.23394027 -0.0726112n -0.00072305 0.2978259 -0.01452125 -0.06529554 -0.08694689 0.01903715n -0.14941891 0.10714116 -0.1096215 0.00143995 0.00146057 0.00348109n 0.06795555 0.10826397 -0.18627991 0.21965174 -0.04136307 -0.01491791n 0.03774849 -0.07495191 -0.03808937 -0.02331351 0.29242265 -0.23740929n 0.13265632 0.1274993 0.17672779 0.11845816 0.01477844 0.07670261n 0.11437597 -0.03779818 -0.21296507 0.03480547 0.06180557 -0.01749492n -0.023851 0.11586148]',)
Новое:
#!/usr/bin/env python3
import cv2
import json
import face_recognition
import mysql.connector as mysql
# DB
conn = mysql.connect(
host = 'localhost',
user = '',
passwd = ''
)
def load(str_data):
str_data = str_data.replace("[", "").replace("]", "")
result = []
for i, line in enumerate(str_data.split("n")):
result.append([])
for element in line.replace(" ", " ").split(" "):
try:
result[i].append(float(element))
except ValueError:
pass
return result
def distance(model, test):
distance = 0
for i, line in enumerate(model):
dist_line = 0
for j, element in enumerate(line):
dist_line = (element - test[i][j]) ** 2
distance = dist_line ** 0.5
return distance
def get_image_hash(image):
# Open image
img = face_recognition.load_image_file(image)
# Save as black
#img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Get vector
vector = face_recognition.face_encodings(img)[0]
# We can save only iterable object
vector = (str(vector),)
return vector
cur = conn.cursor(buffered=True)
cur.execute("SHOW DATABASES")
# Check if db 'test' already exist
db_found = False
for db in cur:
if 'test' in db:
db_found = True
if not db_found:
cur.execute("CREATE DATABASE IF NOT EXISTS test;")
conn.commit()
cur.execute("USE test;")
cur.execute("""CREATE TABLE IF NOT EXISTS faces(id_face BIGINT PRIMARY KEY NOT NULL AUTO_INCREMENT, face_hash TEXT)""")
# Add face in DB
new_image = get_image_hash('test.jpg')
print('new_image debug: ', new_image)
cur.execute('''INSERT INTO faces (face_hash) VALUES(%s)''', new_image)
conn.commit()
# Find added face
find_me_image = get_image_hash('findme.jpg')
print('debug find_me_image: ', find_me_image)
# Get data from DB
cur.execute("SELECT * FROM faces;")
face_data = cur.fetchall()
# Check
for x in face_data:
print('1: ', load(find_me_image[0]))
print('2: ', load(x[1]))
# x[1] == row face_hash
compare_result = distance(load(find_me_image[0]), load(x[1]))
#print('Result: ', compare_result)
# Got error
'''
Traceback (most recent call last):
File "/home/user/Desktop/parser_steam/image_recognition/test/./test.py", line 102, in <module>
compare_result = distance(load(find_me_image[0]), load(x[1]))
File "/home/user/Desktop/parser_steam/image_recognition/test/./test.py", line 35, in distance
dist_line = (element - test[i][j]) ** 2
IndexError: list index out of range
'''
cur.close()
Комментарии:
1.
print(Find_me_image == New_image)
->True
Здесь расстояние равно 0…
Ответ №1:
Вот что вам нужно!
import json
def load(str_data):
str_data = str_data.replace("[", "").replace("]", "")
result = []
for i, line in enumerate(str_data.split("n")):
result.append([])
for element in line.replace(" ", " ").split(" "):
try:
result[i].append(float(element))
except ValueError:
pass
return result
def distance(model, test):
distance = 0
for i, line in enumerate(model):
dist_line = 0
for j, element in enumerate(line):
dist_line = (element - test[i][j]) ** 2
distance = dist_line ** 0.5
return distance
if __name__ == "__main__":
Find_me_image = '[-0.04221933 0.04460172 0.10287622 -0.14319997 -0.13808066 0.00552465n -0.04414323 -0.07157505 0.23200855 -0.12091423 0.16892464 -0.16992114n -0.2487883 0.09141497 -0.14198568 0.1824664 -0.11484738 -0.1130986n -0.14396232 -0.06075872 -0.00201617 0.07473749 -0.01706937 0.05610432n -0.11021845 -0.30173326 -0.02712429 -0.10394925 -0.05155517 -0.21909578n 0.03083897 0.16680503 -0.09715255 -0.0407755 -0.01714687 0.08432341n -0.01913652 -0.13662203 0.21924476 0.04394831 -0.20848413 -0.03259828n 0.04784738 0.30321479 0.22730266 -0.02372641 -0.01165112 -0.12765107n 0.13877977 -0.3403039 0.0424962 0.10813272 0.0511388 0.12078771n 0.04942191 -0.13038178 0.02736722 0.15339687 -0.24367541 0.10453884n 0.13450858 -0.09997959 0.01744595 -0.10602434 0.2614505 0.10681546n -0.12075276 -0.12065229 0.195976 -0.11606392 -0.0447496 0.08198876n -0.13573587 -0.18409243 -0.19127932 0.01680213 0.35644779 0.16652581n -0.12988403 -0.00341757 -0.15569599 -0.09128557 -0.03799717 0.09235845n 0.06296059 -0.07972728 0.00744779 0.07452074 0.23394027 -0.0726112n -0.00072305 0.2978259 -0.01452125 -0.06529554 -0.08694689 0.01903715n -0.14941891 0.10714116 -0.1096215 0.00143995 0.00146057 0.00348109n 0.06795555 0.10826397 -0.18627991 0.21965174 -0.04136307 -0.01491791n 0.03774849 -0.07495191 -0.03808937 -0.02331351 0.29242265 -0.23740929n 0.13265632 0.1274993 0.17672779 0.11845816 0.01477844 0.07670261n 0.11437597 -0.03779818 -0.21296507 0.03480547 0.06180557 -0.01749492n -0.023851 0.11586148]'
New_image = '[-0.04221933 0.04460172 0.10287622 -0.14319997 -0.13808064 0.00552465n -0.04414323 -0.07157505 0.23200855 -0.12091423 0.16892464 -0.16992114n -0.2487883 0.09141497 -0.14198568 0.18246 -0.11484738 -0.1130986n -0.14396232 -0.06075872 -0.0020117 0.07473749 -0.01706937 0.05610432n -0.11021845 -0.30173326 -0.02712429 -0.10394925 -0.05155517 -0.21909578n 0.03083897 0.16680503 -0.09715255 -0.0407755 -0.01714687 0.08432341n -0.01913652 -0.13662203 0.21924476 0.04394831 -0.20848413 -0.03259828n 0.04784738 0.30321479 0.22730266 -0.02372641 -0.0116112 -0.12765107n 0.13877977 -0.3403039 0.0424962 0.10813272 0.0511388 0.12078771n 0.04942191 -0.13038178 0.02736722 0.15339687 -0.24367541 0.10453884n 0.13450858 -0.09997959 0.01744595 -0.10602434 0.2614505 0.10681546n -0.12075276 -0.12065229 0.195976 -0.11606392 -0.0447496 0.08198876n -0.1357387 -0.18409243 -0.19127932 0.01680213 0.35644779 0.16652581n -0.12988403 -0.00341757 -0.15569599 -0.09128557 -0.03799717 0.09235845n 0.06296059 -0.07972728 0.00744779 0.07452074 0.23394027 -0.0726112n -0.00072305 0.2978259 -0.01452125 -0.06529554 -0.08694689 0.0193715n -0.14941891 0.10714116 -0.1096215 0.00143995 0.00146057 0.00348109n 0.06795555 0.10826397 -0.18627991 0.21965174 -0.04136307 -0.01491791n 0.03774849 -0.07495191 -0.03808937 -0.02331351 0.29242265 -0.23740929n 0.13265632 0.1274993 0.1762779 0.11845816 0.01477844 0.07670261n 0.11437597 -0.03779818 -0.21296507 0.03480547 0.0618057 -0.01749492n -0.023851 0.1158648]'
print(distance(
load(Find_me_image),
load(New_image)
))
Сначала вам нужно преобразовать ваши данные с помощью load
функции. Затем рассчитайте расстояние с помощью distance
функции.
Поскольку ваши данные являются именами, я изменяю New_image
данные, чтобы протестировать функцию.
Комментарии:
1. спасибо за помощь!! Если я все правильно понял, сначала мне придется получить ВСЕ(у меня их будет много «>1000000») хэши из базы данных, а затем преобразовать и сравнить их в python? Я сохраню все векторы изображений в базе данных(я еще не знаю, какой тип данных для этого я должен использовать), и мне нужно вычислить евклидово расстояние между вектором моего изображения и всеми векторами, которые находятся в базе данных, используя только SQL-запрос.
2. Нет, вы можете запускать процесс по одному, чтобы не переполнять свою оперативную память 1000000 примерами. Массивы-это не хэши, а массивы, и вы не должны хранить кратные данные в одной базе данных, назовите свои столбцы. Затем вы можете посмотреть на триггеры в базе данных, чтобы выполнять этот расчет расстояния при каждом новом вводе лица в БД. Но ваш вопрос касается получения данных и расчета расстояния. Не забудьте поставить зеленую галочку, если ответили!
3. Привет, Винсент! пожалуйста, можете ли вы проверить(если у вас есть свободное время), почему при расчете евклидова расстояния между списками я получаю ошибку: dist_line = (элемент — тест[i][j]) ** 2 Я добавил новый код для публикации.
4. Эй, вам нужен 2D массив, чтобы функция работала, здесь вы даете 1 D массив
5. Bonjour! Я нашел ошибку, но не понимаю, как ее исправить. Ошибка заключается в том, что последний массив одной фотографии содержит 2 элемента, а остальные 4 элемента. можете ли вы попробовать запустить его самостоятельно?