I'm working on a school project where I have to make a robot move parallel to a wall and stop when it sees a big red square. For this I have the picamera module and the openCV library. I have working code but the camera takes too long to take a picture (3-4 seconds every time). The analyzing is done in a few milliseconds but I need to take pictures faster. The working code is this:
@staticmethod def detect_red(): # saving the picture to an in-program stream rather than a file stream = io.BytesIO() # to speed things up, lower the resolution of the camera camera_width = 320 camera_height = 240 #scale_down = 6 red = False with picamera.PiCamera() as camera: camera.resolution = (camera_width, camera_height) # capture into stream camera.capture(stream, format='jpeg') # convert image into numpy array data = np.fromstring(stream.getvalue(), dtype=np.uint8) # turn the array into a cv2 image img = cv2.imdecode(data, 1) # Resizing the image, blur the image and convert it to HSV values for better recognition # img = cv2.resize(img, (len(img[0]) / scale_down, len(img) / scale_down)) # img = cv2.GaussianBlur(img, (5,5), 0) img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #Defining the red color range and calculating if these values lie in the range red_lower = np.array([0, 150, 0], np.uint8) red_upper = np.array([5, 255, 255], np.uint8) red_binary = cv2.inRange(img, red_lower, red_upper) # Dilates the red space, making it larger dilation = np.ones((15, 15), "uint8") red_binary = cv2.dilate(red_binary, dilation) contours, _ = cv2.findContours(red_binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) if not contours == []: if not red: red = True print "Red surface detected!" else: print "No red surface detected." return red Now I've been trying to get a faster method using capture_continuous and I based my code on: take images in a short time using the Raspberry Pi camera module
def outputs(self): stream = io.BytesIO() for i in range(40): red = False data = np.fromstring(stream.getvalue(), dtype=np.uint8) img = cv2.imdecode(data, 1) print "a" img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) red_lower = np.array([0, 150, 0], np.uint8) red_upper = np.array([5, 255, 255], np.uint8) red_binary = cv2.inRange(img, red_lower, red_upper) dilation = np.ones((15, 15), "uint8") red_binary = cv2.dilate(red_binary, dilation) contours, _ = cv2.findContours(red_binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) if not contours == []: if not red: red = True print "Red surface detected!" else: print "No red surface detected." stream.seek(0) stream.truncate() def video_red(self): with picamera.PiCamera() as camera: camera.resolution = (320,240) camera.framerate = 5 camera.start_preview() time.sleep(2) camera.capture_continuous(self.outputs(), 'jpeg', use_video_port=True) This is the new code but I keep getting openCV Error: Assertion failed (scn == 3 || scn == 4) in the cv2.cvtColor method. How can I fix this? I'm also not sure if what I'm doing with the stream is correct. Any help would be appreciated.