Reputation: 79
So with my code, I'm analyzing the total number of pixels that are within the threshold of my values. However, it's very slow, and it all comes down to one line of code, basically bottle-necking the entire program. This code is simple, in that it splits the array up into the values so I can count the length, however, it brings the frames per second down from 30 to about 4.
import cv2
import numpy as np
import time
from picamera.array import PiRGBArray
from picamera import PiCamera
import RPi.GPIO as GPIO
from PIL import Image
camera = PiCamera()
camera.resolution = (320,240)
rawCapture= PiRGBArray(camera)
for frame in camera.capture_continuous(rawCapture, format='bgr', use_video_port=True):
data= frame.array
lower=np.array([100, %0, 50], dtype='uint8')
upper= np.array([250, 150, 150], dtype="uint8")
thresh= cv2.inRange(data, lower, upper)
data={tuple(item) for item in thresh} # this is the problem line.
len(data)
rawCapture.truncate(0)
FPS=FPS+1
New_time=time.time()-start
if New_time> 10:
print FPS/10, 'fps'
New_time=0
start=time.time()
FPS=0
I feel like half the problem is that it is a loop (python hates loops), but I don't really know how to alter arrays. What's the 'pythonic' way of achieving this?
Upvotes: 2
Views: 131
Reputation: 78564
I don't want the size of the picture itself, nor how many total pixels. Just the pixels that are within the threshold.
cv2.inRange
already does that, so the set comprehension will not be required:
After calling
cv2.inRange
, a binary mask is returned, where white pixels (255) represent pixels that fall into the upper and lower limit range and black pixels (0) do not.
From the binary mask, the in-range values can be counted with:
thresh = cv2.inRange(data, lower, upper)
within_threshold = (thresh == 255).sum()
To get the pixels themselves, you can index the original data
on the in-range binary mask:
data = data[thresh == 255]
Upvotes: 1