尽管Python多处理队列填充在另一个线程中,但它为空

时间:2018-11-16 04:07:06

标签: multithreading python-2.7 queue multiprocessing

我现在已经尝试解决了多个小时的问题,但是无论我做什么,我都无法正常工作。

我的项目跟踪实时数据,并为其他服务提供终点,以获取最新的测量结果。但是无论我做什么,queue.get()始终不返回任何内容。

这是我的代码:

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')

由于我真的没有其他线索,我该怎么做,所以我们将不胜感激。

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

1 个答案:

答案 0 :(得分:0)

我很随意,因为我没有摄像头,所以剥离了CV2代码,并每隔0.5秒用一对随机数替换队列填充符,然后PEP8-稍微修改一下代码,并且这样有效:

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。

因此,我得出结论,问题可能出在图像处理部分。特别是,我注意到只有封闭半径> 10的轮廓才放入队列。也许该代码路径永远不会执行。您确定所有值都放入队列吗?也许print x, y, radius之前的if radius > 10会有所启发。 (为什么还要使用center而不是xy?)