I read this [post] (Right way to share opencv video frame as Numpy array between multiprocessing processes) and tried to complete the implementation. The camera is taking images just find, the shapes of images, buffers and received image in another process are matching. But the received image shows black and white noise lines. I tried adding locks before the read/write Array to no avail.
Here is the code. Basically I want to put an image into a numpy and then into an Array so another process can read the image:
class VideoWorker(Process):
def __init__(self, shared_Array, shape,width, height, fps):
super(VideoWorker, self).__init__()
# passing width /height as want to write video file later...
self.width = width
self.height = height
self.fps = fps
self.shared_Array = shared_Array
self.shape = shape
def run(self):
name = "VideoWorker"
print ('%s %s' % (name, self.name))
cv2.namedWindow(name,cv2.WINDOW_NORMAL)
cv2.resizeWindow(name,640,480)
while True:
img = np.frombuffer(self.shared_Array,dtype=ctypes.c_uint8)
print("%s : got img shape %s " % (name, str(img.shape)))
cv2.imshow(name, img)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
print("%s: done" %name)
if __name__ == '__main__':
camera = cv2.VideoCapture(0)
camera.set(cv2.CAP_PROP_FRAME_WIDTH,1280)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT,720)
width = camera.get(cv2.CAP_PROP_FRAME_WIDTH)
height = camera.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = camera.get(cv2.CAP_PROP_FPS)
cv2.namedWindow("orig",cv2.WINDOW_NORMAL)
cv2.resizeWindow("orig",640,480)
cv2.namedWindow("loop",cv2.WINDOW_NORMAL)
cv2.resizeWindow("loop",640,480)
grabbed, frame = camera.read()
shape = frame.shape
cv2.imshow("orig",frame)
print("main: shape ",shape, "size ", frame.size, "fps ",fps)
# size is L x W x channels
shared_Array = Array(ctypes.c_uint8, shape[0] * shape[1] *shape[2], lock=False)
worker = VideoWorker(shared_Array, shape, width, height, fps )
worker.start()
print("main: reshape size ",shape[0]*shape[1]*shape[2])
while True:
buf = np.frombuffer(shared_Array,dtype=np.uint8)
print("main: frombuffer shape ",buf.shape)
buf = buf.reshape(shape)
print("main: loop buf reshape ",buf.shape)
grabbed, frame = camera.read()
cv2.imshow("loop",frame)
print ("main: frame shape ",frame.shape)
if not grabbed:
break
buf[:] = frame
if worker.is_alive() == False:
break
if cv2.waitKey(20) & 0xFF == ord('q'):
break
print("Main process done")
worker.join()
camera.release()
cv2.destroyAllWindows()
The output is two good windows, and one black/white stripped window, plus the following (trimmed):
VideoWorker VideoWorker-1 VideoWorker : got img shape (2764800,) VideoWorker: done main: shape (720, 1280, 3) size 2764800 fps 30.0 main: reshape size 2764800 main: frombuffer shape (2764800,) main: loop buf reshape (720, 1280, 3) main: frame shape (720, 1280, 3) main: frombuffer shape (2764800,) main: loop buf reshape (720, 1280, 3) main: frame shape (720, 1280, 3) main: frombuffer shape (2764800,) main: loop buf reshape (720, 1280, 3) main: frame shape (720, 1280, 3) main: frombuffer shape (2764800,) main: loop buf reshape (720, 1280, 3) main: frame shape (720, 1280, 3) Main process done
A bit stuck on sharing frames on Arrays. I have Queues working just fine. First post to stackoverflow. Suggestions?