Was mich überraschte war, dass ich mit einem Funktionscode die gewünschten Ergebnisse erzielen konnte. Die folgende Abbildung zeigt den Bildschirm (Echtzeitvideo), auf dem mit der iPad-App 68 Gesichtsdaten von dlib generiert, über das Internet auf dem Server weitergeleitet und auf dem Mac angezeigt wurden. Der Python-Code für diese Anzeige lautet [Code]. 1] Wie gezeigt, gibt es nur etwa 30 Zeilen. Für Pythonisten ist es offensichtlich, für Anfänger jedoch erstaunlich. Ich hatte das Gefühl, dass es das Stärkste für Prototyping-Ideen ist.
Die Seite, die Gesichtsmarkierungsdaten aus dem Gesichtsbild der Kamera erstellt und mit udp sendet, Ich habe das folgende Git Xcode Projekt verwendet. (Zu git des gleichen Autors, Android-Version, Es gibt auch eine Javascript-Version. )
https://github.com/Tastenkunst/brfv4_ios_examples
Ändern Sie track_single_face.hpp darin wie folgt.
addr.sin_port = htons(5000); addr.sin_addr.s_addr = inet_addr("XXX.XX.XXX.XXX");
Portnummer 5000 und Die IP von "XXX.XX.XXX.XXX" entspricht Ihren Einstellungen. Wenn Sie ein Xcode-Projekt erstellen und starten und ein Bild von Ihrem Gesicht aufnehmen, werden die Positionsdaten von 68 Gesichtspunkten als 68 x 2 Byte Daten an den Server gesendet.
track_single_face.hpp
#ifndef __brf__cpp__BRFCppExample_hpp
#define __brf__cpp__BRFCppExample_hpp
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
namespace brf {
class BRFCppExample: public BRFBasicCppExample {
int sock;
struct sockaddr_in addr;
uint16_t shorts;
uint8_t bytes[sizeof(uint8_t)*136*2];
public: BRFCppExample() : BRFBasicCppExample()
{
addr.sin_family = AF_INET;
addr.sin_port = htons(5000);
addr.sin_addr.s_addr = inet_addr("XXX.XX.XXX.XXX");
//sock = socket(AF_INET, SOCK_DGRAM, 0);
}
public: void initCurrentExample(brf::BRFManager& brfManager, brf::Rectangle& resolution) {
brf::trace("BRFv4 - basic - face tracking - track single face" + brf::to_string("\n")+
"Detect and track one face and draw the 68 facial landmarks.");
}
public: void updateCurrentExample(brf::BRFManager& brfManager, brf::DrawingUtils& draw) {
// In a webcam example imageData is the mirrored webcam video feed.
// In an image example imageData is the (not mirrored) image content.
brfManager.update();
// Drawing the results:
draw.clear();
// Face detection results: a rough rectangle used to start the face tracking.
//draw.drawRects(brfManager.getAllDetectedFaces(), false, 1.0, 0x00a1ff, 0.5);
//draw.drawRects(brfManager.getMergedDetectedFaces(), false, 2.0, 0xffd200, 1.0);
// Get all faces. The default setup only tracks one face.
std::vector< std::shared_ptr<brf::BRFFace> >& faces = brfManager.getFaces();
for(size_t i = 0; i < faces.size(); i++) {
brf::BRFFace& face = *faces[i];
if( face.state == brf::BRFState::FACE_TRACKING_START ||
face.state == brf::BRFState::FACE_TRACKING) {
sock = socket(AF_INET, SOCK_DGRAM, 0);
for(int i = 0; i < 136; i++){
shorts = (int)face.vertices[i];
bytes[i * 2] = (uint8_t) (shorts & 0xFF);
bytes[(i * 2) + 1] = (uint8_t) (shorts >> 8);
}
sendto(sock, bytes, sizeof(bytes), 0, (struct sockaddr *)&addr, sizeof(addr));
close(sock);
//draw.drawTriangles( face.vertices, face.triangles, false, 1.0, 0x00a0ff, 0.4);
draw.drawVertices( face.vertices, 2.0, false, 0x00a0ff, 0.4);
}
}
}
};
}
#endif // __brf__cpp__BRFCppExample_hpp
Als nächstes kommt die Serverseite. Es ist ein Code, der nur die Orientierungspunktdaten an die LAN-Seite sendet. Die Portnummer und die IP werden an Ihre Umgebung angepasst. Das Schreiben in Python macht das Schreiben auf der Serverseite einfach.
sendBak.py
import socket
import time
print (time.ctime(),flush=True)
host = '192.168.10.101'
port = 5001
bufsize = 512
portFace = 5000
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#sock.settimeout(0.01)
sock.bind((host,port))
#
sock2 = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock2.settimeout(30.0)
sock2.bind((host,portFace))
while True:
global data, addr
string,addr = sock.recvfrom(bufsize)
print("from:",addr,time.ctime())
while True:
try:
data, (host, port) = sock2.recvfrom(bufsize)
result = sock.sendto(data,addr)
#if result != 272:
# print(result)
except socket.error as e:
#print ('Error: %s' % e)
break
Schließlich die empfangende Seite. Es spielt keine Rolle, ob Python unter Mac, Windows oder Linux funktioniert. Sie können Pythoinista auch unter iOS verwenden.
FaceLineOpenCV.py
import cv2
import socket
import numpy as np
from struct import unpack
from datetime import datetime
host = 'XXXX.com'
port = 5001
message = b'hello'
if __name__ == "__main__" :
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#server.bind(('192.168.2.100', 5000))
width = 600
height = 800
img = np.zeros((height, width, 3), np.uint8)
server.sendto(message, (host, port))
while True:
data, addr = server.recvfrom(1024)
cv2.rectangle(img, (0, 0), (600, 700), color=(255, 0, 0), thickness=-1)
val = unpack('<'+'H'*(len(data)//2), data)
j = 0
for i in range(64):
cv2.circle(img, (int(val[j]), int(val[j+1])), 4, (255, 255, 256), -1)
j = j + 2
cv2.imshow('camera capture', img)
k = cv2.waitKey(1) #
if k == 27:
break
cv2.destroyAllWindows()
FaceLineQt.py
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QTimer
import socket
import numpy as np
from struct import unpack
host = 'XXXX.com'
port = 5001
bufsize = 512
message = b'hello'
class Widget(QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.timer = QTimer(self)
self.timer.timeout.connect(self.update)
self.timer.start(20)#aktualisieren
#
self.server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#self.server.settimeout(0.5)
#self.server.setblocking(False)
#self.img = np.zeros((height, width, 3), np.uint8)
self.server.sendto(message, (host, port))
def paintEvent(self, event):
data, addr = self.server.recvfrom(bufsize)
val = unpack('<'+'H'*(len(data)//2), data)
painter = QPainter(self)
painter.setPen(Qt.red)
painter.setBrush(Qt.red)
j = 0
for i in range(68):
painter.drawRect(int(val[j]), int(val[j+1]), 5, 5)
j = j + 2
def main():
app = QApplication(sys.argv)
w = Widget()
w.show()
w.raise_()
app.exec_()
if __name__ == '__main__':
main()
Ich werde später eine Codebeschreibung hinzufügen.
Pythonista-Version hinzugefügt. Verwenden Sie für Pythonista eine schnelle Szene.
FalceLinePythonista.py
from scene import *
import socket
import numpy as np
from struct import unpack
host = 'XXXX.com'
port = 5001
bufsize = 512
class FaceLine (Scene):
def setup(self):
self.landmarks = []
for i in range(68):
shape = ShapeNode(ui.Path.oval(0,0,5,5), 'white')
self.landmarks.append(shape)
self.add_child(shape)
self.server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#
message = b'hello'
self.server.sendto(message, (host, port))
def update(self):
#
data, addr = self.server.recvfrom(bufsize)
val = unpack('<'+'H'*(len(data)//2), data)
dtx = np.array(val[::2])
dty = np.array(val[1::2])
for i in range(68):
self.landmarks[i].position = (dtx[i]+200,800-dty[i])
run(FaceLine())
Recommended Posts