Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 14126

Python-SocketIO , Yoloface: Is there a possibility that a function call is blocking my main thread?

$
0
0

I am working on a Flask Server with SocketIO. I emplemented an event handler and this is working fine (i implemented the client in a Adroid Studio Project). I can emit and receive Messages without any Problem.

I also want to use Yoloface for Facedetection and i am calling the function with scan_face(). I encountered a problem that scan_face() will only return the correct value for the first time i receive a scan_request from the Client. Everytime there is another scan_request from the client the function is not even called and if i try to use breakpoints to debug the breakpoints are skipped, scan_face() not called and the server continues to listen to the client

this is my output from the console:

flask run --host='0.0.0.0'----- info -----[i] Source of the camera:  0[i] Path to output directory:  outputs/###########################################################==> Skipping create the outputs/ directory... * Debug mode: offWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on all addresses (0.0.0.0) * Running on http://x.x.x.x:5000 * Running on http://x.x.x.x:5000Press CTRL+C to quitx.x.x.x - - [25/Mar/2024 23:29:04] "GET /socket.io/?EIO=4&transport=polling HTTP/1.1" 200 -Client connected to default namespacex.x.x.x - - [25/Mar/2024 23:29:04] "POST /socket.io/?EIO=4&transport=polling&sid=iiua90AsbvoVBspJAAAA HTTP/1.1" 200 -x.x.x.x - - [25/Mar/2024 23:29:04] "GET /socket.io/?EIO=4&transport=polling&sid=iiua90AsbvoVBspJAAAA HTTP/1.1" 200 -x.x.x.x - - [25/Mar/2024 23:29:04] "GET /socket.io/?EIO=4&transport=polling&sid=iiua90AsbvoVBspJAAAA HTTP/1.1" 200 -x.x.x.x - - [25/Mar/2024 23:29:04] "POST /socket.io/?EIO=4&transport=polling&sid=iiua90AsbvoVBspJAAAA HTTP/1.1" 200 -check1Received scan request: Scanne PersonWarning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.200227254[i] ==> # detected faces: 1############################################################value12gesichtercheck2person sent2check1Received scan request: Scanne Personcheck1Received scan request: Scanne Person

This is where i call the scan_face() function:

@socketio.on('scan_request')    def handle_scan_request(message):        print('check1')        print(f"Received scan request: {message}")        scan_result = scan_face() # here i call the function which works only for the first time        print('check2')        if scan_result == 1:            get_person_by_id()        elif scan_result == 0:            person_not_detected()

This is the whole code of my Eventhandler:

from flask import Flask, jsonifyfrom flask_sqlalchemy import SQLAlchemyfrom flask_migrate import Migratefrom flask_socketio import SocketIO, leave_room, join_room, emitfrom flask import requestfrom sqlalchemy import funcfrom flask_socketio import sendfrom yoloface import scan_facefrom PyQt5.QtCore import QTimer, QEventLoop, QCoreApplication, QThread, pyqtSignaldb = SQLAlchemy()migrate = Migrate()socketio = SocketIO(cors_allowed_origins="*")last_sent_person_id = 1def create_app():    global last_sent_person_id    app = Flask(__name__)    app.config['DEBUG'] = True    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'    db.init_app(app)    migrate.init_app(app, db)    socketio.init_app(app)    from models import Person    @app.route('/', methods=['GET', 'POST'])    def handle_request():        return 'Successful Connection'    @app.route('/api/persons', methods=['GET'])    def get_all_persons():        persons = Person.query.all()        result = []        for person in persons:            result.append({'id': person.id,'first_name': person.first_name,'last_name': person.last_name,'last_seen': person.last_seen,'status': person.status,'notes': person.notes,'pronouns': person.pronouns,'appointment': person.appointment,'notRecognized': person.notRecognized,'notSeenInReminderPeriod': person.notSeenInReminderPeriod,'image': person.image            })        return jsonify(result)    def delete_all_data():        with app.app_context():            db.session.query(Person).delete()            db.session.commit()    @app.route('/delete_data', methods=['GET', 'POST'])    def delete_data():        if request.method == 'POST':            delete_all_data()            return 'All data deleted successfully'        else:            return 'This endpoint accepts POST requests only'    @app.route('/create_dummys', methods=['POST', 'GET'])    def create_dummys():        if request.method == 'POST':            from dummy_data import create_dummy_data            create_dummy_data()            return 'Dummy data created successfully'        elif request.method == 'GET':            return 'This endpoint accepts POST requests only'    @socketio.on('get_person_by_id')    def get_person_by_id():        global last_sent_person_id        person = Person.query.filter_by(id=last_sent_person_id).first()        if person:            print("person sent")            emit('person_data', {'id': person.id,'first_name': person.first_name,'last_name': person.last_name,'last_seen': person.last_seen,'status': person.status,'notes': person.notes,'pronouns': person.pronouns,'appointment': person.appointment,'notRecognized': 'False','notSeenInReminderPeriod': person.notSeenInReminderPeriod,'image': person.image            })        else:            emit('server_message', 'Person with ID 1 not found!', broadcast=True)        last_sent_person_id += 1        print(last_sent_person_id)    @socketio.on('send_empty_person')    def person_not_detected():        emit('person_not_detected', {'id': 0,'first_name': 0,'last_name': 0,'last_seen': 0,'status': 0,'notes': 0,'pronouns': 0,'appointment': 0,'notRecognized': 'False','notSeenInReminderPeriod': 'True','image': 0        })    @socketio.on('connect')    def handle_connect():        print('Client connected to default namespace')        emit('server_message', 'Willkommen beim WebSocket-Server!', broadcast=True)    @socketio.on('disconnect')    def handle_disconnect():        print('Client disconnected from default namespace')    @socketio.on('message')    def handle_message(data):        print('received message: '+ data)        send(data, broadcast=True)    @socketio.on('scan_request')    def handle_scan_request(message):        print('check1')        print(f"Received scan request: {message}")        scan_result = scan_face()        print('check2')        if scan_result == 1:            get_person_by_id()        elif scan_result == 0:            person_not_detected()    from namespace import PersonNamespace    socketio.on_namespace(PersonNamespace('/persons'))    return app

