2

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?

16
  • What exactly do you mean by length? It seems to me that you re trying to find the number of unique rows in your array, is that accurate? Commented Aug 13, 2016 at 7:14
  • yes that is correct. Commented Aug 13, 2016 at 7:14
  • I wanted just anything that showed out, but this method appears to be working. If I could get individual pixel that would be brilliant but right now I'm just using what is working. Commented Aug 13, 2016 at 7:15
  • Hmmm. I am unfamiliar with the libary, but if hresh= cv2.inRange(data, lower, upper) is an array with values from data that are within your range, then you should be able to just use hresh.shape, no? I'm still not understanding why they need to be unique. Commented Aug 13, 2016 at 7:18
  • 1
    sorry, np.unique(thresh).size Commented Aug 13, 2016 at 7:29

1 Answer 1

1

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]
Sign up to request clarification or add additional context in comments.

2 Comments

That's it. But curious, why does it work? what does the 255 on it's own mean?
cv2.inRange returns values 255 or 0 at each pixel. 255 indicates values that are in the threshold.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.