blanius
Posts: 35
Joined: Mon Jan 21, 2013 6:48 pm

Re: Pure Python camera interface

Thu Oct 17, 2013 4:47 pm

In Python shell you can get list of Modules
with

help('modules')

if picamera is listed then:

in Idle Shell

import picamera

then

picamera

this will show the version Python thinks is loaded

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Thu Oct 17, 2013 5:04 pm

tristan1990 wrote:Heres the error I'm getting:

Install method

Code: Select all

sudo easy_install --user picamera
Ahh, there's the first issue - no need for "sudo" here. You've got two choices:
  • a user-level installation which is "easy_install --user picamera" (no sudo - but bear in mind this will only work for the user you install it as, presumably "pi"), or
  • a system-level installation which is "sudo easy_install picamera" (no --user; this will work for any user, including root).
tristan1990 wrote:

Code: Select all

[email protected] ~ $ sudo python camera.py
Traceback (most recent call last):
  File "camera.py", line 2, in <module>
    import picamera
  File "/home/pi/picamera.py", line 4, in <module>
    camera = picamera.PiCamera()
AttributeError: 'module' object has no attribute 'PiCamera'
I think I've tried all the solutions mentioned in this thread :/
If you go for the user installation above, just run "python camera.py" (no sudo). If you go for the system installation you should be able to use "sudo python camera.py" if you want, but "python camera.py" should work equally well (being a system installation it should work for all users).

Hope this helps - and if you've still got issues do feel free to mail me directly (my e-mail address is pretty easy to find on github - just follow the source-code link for picamera, and click on "waveform80", my username)


Cheers,

Dave.

User avatar
leol
Posts: 147
Joined: Fri Jan 13, 2012 4:27 pm
Location: Haute-Vienne, France

Re: Pure Python camera interface

Fri Oct 18, 2013 1:51 pm

Hi,

Just tried picamera. It looks terrific. Thanks very much.
Had a problem with continuous, but found the work around on github / issues

Leo

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Mon Oct 21, 2013 2:23 am

A bit later than planned, but picamera 0.5 has just been released. The highlight this time is the video-port based rapid image capture which (at reasonable resolutions) allows images to be captured at up to 30fps. Whether you can process them fast enough (or write them to disk) is an exercise left to the reader!

Anyway, the changelog in the docs has all the gory details, so I'll just repeat the usual links here for convenience:
Have fun and do feel free to let me know of any issues, requests, etc. etc.


Cheers,

Dave.

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Wed Oct 30, 2013 1:46 am

It's that time again! Picamera 0.6 has just been released; major highlights this time include:
  • Raw image capture (in YUV and RGB format)
  • Manual shutter speed manipulation (requires latest firmware) via the shutter_speed property
  • More extensive documentation; the new "Recipes" chapter includes lots of good stuff to play with!
Have fun and do let me know of any bugs - I'm considering this a release candidate for 1.0! Documentation should be up reasonably shortly (it's already available if you click on Latest under the docs link) - but I'm having some issues with RTD at the mo...


Cheers,

Dave.

MartynWard
Posts: 1
Joined: Wed Oct 30, 2013 5:59 pm

Re: Pure Python camera interface

Wed Oct 30, 2013 6:12 pm

Dave,

I`m sorry if you've answered this one before, I`ve looked through the other posts but can`t find anything.
Yesterday I installed picamera 0.5 as instructed, I can get it to work fine in python 2.7.3, however when I try it
(>>> import picamera) under python 3.2.3, I get an error <ImportError: no module called picamera>.
Today I`ve removed picamera 0.5 and installed the new 0.6 version, same problem.
I`m new to this python malarkey, so I`m probably doing something wrong, any clues?

Martyn

payal
Posts: 35
Joined: Tue Oct 29, 2013 10:53 am

Re: Pure Python camera interface

Wed Oct 30, 2013 7:22 pm

waveform80 wrote:EDIT:
Just to note that this first post is now rather out of date - the library's pretty stable, has had a few releases (though we haven't hit 1.0 yet), has test cases and decent docs and so forth. Check out the links below if you want to have a play:
Original post follows...



