Python 多处理队列是空的,尽管它填充在不同的线程中 [英] Python multiprocessing queue is empty although it is filled in a different thread

查看:48
本文介绍了Python 多处理队列是空的,尽管它填充在不同的线程中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在已经尝试解决这个问题好几个小时了,但无论我做什么,我都无法解决问题.

I have now tried to resolve this issue for multiple hours but no matter what I do, I never get the thing to work.

我的项目跟踪实时数据并为其他服务提供端点以获取最新的(ish)测量值.但无论我做什么, queue.get() 总是什么都不返回.

My project tracks live data and provides an endpoint for other services to get the latest(ish) measurement. But no matter what I do, the queue.get() always returns nothing.

这是我的代码:

from collections import deque
import numpy as np
import argparse
import imutils
import cv2
from flask import Flask
from multiprocessing import Queue
import threading
import Queue as Q

app = Flask(__name__)


class ImageParser(object):
    def dosmth(self, q):
        ap = argparse.ArgumentParser()
        ap.add_argument("-v", "--video", help="path to the (optional) video file")
        ap.add_argument("-b", "--buffer", type=int, default=14, help="max buffer size")
        args = vars(ap.parse_args())

        greenLower = [(86, 61, 128)]
        greenUpper = [(148, 183, 196)]
        pts1 = deque(maxlen=args["buffer"])
        pts2 = deque(maxlen=args["buffer"])

        if not args.get("video", False):
            camera = cv2.VideoCapture(0)

        else:
            camera = cv2.VideoCapture(args["video"])

        while True:
            (grabbed, frame) = camera.read()

            if args.get("video") and not grabbed:
                break

            frame = imutils.resize(frame, width=1200)
            hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

            for j in range(len(greenLower)):
                upper = greenUpper[j]
                lower = greenLower[j]

                mask = cv2.inRange(hsv, lower, upper)
                mask = cv2.erode(mask, None, iterations=2)
                mask = cv2.dilate(mask, None, iterations=2)

                cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
                                        cv2.CHAIN_APPROX_SIMPLE)[-2]
                for i in range(len(cnts)):
                    center = None

                    if len(cnts) > 0:
                        c = max(cnts, key=cv2.contourArea)

                        ((x, y), radius) = cv2.minEnclosingCircle(c)
                        M = cv2.moments(c)
                        center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))

                        if radius > 10:
                            q.put(center)
                            cv2.circle(frame, (int(x), int(y)), int(radius),
                                       (0, 255, 255), 2)
                            cv2.circle(frame, center, 5, (0, 0, 255), -1)

                    if j == 0:
                        pts1.appendleft(center)
                        for i in xrange(1, len(pts1)):
                            if pts1[i - 1] is None or pts1[i] is None:
                                continue

                            thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)
                            cv2.line(frame, pts1[i - 1], pts1[i], (255,0,0), thickness)

                    if j == 1:
                        pts2.appendleft(center)
                        for i in xrange(1, len(pts2)):
                            if pts2[i - 1] is None or pts2[i] is None:
                               continue

                            thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)
                            cv2.line(frame, pts2[i - 1], pts2[i], (51, 153, 255), thickness)

            cv2.imshow("Frame", frame)
            key = cv2.waitKey(1) & 0xFF

            if key == ord("q"):
                break

        camera.release()
        cv2.destroyAllWindows()


imgPar = ImageParser()
q = Queue()
scp = threading.Thread(target=imgPar.dosmth, args=(q,))
scp.start()

def getVal():
    try:
        (x,y) = q.get_nowait()
    except Q.Empty:
        return -1 , -1
    return (x,y)

@app.route('/', methods=['GET'])
def doMain():
    x,y = getVal()
    print x,y
    return '{},{}'.format(x,y)

app.run(debug=True, host='10.21.8.52')

由于我真的没有任何其他线索,我应该做什么,任何帮助将不胜感激.

As I really do not have any other clue, what I should do, any help would be appreciated.

如果有任何帮助,一切都在 anaconda 环境中在 python 2.7.15 上运行.
因为我真的没有

Everything is running on python 2.7.15 in an anaconda environment if that helps in any way.
As I really do not have

推荐答案

由于我没有相机,我冒昧地剥离了 CV2 代码,并每隔 0.5 用一对随机数替换队列填充器秒,然后PEP8 - 稍微编写代码,这样它作品:

I took the liberty of stripping out the CV2 code as I don't have a camera, and replace the queue filler with a pair of random numbers every .5 seconds, and PEP8-ing the code a bit, and this way it works:

import random
import time

from flask import Flask
import threading
from multiprocessing import Queue
from Queue import Empty as QueueEmpty

app = Flask(__name__)

class ImageParser(object):
    def __init__(self, queue):
        self.queue = queue
        self.source = random.random
        self.pause = 0.5

    def run(self):
        while True:
            value = (self.source(), self.source())
            self.queue.put(value)
            time.sleep(self.pause)

queue = Queue()
image_parser = ImageParser(queue)
image_thread = threading.Thread(target=image_parser.run)

@app.route('/', methods=['GET'])
def do_main():
    try:
        value = queue.get_nowait()
    except QueueEmpty:
        value = None
    print(value)
    return str(value)

if __name__ == '__main__':
    image_thread.start()
    app.run(debug=True, host='127.0.0.1')

http://127.0.0.1:5000/ 下,我现在得到成对的随机数,当我重新加载太快时偶尔会得到 None.

Under http://127.0.0.1:5000/ I now get pairs of random numbers, and the occasional None when I reload too fast.

因此,我得出结论,问题可能出在图像处理部分.具体来说,我注意到只有封闭半径 > 10 的轮廓才能进入队列.也许那条代码路径永远不会被执行.您确定将任何值放入队列中吗?可能在 if radius > 之前 print x, y, radius10 会有所启发.(为什么用 center 而不是 xy ?)

I therefore conclude that the problem probably lies with the image processing part. Specifically I noticed that only contours with an enclosing radius > 10 get put into the queue. Maybe that path of code just never gets executed. Are you quite sure that any values get put into the queue at all? Maybe a print x, y, radius before the if radius > 10 will shed some light. (And why put center instead of x and y?)

这篇关于Python 多处理队列是空的,尽管它填充在不同的线程中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