Add video abstraction class

This commit is contained in:
Cole Deck 2024-02-17 20:06:37 -06:00
parent fc6baa8826
commit 0299b3877d
7 changed files with 259 additions and 23 deletions

166
banner_ivu_export.py Executable file
View File

@ -0,0 +1,166 @@
#!/usr/bin/env python3
import socket
from datetime import datetime
from time import sleep
from util import fprint
"""
from: https://github.com/MoisesBrito31/ve_data_log/blob/main/serverContagem/VE/drive.py
(no license)
(partially) adapted to English language & iVu camera instead of classic VE by Cole Deck
"""
def gravaLog(ip="1",tipo="Evento", msg="", file="log_imagem.txt"):
# removed full logging
fprint(msg)
class DriveImg():
HEADERSIZE = 100
ip = "192.168.0.1"
port = 32200
onLine = False
def __init__(self, ip, port, pasta = "media/"):
self.pasta = pasta
self.ip=ip
self.port = port
self.trans = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.trans.settimeout(5)
fprint("Trying to connect...")
try:
self.trans.connect((self.ip,self.port))
self.onLine = True
fprint("Camera Online")
#self.trans.close()
except:
self.onLine = False
fprint("Offline")
def read_img(self):
resposta = 'Falha'
try:
if not self.onLine:
#print(f'tentando Conectar camera {self.ip}...')
gravaLog(ip=self.ip,msg=f'Trying to connect...')
sleep(2)
try:
self.trans = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.trans.connect((self.ip,self.PORT))
self.onLine = True
gravaLog(ip=self.ip,msg=f'Connection established.')
except:
self.onLine = False
self.trans.close()
return resposta
ret = self.trans.recv(64)
try:
valida = str(ret[0:15].decode('UTF-8'))
#print(valida)
if valida.find("TC IMAGE")<0:
self.onLine = False
self.trans.close()
sleep(2)
gravaLog(ip=self.ip,tipo="Falha",msg=f'Unable to find TC IMAGE bookmark')
return "Error"
except Exception as ex:
self.onLine = False
self.trans.close()
sleep(2)
gravaLog(ip=self.ip,tipo="Falha",msg=f'Error - {str(ex)}')
return "Error"
if ret:
frame = int.from_bytes(ret[24:27],"little")
isJpeg = int.from_bytes(ret[32:33],"little")
img_size = int.from_bytes(ret[20:23],"little")
data = self.trans.recv(5000)
while img_size>len(data) and ret:
ret = self.trans.recv(10000)
if ret:
data = data+ret
#print(f'{len(ret)}b dados recebidos, total de: {len(data)+64}b')
else:
gravaLog(ip=self.ip,tipo="Falha",msg="Unable to recieve the image")
self.onLine = False
return "Unable to recieve the image"
hoje = datetime.now()
idcam = self.ip.split('.')
"""try:
nomeFile = f'{hoje.day}{hoje.month}{hoje.year}-{idcam[3]}-{frame}'
if isJpeg==1:
file = open(f'{self.pasta}{nomeFile}.jpg','wb')
nomeFile = f'{nomeFile}.jpg'
else:
file = open(f'{self.pasta}{nomeFile}.bmp','wb')
nomeFile = f'{nomeFile}.bmp'
file.write(data)
file.close()
except Exception as ex:
sleep(2)
gravaLog(ip=self.ip,tipo="Falha",msg=f'Error - {str(ex)}')
return "Falha"
"""
if isJpeg==1:
return "jpeg",data
else:
return "bmp",data
except Exception as ex:
gravaLog(ip=self.ip,tipo="Falha Generica",msg=f'Error - {str(ex)}')
#print(f'erro {str(ex)}')
self.onLine = False
self.trans.close()
sleep(2)
return resposta
class DriveData():
HEADERSIZE = 100
ip = "192.168.0.1"
port = 32100
onLine = False
def __init__(self, ip, port):
gravaLog(ip=self.ip,msg=f'iniciou drive',file="log_data.txt")
self.ip=ip
self.port = port
self.trans = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
self.trans.connect((self.ip,self.port))
self.onLine = True
except:
self.onLine = False
def read_data(self):
resposta = 'falha'
try:
if not self.onLine:
#print(f'tentando Conectar...\n')
gravaLog(ip=self.ip,msg=f'tentando Conectar...',file="log_data.txt")
sleep(2)
try:
self.trans = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.trans.connect((self.ip,self.PORT))
self.onLine = True
gravaLog(ip=self.ip,msg=f'Conexão restabelecida...',file="log_data.txt")
except:
self.onLine = False
return resposta
resposta = self.trans.recv(self.HEADERSIZE).decode("utf-8")
resposta = str(resposta).split(',')
return resposta
except Exception as ex:
self.onLine = False
gravaLog(ip=self.ip,tipo="Falha Generica",msg=f'erro {str(ex)}',file="log_data.txt")
sleep(2)
return resposta
if __name__ == "__main__":
test = DriveImg("192.168.1.125", 32200)
x = 0
while x < 100:
x=x+1
imgtype, img = test.read_img()

