3
\$\begingroup\$

I have a Pi with a camera module that I control with Python.

I created a web server with web.py that allows me to make HTTP requests to the PI to retrieve an image. There are two optional parameters to specify the width and height of the image. The code looks like this (imports omitted):

urls = (
    '/capture', 'Capture'
)

# start with default values for resolution
width = 1024
height = 768

if __name__ == "__main__":

    app = web.application(urls, globals())
    app.run()

class Capture:
    def GET(self):
        input = web.input(w="0", h="0")                 # reading user input of resolution values for 

        input.w = int(input.w)                          # to integer
        input.h = int(input.h)

        if input.w == 0:
            input.w = width                             # no width given, use saved one
        else:
            input.w = max(0,min(2592, input.w))         # clamp to range of valid values

        if input.h == 0:
            input.h = height                            # no height given, use saved one
        else:
            input.h = max(0,min(1944, input.h))         # clamp to range of valid values

        camera = picamera.PiCamera()                    # camera
        camera.resolution = (input.w, input.h)
        camera.capture('picture.jpg')                   # capture image to file
        camera.close()

        web.header('Content-Type', 'image/jpg')
        return open('picture.jpg',"rb").read()          # read image from file and respond

I understand that the code handling the width and height is not very elegant and could be shorter.

To get an image, I can enter http://<PI IP address>/capture in a browser. The problem is that it takes quite a while (1311ms): waiting 1264ms and receiving 47ms.

The results are obviously the same on different browsers because this is a server-side issue.

How can I get the image more quickly?

I think saving to an image file first and reopening that to get the return value is redundant (and possibly slow), but I don't know how to make the capture() function return the value directly (so that I could return it to the client directly). I do not necessarily need jpeg format.

\$\endgroup\$
  • \$\begingroup\$ possible hints: raspberrypi.stackexchange.com/a/24259 \$\endgroup\$ – user3802077 May 10 '16 at 14:48
  • 2
    \$\begingroup\$ Besides the hint given by user3802077, I would like to ask the following question: what have you done to determine the bottleneck. Look into profiling the code. Add logging of timestamps at various points to see which sequence takes the longest. For instance, how long does input.w = int(input.w) take? How long does camera.capture('picture.jpeg') take? Finding it out by hand teaches you more than a code review would give you. \$\endgroup\$ – Sjoerd Job Postmus May 10 '16 at 18:06
  • \$\begingroup\$ It take a long time to save the image to the hard drive (which might be an SD card in this case). Try using variables instead, but I am also trying to figure out how. \$\endgroup\$ – Tim Cheng Apr 30 '17 at 2:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.