And this is the yoloface.py where de scan_face() function is defined (i changed the function from yoloface.py so that i can call it without the need of arguments)

import argparseimport asyncioimport sysimport osfrom utils import *SRC = 0OUTPUT_DIR = 'outputs/'MODEL_CFG = './cfg/yolov3-face.cfg'MODEL_WEIGHTS = './model-weights/yolov3-wider_16000.weights'###################################################################### print the argumentsprint('----- info -----')print('[i] Source of the camera: ', SRC)print('[i] Path to output directory: ', OUTPUT_DIR)print('###########################################################\n')# check outputs directoryif not os.path.exists(OUTPUT_DIR):    print('==> Creating the {} directory...'.format(OUTPUT_DIR))    os.makedirs(OUTPUT_DIR)else:    print('==> Skipping create the {} directory...'.format(OUTPUT_DIR))net = cv2.dnn.readNetFromDarknet(MODEL_CFG, MODEL_WEIGHTS)net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)def scan_face():    wind_name = 'face detection using YOLOv3'    cv2.namedWindow(wind_name, cv2.WINDOW_NORMAL)    output_file = ''    cap = cv2.VideoCapture(SRC)    value = None    while True:        has_frame, frame = cap.read()        # Create a 4D blob from a frame.        blob = cv2.dnn.blobFromImage(frame, 1 / 255, (IMG_WIDTH, IMG_HEIGHT),                                     [0, 0, 0], 1, crop=False)        # Sets the input to the network        net.setInput(blob)        # Runs the forward pass to get output of the output layers        outs = net.forward(get_outputs_names(net))        # Remove the bounding boxes with low confidence        faces = post_process(frame, outs, CONF_THRESHOLD, NMS_THRESHOLD)        print('[i] ==> # detected faces: {}'.format(len(faces)))        print('#' * 60)        # initialize the set of information we'll displaying on the frame        info = [            ('number of faces detected', '{}'.format(len(faces)))        ]        for (i, (txt, val)) in enumerate(info):            text = '{}: {}'.format(txt, val)            cv2.putText(frame, text, (10, (i * 20) + 20),                        cv2.FONT_HERSHEY_SIMPLEX, 0.7, COLOR_RED, 2)        cv2.imshow(wind_name, frame)        value = len(faces)        print("value" + str(value))        if value == 0:            print('0gesicht')            break        elif value == 0:            print('1gesicht')            break        else:            print('2gesichter')            break    cap.release()    cv2.destroyAllWindows()    if value == 0:        return 0    else:        return 1

I tried a few things including multithreading but none of it works so that i can call scan_face() everytime i receive a scan request from the client.

I am out of ideas how i am able to call scan_face() consistently. Maybe i am missing something.value = len(faces)

I thought that my flask Server is running on my main thread and that the call of the scan_face() function is blocking it but it still didn't work.

Also i thought that scan_face() may not be terminated in the right way so i tried to force the termination of scan_face() with sys.exit() but it still only worked the first time i called the function.


Viewing all articles
Browse latest Browse all 14126

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>