----------------------------------------

I've been developing an application for the RPi's camera in Python and the lack of a pure Python interface was beginning to grate a bit, so I've sat down and written one. Well ... started one anyway. It's still thoroughly unfinished but it's vaguely functional and could be useful for some things (basically preview and image capture works, along with some configuration bits, but video capture still needs finishing, along with a load of other bits).

Also, when I say pure Python I mean it doesn't rely on calling raspistill or raspivid, but it does rely on libmmal; specifically I sat down and wrote a header translation of libmmal for Python using ctypes so while the code is technically pure Python, internally it looks like a horrendous mish-mash of C and Python! Still, that doesn't detract from its usability (I'm trying to give it a relatively "pythonic" interface). Using the package (which is rather unimaginatively called picamera) you can do something like the following to display a preview for 10 seconds:

Code: Select all

import time
import picamera

camera = picamera.PiCamera()
try:
    camera.start_preview()
    time.sleep(10)
    camera.stop_preview()
finally:
    camera.close()
Or more simply, using the context manager protocol:

Code: Select all

import time
import picamera

with picamera.PiCamera() as camera:
    camera.start_preview()
    time.sleep(10)
    camera.stop_preview()
You can ramp up the brightness while the preview's running with something like this:

Code: Select all

import time
import picamera

with picamera.PiCamera() as camera:
    camera.start_preview()
    for i in range(100):
        camera.brightness = i
        time.sleep(0.2)
    camera.stop_preview()
Or start the preview and then take an image after it's run a few seconds like this (note that the output doesn't have to be a filename - it can be a file-like object too!) :

Code: Select all

import time
import picamera

with picamera.PiCamera() as camera:
    camera.start_preview()
    time.sleep(2)
    camera.capture('foo.jpg')
    camera.stop_preview()
Anyway, here's some links for code, documentation, and the package. As mentioned it's still very incomplete, but I figured I'd try the "release early, release often" approach for once and see if anyone wants to pitch in! The package works with Python 2.7+ or 3.2+ and I would very much welcome patches, bug reports, pull requests, general suggestions of what you think the API should look like, or other comments.

hello...

i have used picamera library
camera = PiCamera.picamera()