View File

@ -7,6 +7,12 @@ core:
arm: arm:
ip: 192.168.1.145 ip: 192.168.1.145
#cable_map:
cameras:
banner:
ip: 192.168.1.125
port: 32200
led: led:
fps: 90 fps: 90
timeout: 0 timeout: 0

View File

@ -170,7 +170,7 @@ def init():
data = list() data = list()
for x in range(len(leds)): for x in range(len(leds)):
if leds_size[x] == 3: if leds_size[x] == 3:
data.append((50,50,255)) data.append((20,20,127))
elif leds_size[x] == 4: elif leds_size[x] == 4:
data.append((50,50,255,0)) data.append((50,50,255,0))
else: else:
@ -290,7 +290,7 @@ def close():
time.sleep(0.5) time.sleep(0.5)
sender.stop() sender.stop()
def mapimage(image, fps=30): def mapimage(image, fps=60):
global start global start
while uptime() - start < 1/fps: while uptime() - start < 1/fps:
time.sleep(0.00001) time.sleep(0.00001)

45
process_video.py Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/env python3
import cv2
import banner_ivu_export
import numpy as np
from util import fprint
class qr_reader():
camera = None
def __init__(self, ip, port):
self.camera = banner_ivu_export.DriveImg(ip, port)
def read_qr(self, tries=1):
print("Trying " + str(tries) + " frames.")
for x in range(tries):
try:
imgtype, img = self.camera.read_img()
#fprint(imgtype)
image_array = np.frombuffer(img, np.uint8)
img = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
#cv2.imshow('Image', img)
#cv2.waitKey(1)
detect = cv2.QRCodeDetector()
value, points, straight_qrcode = detect.detectAndDecode(img)
return value
except:
continue
return False
class video_streamer():
camera = None
def __init__(self, ip, port):
self.camera = banner_ivu_export.DriveImg(ip, port)
def get_frame(self):
try:
return self.camera.read_img()
except:
return False
if __name__ == "__main__":
test = qr_reader("192.168.1.125", 32200)
while True:
fprint(test.read_qr(5))

26
run.py
View File

@ -21,6 +21,7 @@ import led_control
import server import server
import asyncio import asyncio
import json import json
import process_video
@ -34,6 +35,7 @@ vm_ready = False
killme = None killme = None
#pool = None #pool = None
serverproc = None serverproc = None
camera = None
to_server_queue = Queue() to_server_queue = Queue()
from_server_queue = Queue() from_server_queue = Queue()
@ -78,7 +80,7 @@ def start_server_socket():
app.run(host='0.0.0.0', port=5000)""" app.run(host='0.0.0.0', port=5000)"""
global to_server_queue global to_server_queue
global from_server_queue global from_server_queue
fprint("Starting WebSocket server...")
websocket_process = server.start_websocket_server(to_server_queue, from_server_queue) websocket_process = server.start_websocket_server(to_server_queue, from_server_queue)
# Example # Example
@ -86,9 +88,10 @@ def start_server_socket():
while True: while True:
#print("HI")
if not from_server_queue.empty(): if not from_server_queue.empty():
message = from_server_queue.get() client_id, message = from_server_queue.get()
fprint(f"Message from client: {message}") fprint(f"Message from client {client_id}: {message}")
# Message handler # Message handler
try: try:
@ -141,6 +144,13 @@ def start_server_socket():
fprint("") fprint("")
elif call == "request": elif call == "request":
fprint("") fprint("")
if data["enabled"] == True:
# todo : send this to client
p = Process(target=run_cmd, args=("./keyboard-up.ps1",))
p.start()
elif data["enabled"] == False:
p = Process(target=run_cmd, args=("./keyboard-down.ps1",))
p.start()
case "machine_settings": case "machine_settings":
fprint("machine_settings message") fprint("machine_settings message")
@ -202,10 +212,10 @@ def setup_server(pool):
global led_ready global led_ready
global arm_ready global arm_ready
global serverproc global serverproc
global camera
pool.apply_async(ur5_control.init, (config["arm"]["ip"],), callback=arm_start_callback) pool.apply_async(ur5_control.init, (config["arm"]["ip"],), callback=arm_start_callback)
pool.apply_async(led_control.init, callback=led_start_callback) pool.apply_async(led_control.init, callback=led_start_callback)
#pool.apply_async(camera_control.init, callback=camera_start_callback)
#pool.apply_async(sensor_control.init, callback=sensor_start_callback) #pool.apply_async(sensor_control.init, callback=sensor_start_callback)
serverproc = Process(target=start_server_socket) serverproc = Process(target=start_server_socket)
serverproc.start() serverproc.start()
@ -225,10 +235,11 @@ def setup_server(pool):
if camera_ready is False: if camera_ready is False:
fprint("waiting for " + "Camera initilization" + " to complete...", sendqueue=to_server_queue) fprint("waiting for " + "Camera initilization" + " to complete...", sendqueue=to_server_queue)
while camera_ready is False: camera = process_video.qr_reader(config["cameras"]["banner"]["ip"], config["cameras"]["banner"]["port"])
sleep(0.1)
fprint("Camera initialized.", sendqueue=to_server_queue) fprint("Camera initialized.", sendqueue=to_server_queue)
arm_ready = True
if arm_ready is False: if arm_ready is False:
fprint("waiting for " + "UR5 initilization" + " to complete...", sendqueue=to_server_queue) fprint("waiting for " + "UR5 initilization" + " to complete...", sendqueue=to_server_queue)
while arm_ready is False: while arm_ready is False:
@ -251,6 +262,9 @@ def mainloop_server(pool):
killall() killall()
counter = counter + 1 counter = counter + 1
fprint("Looking for QR code...")
print(camera.read_qr(30))
def run_loading_app(): def run_loading_app():
app = Flask(__name__) app = Flask(__name__)

