Python 多处理队列是空的,尽管它填充在不同的线程中 [英] Python multiprocessing queue is empty although it is filled in a different thread
问题描述
我现在已经尝试解决这个问题好几个小时了,但无论我做什么,我都无法解决问题.
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, radius
10center
而不是 x
和 y
?)
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屋!