i used this command but it not executed so i kill the process. After this my camera not working means not capturing images only red led is glowing..
what i do?
have you any solution? Ps tell me. :(

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Wed Oct 30, 2013 7:31 pm

payal wrote: hello...

i have used picamera library
camera = PiCamera.picamera()

i used this command but it not executed
What exactly do you mean "not executed"? Did an error occur? Did anything get printed to the terminal?
payal wrote: ...so i kill the process. After this my camera not working means not capturing images only red led is glowing..
what i do?
have you any solution? Ps tell me. :(
A reboot should restore the camera to normal (you may find that the Pi won't reboot normally when the camera is in this state, in which case you'll just have to pull the power cable and plug it back in again). Generally speaking, don't kill the python process as that'll leave the camera (and hence the Pi) in this state - just quitting the process normally with Ctrl+D should shut down the camera properly, but to be certain you should use camera.close() or use the "with picamera..." variation to guarantee the camera is closed correctly before the python process exits (have a read of the Quickstart chapter in the documentation - it briefly runs through these things).


Cheers,

Dave.

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Thu Oct 31, 2013 9:29 am

MartynWard wrote:Dave,

I`m sorry if you've answered this one before, I`ve looked through the other posts but can`t find anything.
Yesterday I installed picamera 0.5 as instructed, I can get it to work fine in python 2.7.3, however when I try it
(>>> import picamera) under python 3.2.3, I get an error <ImportError: no module called picamera>.
Hi Martyn,

I think you're the first python 3 user we've had on here - good to see someone trying it out! The reason you're having issues is yet another deficiency in my installation instructions (writing them and revising them from user comments has been a real eye opener of just how much detail is required, and the sheer breadth of user configurations that need supporting!)

In this case, the issue is that python 2 and 3 have different library paths (necessarily as they're deliberately incompatible), and hence there are typically two versions of easy_install available. While easy_install will perform installations for python 2, easy_install3 will perform installations for python 3 (at least, that's how raspbian is setup - it may be different on other distros or in (the distant) future when python 3 eventually becomes the standard there'll just be the one without any suffix). I'll add this to the instructions for the next version :)

Cheers,

Dave

randallsussex
Posts: 13
Joined: Thu Oct 10, 2013 5:13 pm

Re: Pure Python camera interface

Fri Nov 01, 2013 11:21 pm

Hi,
The Picamera python api looks great. Just what I would like to use.

However, I'm getting an error when trying to run.

Traceback (most recent call last):
File "testUseCamera.py", line 31, in <module>
useCamera.takeSinglePicture("test", 1)
File "./actions/useCamera.py", line 80, in takeSinglePicture
camera = picamera.PiCamera()
File "/usr/local/lib/python2.7/dist-packages/picamera-0.6-py2.7.egg/picamera/camera.py", line 206, in __init__
GPIO.setup(5, GPIO.OUT, initial=GPIO.LOW)
RPIO.Exceptions.InvalidChannelException: The channel sent is invalid on a Raspberry Pi (not a valid gpio)

I'm clueless on how to fix this.

Randall

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Fri Nov 01, 2013 11:33 pm

randallsussex wrote:Hi,
The Picamera python api looks great. Just what I would like to use.

However, I'm getting an error when trying to run.

Traceback (most recent call last):
File "testUseCamera.py", line 31, in <module>
useCamera.takeSinglePicture("test", 1)
File "./actions/useCamera.py", line 80, in takeSinglePicture
camera = picamera.PiCamera()
File "/usr/local/lib/python2.7/dist-packages/picamera-0.6-py2.7.egg/picamera/camera.py", line 206, in __init__
GPIO.setup(5, GPIO.OUT, initial=GPIO.LOW)
RPIO.Exceptions.InvalidChannelException: The channel sent is invalid on a Raspberry Pi (not a valid gpio)

I'm clueless on how to fix this.

Randall
Interesting! I'd assumed (on the basis that the RPIO documentation claims that RPIO is drop-in compatible with the RPi.GPIO package) that I could use the same code for both, and given the difficulty of building a test-suite for both libraries I'd simply mocked-up the test suite for that method. Apparently there's some difference which is incompatible; my apologies, I should've tested this properly with both libraries before releasing.

I'm afraid the only fix I can recommend off the top of my head is to uninstall RPIO and install RPi.GPIO instead, but if you're relying on RPIO-specific functionality that's obviously not an option. I've got some time tomorrow morning so I'll try out the RPIO library properly and see if I can't come up with a proper fix for this.


Cheers,

Dave.

User avatar
jbeale
Posts: 3438
Joined: Tue Nov 22, 2011 11:51 pm
Contact: Website

Re: Pure Python camera interface

Sat Nov 02, 2013 12:02 am

randallsussex wrote: GPIO.setup(5, GPIO.OUT, initial=GPIO.LOW)
RPIO.Exceptions.InvalidChannelException: The channel sent is invalid on a Raspberry Pi (not a valid gpio)
I think RPIO requires your python program to be run as root (?) whereas your program seems to be intended for non-root (?)
Anyway I installed PiCamera as root, and I got the same error shown above.

What GPIO numbering scheme are you using? I am using RPIO in a different Python program. I don't see that there is any GPIO 5 available.

http://elinux.org/RPi_Low-level_periphe ... re_hacking
The complete list of chipset GPIO pins which are available on the GPIO connector is:
0, 1, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25
(on the Revision2.0 RaspberryPis, this list changes to: 2, 3, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 22, 23, 24, 25, 27, with 28, 29, 30, 31 additionally available on the P5 header)
If you are using the WiringPi pin numbering, then GPIO 5 is the same as RPIO 24.
See also: https://projects.drogon.net/raspberry-pi/wiringpi/pins/

Anyway, since I have the RPIO library installed, I did a crude patch fix by manual edit of /usr/local/lib/python2.7/dist-packages/picamera-0.6-py2.7.egg/picamera/camera.py to change one line, to use 24 instead of 5 (not sure how to make it automatic based on the GPIO/RPIO library cases):

Code: Select all

                GPIO.setup(24, GPIO.OUT, initial=GPIO.LOW)
and then confirmed that your test program works as expected. Good work, this syntax looks much cleaner/ more friendly than the other camera programs I've seen!

Code: Select all

import time
import picamera

camera = picamera.PiCamera()
try:
    camera.start_preview()
    time.sleep(10)
    camera.stop_preview()
finally:
    camera.close()

User avatar
jbeale
Posts: 3438
Joined: Tue Nov 22, 2011 11:51 pm
Contact: Website

Re: Pure Python camera interface

Sat Nov 02, 2013 12:56 am

I really like the fast still-capture demo, very nice! Here are a few results from the code below it. You can see the SD card buffering affect the fps measurement at higher resolutions when you have a longer burst vs shorter burst. I don't think we've ever had the capability of near-full res frames at 6 fps even in a short burst, so that's great.

Code: Select all

320x240 Captured 120 images at 29.30fps
640x480 Captured 120 images at 13.71fps
1024x768 Captured 40 images at 22.86fps
2000x1500: Captured 8 images at 6.02fps
2000x1500: Captured 40 images at 3.18fps
Here is the still speed testing code:

Code: Select all

import time
import picamera
frames = 8
xres = 2000
yres = 1500

with picamera.PiCamera() as camera:
    camera.resolution = (xres, yres)
    camera.start_preview()
    start = time.time()
    camera.capture_sequence((
        'image%03d.jpg' % i
        for i in range(frames)
        ), use_video_port=True)
    print('%dx%d: Captured %d images at %.2ffps' % (xres, yres, frames, (frames / (time.time() - start))))
    camera.stop_preview()
Update: I installed the library on another Pi which did not have the RPIO library, and it worked straight off (and without needing to be root). Great documentation, by the way! You must have spent a tremendous amount of time on this.

poing
Posts: 1131
Joined: Thu Mar 08, 2012 3:32 pm

Re: Pure Python camera interface

Sat Nov 02, 2013 3:57 pm

@waveform80:
I'm trying to use your code to take images and then use the result image with an OCR program from Windows, as detection speed is key and the Pi is too slow. But it seems that 'text.jpg' in my example is not released because I get a 'file in use by another process' error when I try to delete it from Windows.

Code: Select all

import os
import time
import picamera
os.system("sudo chmod 777 /run/shm")
with picamera.PiCamera() as camera:
	camera.resolution = (1000, 400)
	camera.ISO=100
	camera.awb_mode='off'
	camera.contrast=100
	camera.crop=(0.3,0.3,0.5,0.5)
	camera.shutter_speed=100000
	camera.vflip=1
	camera.hflip=1

	camera.start_preview()
	try:
		for i, filename in enumerate(camera.capture_continuous('/run/shm/text.jpg')):
			print('Captured image %s' % filename)
			while True:
				if os.path.exists("/run/shm/text.jpg"):
					time.sleep(0.1)
				else:
					break
	finally:
		camera.close()
I can copy text.jpg to text0.jpg, but after several minutes the text.jpg capture becomes black. The frequency is about one capture per second.

It does work when I start raspistill directly from python, hoped to improve speed a little with picamera.

User avatar
jbeale
Posts: 3438
Joined: Tue Nov 22, 2011 11:51 pm
Contact: Website

Re: Pure Python camera interface

Sat Nov 02, 2013 8:30 pm

poing wrote:@waveform80:
I'm trying to use your code to take images and then use the result image with an OCR program from Windows, as detection speed is key and the Pi is too slow. But it seems that 'text.jpg' in my example is not released because I get a 'file in use by another process' error when I try to delete it from Windows.
I know when I try to delete a new file in Windows, I'm often blocked because my antivirus program has it open, trying to scan it for viruses.

User avatar
jbeale
Posts: 3438
Joined: Tue Nov 22, 2011 11:51 pm
Contact: Website

Re: Pure Python camera interface

Sun Nov 03, 2013 5:57 am

a few more timing examples, and the code that generated them. This is with the ARM at 900 MHz and writing to the ramdisk ( /run/shm ). Interesting note: only at full-res (2592 x 1944) do I get the full field of view. Even though the other requested resolutions have the same aspect ratio, they are noticably cropping the sensor, I think as if it was in video mode.

Code: Select all

1  2592x1944: Captured 15 images at 5.48fps
2  1296x972: Captured 60 images at 21.77fps
3  648x486: Captured 60 images at 28.50fps
4  324x243: Captured 60 images at 29.14fps
5  162x121: Captured 60 images at 29.19fps
6  81x60: Captured 60 images at 28.70fps
7  40x30: Captured 60 images at 28.68fps

Code: Select all

#!/usr/bin/python

import time
import picamera
import glob, os

frames = 15
xres = 2592
yres = 1944
j = 1

while (xres > 20):
  with picamera.PiCamera() as camera:
    jexp = '/run/shm/*.jpg'  # first, clear out the jpegs in this directory
    plist = glob.glob(jexp)
    for fname in plist:
      os.remove(fname)
    camera.resolution = (xres, yres)
    camera.start_preview()
    time.sleep(2)  # wait for autoexposure to work
    start = time.time()
    camera.capture_sequence(( '/run/shm/image%03d.jpg' % i for i in range(frames) ), use_video_port=True)
    print('%d  %dx%d: Captured %d images at %.2ffps' % (j, xres, yres, frames, (frames / (time.time() - start))))
    camera.stop_preview()
    xres = xres / 2
    yres = yres / 2
    frames = 60
    j = j + 1

selectnone
Posts: 55
Joined: Fri Jun 22, 2012 10:16 pm

Re: Pure Python camera interface

Mon Nov 04, 2013 2:22 am

This is an excellent library, exactly what I needed!
Excellent level of documentation too, lovely.

I've managed to get a reasonable-ish framerate (just over 3fps) using Capture - certainly better than what I was getting by calling raspistill every frame!

I haven't managed to get the Capture_Continuous example working yet though - it appears to lock up the camera or something after one frame
Any idea what I might be doing wrong with that?

I don't want to touch the SD-card, so I'm attempting to everything via streams.

I'm running my Pi remotely via the Adafruit WebIDE, if that matters.

BTW, here's the example I just managed to get working, which just outputs a stream of images to the screen via PyGame (which I'm using in my main project)

Code: Select all

import pygame, Image
import io
import time
import picamera

pygame.init()
screenSize = (pygame.display.Info().current_w, pygame.display.Info().current_h)
pygame.mouse.set_visible(0)
pygame.display.set_mode(screenSize, pygame.FULLSCREEN)
screen = pygame.display.set_mode(screenSize)

clock = pygame.time.Clock()

camera = picamera.PiCamera()
camera.resolution = (360, 240)
camera.rotation = 90
camera.brightness = 75
camera.contrast = 50
camera.exposure_mode = 'night'

try:
	while(True):
		stream = io.BytesIO()
		camera.capture(stream, format='jpeg')
		stream.seek(0)
		
		image = pygame.image.load(stream,'jpeg')
		stream.close()
		
		image = pygame.transform.scale(image.convert(), screenSize)
		
		screen.blit (image, (0,0))
		pygame.display.update()
		
		clock.tick(-1)
		print (clock.get_fps())
finally:
	camera.close()

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Mon Nov 04, 2013 1:37 pm

jbeale wrote: ...
If you are using the WiringPi pin numbering, then GPIO 5 is the same as RPIO 24.
See also: https://projects.drogon.net/raspberry-pi/wiringpi/pins/

Anyway, since I have the RPIO library installed, I did a crude patch fix by manual edit of /usr/local/lib/python2.7/dist-packages/picamera-0.6-py2.7.egg/picamera/camera.py to change one line, to use 24 instead of 5 (not sure how to make it automatic based on the GPIO/RPIO library cases):
...
I've now had some time to dig into the guts of RPi.GPIO and RPIO. Unfortunately the fix suggested here, while permitting the script to run, doesn't actually permit control of the camera LED. Specifically, we need to address BCM GPIO 5 (which is absent from the table linked to on drogon.net). When RPi.GPIO is in BCM mode, it doesn't check that the GPIO being addressed is valid (beyond ensuring it's within a particular range). By contrast RPIO checks the GPIO being addressed is known regardless of what mode it's in (and since it doesn't have BCM GPIO 5 in its "known" array, it rejects attempts to write to it). Basically this means the led property can't support RPIO at this time; I'm preparing a pull request to send upstream to RPIO but for picamera 0.7 I'll be disabling RPIO support for the led property (this doesn't mean you need to switch to RPi.GPIO for your scripts - just that if you've only got RPIO installed and not RPi.GPIO, you won't be able to use the led property in picamera).


Cheers,

Dave.

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Mon Nov 04, 2013 1:53 pm

poing wrote:@waveform80:
I'm trying to use your code to take images and then use the result image with an OCR program from Windows, as detection speed is key and the Pi is too slow. But it seems that 'text.jpg' in my example is not released because I get a 'file in use by another process' error when I try to delete it from Windows.

...
Interesting - can I ask how you're accessing the image from Windows?

I'll hazard a guess here that you're using something like Samba to share /run/shm as a Windows-compatible file share. The reason I'm assuming this is that under POSIX file rules it's perfectly acceptable to delete a file that's in use by another process (the file ceases to be "visible" as a filename to other applications but the application(s) which currently have the file open continue to be able to read from it until they close their handles at which point the storage is *really* released).

So, you could try moving the deletion to the UNIX side of things (i.e. on the Pi) where it shouldn't care whether any process has the file open (and won't interfere with other processes opening it), but that raises the ugly issue of checking that the Windows side has actually had a chance to open the file first (network synchronization is about as much fun as multi-threading and locks ...).

Alternately, you could go for a simpler protocol. The Windows file-sharing protocol (SMB) is ... well, it's not very good (he says diplomatically...). Furthermore, for this particular task it's probably massive overkill (involving a load of overhead for authentication and locking that you probably don't care about). I've just pushed some new commits for the "Recipes" documentation that cover streaming JPEGs off the Pi onto a server for processing; they're a bit crude but they should be a lot faster than using SMB (they just use straight TCP sockets and write little more than the JPEG data itself). You can find the first here, and some more complex variants here, under the "latest" version (they'll become part of the 0.7 docs when I release that sometime this week).


Hope this helps!

Dave.

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Mon Nov 04, 2013 3:10 pm

jbeale wrote:a few more timing examples, and the code that generated them. This is with the ARM at 900 MHz and writing to the ramdisk ( /run/shm ). Interesting note: only at full-res (2592 x 1944) do I get the full field of view. Even though the other requested resolutions have the same aspect ratio, they are noticably cropping the sensor, I think as if it was in video mode.
On the subject of the cropped view when using "use_video_port", this is noted, albeit extremely briefly and without any decent visual examples, in the rapid-capture recipe:
When using video-port based capture only the preview area is captured; in some cases this may be desirable (see the discussion under Preview vs Still resolution).
I really ought to expand on this and add some bits to the API docs for it, so consider this a test run to see if I can explain it better! Basically when use_video_port is True, you *are* capturing video (at least as far as the camera is concerned). The only difference is that instead of strapping an H.264 encoder to the video port, we strap a JPEG encoder onto it instead. The upshot is that instead of receiving a stream of H.264 frames we receive a stream of JPEG frames (which we then write out to different files/streams as opposed to sticking them all in a single file/stream).

However, this does mean that it winds up with several features missing (no Exif, certain image effects aren't accessible, and I've no idea what it does to things like exposure/awb/etc. - need to experiment!); it also means that the capture area is the same as if you were capturing video (i.e. it's the cropped preview area in the centre rather than the full frame that "proper" still captures use). It probably also explains the slight "grainier" nature of the images captured this way (I assuming no "binning" is going on).
jbeale wrote:

Code: Select all

1  2592x1944: Captured 15 images at 5.48fps
2  1296x972: Captured 60 images at 21.77fps
3  648x486: Captured 60 images at 28.50fps
4  324x243: Captured 60 images at 29.14fps
5  162x121: Captured 60 images at 29.19fps
6  81x60: Captured 60 images at 28.70fps
7  40x30: Captured 60 images at 28.68fps
Interesting results! That pretty much mirrors my experience in that above 800x600 things start hitting bottlenecks (I/O bandwidth in most cases I assume) and the framerate drops below 30fps, at least when using JPEG encoding (H.264 is much better than JPEG; much less bandwidth required for equivalent quality so it'll sustain much higher framerates).


Cheers,

Dave.

User avatar
jbeale
Posts: 3438
Joined: Tue Nov 22, 2011 11:51 pm
Contact: Website

Re: Pure Python camera interface

Mon Nov 04, 2013 5:31 pm

waveform80 wrote:
When using video-port based capture only the preview area is captured; in some cases this may be desirable (see the discussion under Preview vs Still resolution).
I really ought to expand on this and add some bits to the API docs for it, so consider this a test run to see if I can explain it better! Basically when use_video_port is True, you *are* capturing video (at least as far as the camera is concerned). The only difference is that instead of strapping an H.264 encoder to the video port, we strap a JPEG encoder onto it instead. The upshot is that instead of receiving a stream of H.264 frames we receive a stream of JPEG frames (which we then write out to different files/streams as opposed to sticking them all in a single file/stream).
In that case, I am confused about why I am getting the full field of view for the full-resolution 2592x1944 case, even though I am in video mode?

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Tue Nov 05, 2013 12:03 pm

selectnone wrote:This is an excellent library, exactly what I needed!
Excellent level of documentation too, lovely.

I've managed to get a reasonable-ish framerate (just over 3fps) using Capture - certainly better than what I was getting by calling raspistill every frame!

I haven't managed to get the Capture_Continuous example working yet though - it appears to lock up the camera or something after one frame
Any idea what I might be doing wrong with that?
I've had a quick play with your code and I suspect the issue is with pygame's image.load behaviour; it closes whatever stream is provided to it (regardless of whether it opened it or not). Personally I think that's a bug, but it's a bit of a semantic thing and changing it could lead to some subtle breakage so I'm wary about jumping in and opening a bug report just now. Anyway, here's a variant of your script which uses capture_continuous:

Code: Select all

import io
import pygame
import picamera

pygame.init()
screenSize = (pygame.display.Info().current_w, pygame.display.Info().current_h)
pygame.mouse.set_visible(0)
pygame.display.set_mode(screenSize, pygame.FULLSCREEN)
screen = pygame.display.set_mode(screenSize)

clock = pygame.time.Clock()

with picamera.PiCamera() as camera:
    camera.resolution = (320, 240)
    camera.brightness = 75
    camera.contrast = 50
    camera.exposure_mode = 'night'
    stream = io.BytesIO()
    for foo in camera.capture_continuous(stream, format='jpeg'):
        stream.truncate()
        stream.seek(0)
        # Annoyingly, pygame's image.load method closes whatever stream one
        # passes to it (personally I'd regard this as a bug). So instead of
        # passing it stream (which we want to re-use), we pass it a copy
        stream_copy = io.BytesIO(stream.getvalue())
        image = pygame.image.load(stream_copy, 'jpeg')
        image = pygame.transform.scale(image.convert(), screenSize)
        screen.blit(image, (0, 0))
        pygame.display.update()
        clock.tick(-1)
        print (clock.get_fps())
Incidentally something odd seems to happen when it's been running for a minute or so; the captured images slowly fade out to black. This seems to be something to do with the camera firmware (and might even be intentional). The only way I've found of mitigating it at the moment (at least when capture_continuous is used) is to activate the preview (which can be made entirely transparent so it doesn't actually appear), but this does kill the framerate to 1fps:

Code: Select all

import io
import pygame
import picamera

pygame.init()
screenSize = (pygame.display.Info().current_w, pygame.display.Info().current_h)
pygame.mouse.set_visible(0)
pygame.display.set_mode(screenSize, pygame.FULLSCREEN)
screen = pygame.display.set_mode(screenSize)

clock = pygame.time.Clock()

with picamera.PiCamera() as camera:
    camera.resolution = (320, 240)
    camera.preview_alpha = 0
    camera.start_preview()
    stream = io.BytesIO()
    for foo in camera.capture_continuous(stream, format='jpeg'):
        stream.truncate()
        stream.seek(0)
        # Annoyingly, pygame's image.load method closes whatever stream one
        # passes to it (personally I'd regard this as a bug). So instead of
        # passing it stream (which we want to re-use), we pass it a copy
        stream_copy = io.BytesIO(stream.getvalue())
        image = pygame.image.load(stream_copy, 'jpeg')
        image = pygame.transform.scale(image.convert(), screenSize)
        screen.blit(image, (0, 0))
        pygame.display.update()
        clock.tick(-1)
        print (clock.get_fps())
Note I also removed the exposure_mode and brightness bits in the above code - when the preview's running the output is *much* brighter. Again, I suspect there's some firmware related reason for this (I'm not sure the exposure_mode actually does much when the preview isn't running and/or video isn't being recorded).

Cheers,

Dave.

selectnone
Posts: 55
Joined: Fri Jun 22, 2012 10:16 pm

Re: Pure Python camera interface

Tue Nov 05, 2013 12:36 pm

Excellent, I'll give that a go tonight!
waveform80 wrote:I've had a quick play with your code and I suspect the issue is with pygame's image.load behaviour
If I remember right, I wasn't actually able to get the example given in the docs to work, as given - no Pygame bits were included:

Code: Select all

import io
import time
import picamera
with picamera.PiCamera() as camera:
    stream = io.BytesIO()
    for foo in camera.continuous(stream):
        # Truncate the stream to the current position (in case
        # prior iterations output a longer image)
        stream.truncate()
        stream.seek(0)
        if process(stream):
            break
        time.sleep(0.1) # see note below
(I was running this with the undefined 'process' function-call chunk removed)

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Pure Python camera interface

Tue Nov 05, 2013 12:40 pm

selectnone wrote:Excellent, I'll give that a go tonight!
waveform80 wrote:I've had a quick play with your code and I suspect the issue is with pygame's image.load behaviour
If I remember right, I wasn't actually able to get the example given in the docs to work, as given - no Pygame bits were included:

Code: Select all

import io
import time
import picamera
with picamera.PiCamera() as camera:
    stream = io.BytesIO()
    for foo in camera.continuous(stream):
        # Truncate the stream to the current position (in case
        # prior iterations output a longer image)
        stream.truncate()
        stream.seek(0)
        if process(stream):
            break
        time.sleep(0.1) # see note below
(I was running this with the undefined 'process' function-call chunk removed)
Ooops - definite bug in there - it's lacking a format specification for continuous, and for that matter I deprecated continuous in favour of capture_continuous (after capture_sequence was introduced). Right ... time for some fixes!

Cheers,

Dave.

selectnone
Posts: 55
Joined: Fri Jun 22, 2012 10:16 pm

Re: Pure Python camera interface

Tue Nov 05, 2013 12:44 pm

Here's a bug I noticed - if I set the camera's ISO setting to >800, it throws an error stating that the range is 0 to 1600.

The docs suggest it might not actually do anything, but the error ought to at least be consistent ;)

Return to “Camera board”