Files
opencv/piCameraPipeline/PiCameraPipeline.py
T
jens 7b083ccd14 - added PiCameraPipeline
- added Lasertrack
- picam_test uses PiCameraPipeline



git-svn-id: http://moon:8086/svn/software/trunk/projects/opencv@324 b431acfa-c32f-4a4a-93f1-934dc6c82436
2016-10-19 14:59:21 +00:00

214 lines
4.9 KiB
Python
Executable File

# import the necessary packages
from __future__ import print_function
from imutils.video import FPS
from picamera import PiCamera
from picamera import array
import imutils
import time
import numpy as np
from threading import Thread
from threading import Lock
from threading import Semaphore
class Fifo(object):
def __init__(self, dim=(4, 320, 240, 3), dtype=np.uint8):
self.size = 0
self.capacity = dim[0]
self.wi = 0
self.ri = 0
self.buffer = np.empty(dim, dtype=dtype)
self.lock = Lock()
self.sema = Semaphore(value=0)
def write(self, data):
shouldNotify = False
self.lock.acquire()
self.buffer[self.wi] = data
self.wi += 1
if self.wi == self.capacity:
self.wi = 0
if self.size < self.capacity:
self.size += 1
shouldNotify = True
self.lock.release()
if shouldNotify:
self.sema.release()
def read(self, timeout=None):
data = None
if self.sema.acquire(blocking=True, timeout=timeout):
self.lock.acquire()
data = self.buffer[self.ri]
self.ri += 1
if self.ri == self.capacity:
self.ri = 0
self.size -= 1
self.lock.release()
return data
class RgbProcess(Fifo):
def __init__(self, resolution=(320, 240, 3), numEntries=2, next=None):
super(RgbProcess, self).__init__((numEntries, ) + resolution)
self.next = next
self.thread = Thread(target=self.run)
self.cancel = False
self.fps = None
self.frames = 0
# called on construction
def onConstruct(self):
pass
# called on first frame
def onFirstFrame(self):
self.thread.start()
if self.next is not None:
self.next.onFirstFrame()
# may be overriden to process in caller context
def onData(self, data):
self.write(data)
# thread main loop
def run(self):
self.fps = FPS().start()
while not self.cancel:
self.process()
self.frames += 1
# abstractmethod
def process(self):
pass
# should be called to exit thread
def stop(self):
self.fps.stop()
print("Processed " + str(self.frames) + " frames")
print("FPS = " + str(self.frames/self.fps.elapsed()))
self.cancel = True
self.thread.join()
if self.next is not None:
self.next.stop()
class RgbProcessorAdapter(object):
def __init__(self, resolution=(320, 240, 3)):
self.resolution = resolution
self.frameSize = resolution[0]*resolution[1]*resolution[2]
self.size = 0
self.frames = 0
self.fps = None
self.processors = []
self.needRgbConversion = True
def processorAdd(self, processor):
self.processors.append(processor)
processor.onConstruct()
def writable(self):
return True
def write(self, data):
if self.size == 0:
for proc in self.processors:
proc.onFirstFrame()
self.fps = FPS().start()
if data is None:
return
self.size += len(data)
self.frames += len(data)/self.frameSize
res = (self.resolution[0], self.resolution[1])
if self.needRgbConversion:
rgbData = array.bytes_to_rgb(data, res)
else:
rgbData = data
for proc in self.processors:
proc.onData(rgbData)
def size(self):
return self.size
def flush(self):
if self.size > 0:
self.fps.stop()
print("Recorded " + str(self.frames) + " frames (" + str(self.size) + " bytes)")
print("FPS = " + str(self.frames/self.fps.elapsed()))
if ("__main__" == __name__):
import cv2
# Unit test with to threaded processors
class MyRgbProcess1(RgbProcess):
def __init__(self, resolution=(320, 240, 3), numEntries=2, next=None):
super(MyRgbProcess1, self).__init__(resolution, numEntries, next)
def process(self):
data = self.read(1.0)
if data is not None:
gray = cv2.cvtColor(data,cv2.COLOR_BGR2GRAY)
gray_blurred = cv2.medianBlur(gray,5)
cv2.imshow('displayThread1', gray_blurred)
cv2.waitKey(1)
if self.next is not None:
self.next.write(cv2.cvtColor(gray_blurred,cv2.COLOR_GRAY2BGR))
class MyRgbProcess2(RgbProcess):
def __init__(self, resolution=(320, 240, 3), numEntries=2, next=None):
super(MyRgbProcess2, self).__init__(resolution, numEntries)
def process(self):
data = self.read(1.0)
if data is not None:
gray = cv2.cvtColor(data,cv2.COLOR_BGR2GRAY)
# Canny edge detection
canny = cv2.Canny(gray, 100, 50)
cv2.imshow('displayThread2', canny)
cv2.waitKey(1)
# initialize the camera and stream
camera = PiCamera()
camera.resolution = (320, 240)
camera.framerate = 60
frameDim = (camera.resolution[0], camera.resolution[1], 3)
myProcessor2 = MyRgbProcess2((240, 320, 3), 4)
myProcessor1 = MyRgbProcess1((240, 320, 3), 4, myProcessor2)
myRgbProcessorAdapter = RgbProcessorAdapter(frameDim)
myRgbProcessorAdapter.processorAdd(myProcessor1)
camera.start_recording(myRgbProcessorAdapter, format="bgr")
dictFifo = Fifo(dim=(8,), dtype=dict)
dictFifo.write({'a':1, 'b':2})
print(dictFifo.read())
# allow the camera to warmup and start the FPS counter
print("[INFO] sampling frames from `picamera` module...")
time.sleep(10.0)
camera.stop_recording()
myProcessor1.stop()
# do a bit of cleanup
cv2.destroyAllWindows()
camera.close()