распознование лиц
This commit is contained in:
commit
86b87f5cd3
BIN
img/img1.png
Normal file
BIN
img/img1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
BIN
img/img11.jpg
Normal file
BIN
img/img11.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 232 KiB |
BIN
img/license.jpg
Normal file
BIN
img/license.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
BIN
img/license_small.png
Normal file
BIN
img/license_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 111 KiB |
210
main.py
Normal file
210
main.py
Normal file
@ -0,0 +1,210 @@
|
||||
import asyncio
|
||||
import websockets
|
||||
import ffmpeg
|
||||
import json
|
||||
import time
|
||||
import random
|
||||
import os
|
||||
import cv2
|
||||
import numpy as np
|
||||
from threading import Thread
|
||||
from queue import Queue, Empty
|
||||
from threading import Lock
|
||||
import pytesseract
|
||||
import face_recognition
|
||||
|
||||
|
||||
|
||||
template = cv2.imread('img/img1.png', 0)
|
||||
#template = cv2.imread('img/license_small.png', 0)
|
||||
|
||||
|
||||
directoryToSave = "C:/Users/ASUS/Desktop/fishrungame/NEWW/saved"
|
||||
#directoryToSave = "/home/mephi1984/law-video/law-video/saved"
|
||||
ffmpegPath = "C:\\Users\\ASUS\\Desktop\\fishrungame\\NEWW\\ffm\\ffmpeg-2024-02-19-git-0c8e64e268-full_build\\bin\\ffmpeg.exe"
|
||||
#ffmpegPath = "/usr/bin/ffmpeg"
|
||||
pytesseract.pytesseract.tesseract_cmd = r'C:\Users\ASUS\Desktop\fishrungame\treadBibliotek\tesseract.exe'
|
||||
|
||||
if not os.path.exists(directoryToSave):
|
||||
os.makedirs(directoryToSave)
|
||||
|
||||
|
||||
|
||||
def detect_rectangle(frame, template):
|
||||
result = cv2.matchTemplate(frame, template, cv2.TM_CCOEFF_NORMED)
|
||||
_, max_val, _, max_loc = cv2.minMaxLoc(result)
|
||||
|
||||
# Check if the maximum correlation coefficient is above the threshold
|
||||
print(max_val)
|
||||
|
||||
if max_val >= 0.2:
|
||||
# Define the rectangle area
|
||||
h, w = template.shape[:2]
|
||||
top_left = max_loc
|
||||
bottom_right = (top_left[0] + w, top_left[1] + h)
|
||||
|
||||
return True, top_left, bottom_right
|
||||
|
||||
return False, None, None
|
||||
|
||||
|
||||
def process_image(image, top_left, bottom_right):
|
||||
# Cut part with ИДЕНТИФИКАЦИОННАЯ КАРТА
|
||||
card_part = image[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]]
|
||||
# Применение OCR
|
||||
custom_config = r'--oem 3 --psm 6 -l kir+eng+rus'
|
||||
text = pytesseract.image_to_string(card_part, config=custom_config)
|
||||
|
||||
return text, card_part
|
||||
|
||||
|
||||
|
||||
def handle_output(out, frame_lock, frame_container):
|
||||
print("handle_output start")
|
||||
try:
|
||||
while True:
|
||||
in_bytes = out.read(640 * 480 * 3)
|
||||
if not in_bytes:
|
||||
break
|
||||
with frame_lock:
|
||||
frame_container['received_frame'] = np.frombuffer(in_bytes, dtype='uint8').reshape((480, 640, 3))
|
||||
finally:
|
||||
print("finally")
|
||||
|
||||
|
||||
async def save_webm_stream(websocket):
|
||||
|
||||
json_data_received = False
|
||||
|
||||
print("save_webm_stream hello")
|
||||
|
||||
random_number = random.randint(0, 999)
|
||||
|
||||
current_video_timestamp = str(round(time.time() * 1000)) + str(random_number).zfill(3)
|
||||
|
||||
process = (
|
||||
ffmpeg
|
||||
.input('pipe:', format='webm')
|
||||
.output('pipe:', format='rawvideo', pix_fmt='bgr24')
|
||||
.run_async(pipe_stdin=True, pipe_stdout=True, cmd=ffmpegPath)
|
||||
)
|
||||
|
||||
|
||||
frame_lock = Lock()
|
||||
|
||||
frame_container = {'received_frame': None}
|
||||
|
||||
thread = Thread(target=handle_output, args=(process.stdout,frame_lock, frame_container))
|
||||
thread.start()
|
||||
|
||||
stage = 1
|
||||
count = 0
|
||||
last_face_location = None
|
||||
last_face_frame = None
|
||||
|
||||
try:
|
||||
async for message in websocket:
|
||||
if not json_data_received:
|
||||
|
||||
json_data, _, binary_data = message.partition('\0')
|
||||
|
||||
if json_data:
|
||||
|
||||
try:
|
||||
json_object = json.loads(json_data)
|
||||
print("JSON data received:", json_object)
|
||||
except json.JSONDecodeError:
|
||||
print("Invalid JSON")
|
||||
|
||||
json_data_received = True
|
||||
|
||||
if binary_data:
|
||||
process.stdin.write(message)
|
||||
count += len(message)
|
||||
|
||||
else:
|
||||
process.stdin.write(message)
|
||||
count += len(message)
|
||||
|
||||
with frame_lock:
|
||||
local_frame = frame_container['received_frame']
|
||||
|
||||
if local_frame is None:
|
||||
continue
|
||||
|
||||
if stage == 1:
|
||||
gray_frame = cv2.cvtColor(local_frame, cv2.COLOR_BGR2GRAY)
|
||||
result = cv2.matchTemplate(gray_frame, template, cv2.TM_CCOEFF_NORMED)
|
||||
_, max_val, _, max_loc = cv2.minMaxLoc(result)
|
||||
await websocket.send(json.dumps({"stage": 1, "match": max_val}))
|
||||
if max_val > 0.2:
|
||||
success, top_left, bottom_right = detect_rectangle(gray_frame, template)
|
||||
if success:
|
||||
# Вырезаем прямоугольный объект по найденным координатам
|
||||
object_image = local_frame[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]]
|
||||
|
||||
# Сохраняем вырезанный объект
|
||||
cv2.imwrite('object.png', object_image)
|
||||
|
||||
faces_locations = face_recognition.face_locations(local_frame)
|
||||
if len(faces_locations) == 1:
|
||||
top, right, bottom, left = faces_locations[0] # Распаковываем координаты лица
|
||||
face_image = local_frame[top:bottom,
|
||||
left:right] # Извлекаем лицо с использованием координат
|
||||
cv2.imwrite('output1.png', local_frame)
|
||||
cv2.imwrite('output2.png', face_image)
|
||||
lact_face_location = faces_locations
|
||||
last_face_frame = local_frame.copy()
|
||||
|
||||
text, _ = process_image(object_image, (0, 0),
|
||||
(object_image.shape[1], object_image.shape[0]))
|
||||
|
||||
if "идентификационная карта" in text.lower():
|
||||
stage = 2
|
||||
else:
|
||||
os.remove('object.png')
|
||||
continue
|
||||
|
||||
|
||||
elif stage == 2:
|
||||
faces_locations = face_recognition.face_locations(local_frame)
|
||||
face_count = len(faces_locations)
|
||||
face_width1 = 0
|
||||
face_width2 = 0
|
||||
if face_count == 2:
|
||||
top1, right1, bottom1, left1 = faces_locations[0]
|
||||
top2, right2, bottom2, left2 = faces_locations[1]
|
||||
|
||||
face_width1 = right1 - left1
|
||||
face_width2 = right2 - left2
|
||||
|
||||
if (face_width1 > 30) and (face_width2 > 30):
|
||||
face_encodings = [face_recognition.face_encodings(local_frame, [face_location])[0] for face_location in
|
||||
faces_locations]
|
||||
original_face_encoding = face_recognition.face_encodings(last_face_frame, lact_face_location)
|
||||
|
||||
results = face_recognition.compare_faces(face_encodings, original_face_encoding[0])
|
||||
|
||||
if all(results):
|
||||
cv2.imwrite('face_all.png', local_frame)
|
||||
for i, (top, right, bottom, left) in enumerate(faces_locations):
|
||||
cv2.imwrite(f'face_{i + 1}.png', local_frame[top:bottom, left:right])
|
||||
|
||||
await websocket.send(json.dumps({"stage": 3}))
|
||||
break
|
||||
await websocket.send(json.dumps({"stage": 2, "faceCount": face_count, "faceWidth1" : face_width1, "faceWidth2" : face_width2}))
|
||||
|
||||
|
||||
except websockets.exceptions.ConnectionClosed:
|
||||
print("Connection Closed")
|
||||
|
||||
process.stdin.close()
|
||||
#await process.wait()
|
||||
|
||||
|
||||
print("Video server go!")
|
||||
|
||||
start_server = websockets.serve(save_webm_stream, "0.0.0.0", 3001)
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
13
requirements.txt
Normal file
13
requirements.txt
Normal file
@ -0,0 +1,13 @@
|
||||
phonenumbers==8.13.24
|
||||
pytz==2023.3.post1
|
||||
register==0.1
|
||||
sqlparse==0.4.4
|
||||
typing_extensions==4.8.0
|
||||
tzdata==2023.4
|
||||
uritemplate==4.1.1
|
||||
websockets
|
||||
ffmpeg-python
|
||||
opencv-python
|
||||
numpy
|
||||
face_recognition
|
||||
pytesseract
|
Loading…
Reference in New Issue
Block a user