View File

@ -50,32 +50,37 @@ def run_server():
import asyncio import asyncio
import websockets import websockets
from multiprocessing import Process, Queue from multiprocessing import Process, Queue
from util import fprint
import uuid
connected_clients = set() connected_clients = {}
async def handler(websocket, path, to_server_queue, from_server_queue): async def handler(websocket, path, to_server_queue, from_server_queue):
# Register websocket connection # Register websocket connection
connected_clients.add(websocket) client_id = str(uuid.uuid4())
connected_clients[client_id] = websocket
try: try:
# Handle incoming messages # Handle incoming messages
async for message in websocket: async for message in websocket:
#print(f"Received message: {message}") #print(f"Received message: {message}")
from_server_queue.put(message) # Put received message into from_server_queue print(client_id)
from_server_queue.put((client_id, message))
finally: finally:
# Unregister websocket connection # Unregister websocket connection
connected_clients.remove(websocket) if client_id in connected_clients:
del connected_clients[client_id]
print(f"Client {client_id} connection closed")
async def send_messages(to_server_queue): async def send_messages(to_server_queue):
while True: while True:
if not to_server_queue.empty(): if not to_server_queue.empty():
message = to_server_queue.get() client_id, message = to_server_queue.get()
if connected_clients: # Check if there are any connected clients if client_id in connected_clients: # Send message to specific client
#await asyncio.wait([client.send(message) for client in connected_clients]) await connected_clients[client_id].send(message)
#await [client.send(message) for client in connected_clients] elif len(connected_clients) > 0: # Broadcast message to all clients
for client in connected_clients: for client in connected_clients.values():
await client.send(message) await client.send(message)
await asyncio.sleep(0.001)
await asyncio.sleep(0.1) # Prevent the loop from running too fast
def websocket_server(to_server_queue, from_server_queue): def websocket_server(to_server_queue, from_server_queue):
start_server = websockets.serve(lambda ws, path: handler(ws, path, to_server_queue, from_server_queue), "localhost", 9000) start_server = websockets.serve(lambda ws, path: handler(ws, path, to_server_queue, from_server_queue), "localhost", 9000)

View File

@ -62,7 +62,7 @@ def fprint(msg, settings = None, sendqueue = None):
print(logMsg) print(logMsg)
if (sendqueue is not None): if (sendqueue is not None):
sendqueue.put("{ \"type\": \"log\", \"call\":\"send\", \"data\": \"" + logMsg + "\" }") sendqueue.put(("*", "{ \"type\": \"log\", \"call\":\"send\", \"data\": \"" + logMsg + "\" }"))
if (settings is not None): if (settings is not None):
tmpList = settings["logMsg"] tmpList = settings["logMsg"]
tmpList.append(logMsg) tmpList.append(logMsg)
@ -111,9 +111,9 @@ def run_cmd(cmd):
return completed return completed
def setup_child(sets=None): def setup_child(sets=None):
#if not getattr(sys, "frozen", False): if not getattr(sys, "frozen", False):
# sys.stdout = Logger(filename=find_data_file("output.log")) sys.stdout = Logger(filename=find_data_file("output.log"))
# sys.stderr = Logger(filename=find_data_file("output.log")) sys.stderr = Logger(filename=find_data_file("output.log"))
if sets is not None: if sets is not None:
settings = sets settings = sets