User avatar
butyi
Posts: 2
Joined: Thu Jan 02, 2014 8:34 pm
Location: Hungary, Budapest
Contact: Website

Re: Pure Python camera interface

Fri Jan 03, 2014 6:53 pm

waveform80 wrote: Wow - that's quite strange. The io module is one of the core Python modules, so it looks like something's gone horribly wrong with your Python installation (how, I'm not sure). Could you try the following, just to confirm: fire up "python" on the command line, import the io module and see what the "open" function is? Here's what I get:

Code: Select all

[email protected] ~ $ python
Python 2.7.3 (default, Jan 13 2013, 11:20:46) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import io
>>> io.open
<built-in function open>
>>> 
If you get something other than <built-in function open> then your python installation is indeed broken - I might suspect a corrupted/broken SD card, given you've reflashed the raspbian image on it (though it's an awfully specific corruption...).
You are right. Here is my result:

Code: Select all

Python 2.7.3 (default, Jan 13 2013, 11:20:46) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import io
>>> io.open
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'open'
>>> 
I concentrated to python package. In my home folder I unintentionally recognized an io.py and io.pyc. I removed the two files and: <built-in function open>.
Now my python script also works. I have already done a "Tabula rasa" before, means dd a virgin image to card, install picamera, but I had copied back my files into home folder, including these two one. :-)

Thanks Dave!
butyi

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

Re: Pure Python camera interface

Fri Jan 03, 2014 9:13 pm

butyi wrote:
waveform80 wrote: Wow - that's quite strange. The io module is one of the core Python modules, so it looks like something's gone horribly wrong with your Python installation (how, I'm not sure). Could you try the following, just to confirm: fire up "python" on the command line, import the io module and see what the "open" function is? Here's what I get:

Code: Select all

[email protected] ~ $ python
Python 2.7.3 (default, Jan 13 2013, 11:20:46) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import io
>>> io.open
<built-in function open>
>>> 
If you get something other than <built-in function open> then your python installation is indeed broken - I might suspect a corrupted/broken SD card, given you've reflashed the raspbian image on it (though it's an awfully specific corruption...).
You are right. Here is my result:

Code: Select all

Python 2.7.3 (default, Jan 13 2013, 11:20:46) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import io
>>> io.open
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'open'
>>> 
I concentrated to python package. In my home folder I unintentionally recognized an io.py and io.pyc. I removed the two files and: <built-in function open>.
Now my python script also works. I have already done a "Tabula rasa" before, means dd a virgin image to card, install picamera, but I had copied back my files into home folder, including these two one. :-)

Thanks Dave!
butyi
Doh! I hadn't considered an io module in the same directory you were working in (sometimes we don't consider the simplest things!) Anyway, glad to know it was something nice and easy to fix :)


Cheers,

Dave.

husamwadi
Posts: 18
Joined: Mon Jan 06, 2014 7:54 am

Re: Pure Python camera interface

Mon Jan 06, 2014 9:15 pm

Hi, Thank you so much for the picamera interface for python!

I want to make 2 preview images side by side kind of like this:

http://postimg.org/image/kmn70tnyn/

is that possible? I have tried opening two instances like this:

camera = picamera.Picamera()
camera2 = picamera.Picamera()

then running 2 windows side by side, but it says I cannot have 2 instances of Picamera running.

Is there anyway to copy the video preview (copy pixels) or something so that I can have 2 camera previews side by side?

Thank you :D !

Chiara
Posts: 10
Joined: Tue Aug 20, 2013 7:44 am

Re: Pure Python camera interface

Thu Jan 09, 2014 1:48 pm

Thanks for the picamera python!

I'm looking to a way to output live images from the camera to a linear array that control a led matrix. Would you kindly advice which is the better way?

Image processing:
1) a script that take a shot and rewrite forever the same image file.
2) another script using PIL process x and y from the file and write the array output.

this works but take a long refresh time: 1 shot at second at 40x40 pixel resolution.

Video processing:
1) discovered now opencv ...
2) would it be possible to process it with PIL?

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

Re: Pure Python camera interface

Thu Jan 09, 2014 2:03 pm

Chiara wrote:Thanks for the picamera python!

I'm looking to a way to output live images from the camera to a linear array that control a led matrix. Would you kindly advice which is the better way?

Image processing:
1) a script that take a shot and rewrite forever the same image file.
2) another script using PIL process x and y from the file and write the array output.

this works but take a long refresh time: 1 shot at second at 40x40 pixel resolution.

Video processing:
1) discovered now opencv ...
2) would it be possible to process it with PIL?

Interesting idea! Firstly, you want to avoid dealing with the disk (as it just slows everything down), so I'd suggest looking at the capturing to stream recipe in the docs. Secondly, as you want to get it working faster, check out video-port based captures (you can ignore all the complex code in there - the important bit to note is the "use_video_port=True" option).

However, while the above will speed things up a bit, you ideally want to move beyond encoded images (which introduces overhead you want to avoid). I suspect what would be most useful would simply be for the camera to give you a two-dimensional numpy array of the brightness of each pixel in the image...

The Y channel of a raw YUV capture is ideal for this, so check out the raw YUV capture recipe. You can ignore all the bits in there about reading the UV values and RGB conversion - in other words, you only need the bits up to the "Y = np.fromfile(...)" line (and don't forget to add a "use_video_port=True" parameter to the capture() call!).

Good luck!

Dave.

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

Re: Pure Python camera interface

Thu Jan 09, 2014 9:14 pm

husamwadi wrote:Hi, Thank you so much for the picamera interface for python!

I want to make 2 preview images side by side kind of like this:

http://postimg.org/image/kmn70tnyn/

is that possible? I have tried opening two instances like this:

camera = picamera.Picamera()
camera2 = picamera.Picamera()

then running 2 windows side by side, but it says I cannot have 2 instances of Picamera running.

Is there anyway to copy the video preview (copy pixels) or something so that I can have 2 camera previews side by side?

Thank you :D !
Yup, picamera can't be instantiated twice as prior to a fairly recent firmware version, two applications accessing the camera simultaneously locked up the board completely and required a reboot to "unstick" it. That's now been rectified, but the check will remain in place for a few versions until I'm reasonably confident everyone's running a recent firmware.

As to your question about duplicating the preview ... interesting! It's definitely not possible with picamera as it stands, but it *might* be possible to do it at a lower level. For example, there's an MMAL splitter component which picamera uses to duplicate the camera's video port to permit simultaneous video recording and image capturing. I've no idea if the following is possible - it's just speculation, but I wonder what would happen if a splitter component was connected to the preview port, and then two renderer components (preview windows) were bunged onto a couple of the splitter's output ports...

If it's possible, I think that'd be the way to do it. Anyway, I'll open a ticket in the bug tracker to remind me to investigate, this though I can't promise it'll be in the near future - I've got a bit too much on my plate at the mo and 1.0 is just around the corner.

Dave.

teenageguru
Posts: 1
Joined: Tue Feb 19, 2013 6:19 pm

Re: Pure Python camera interface

Fri Jan 10, 2014 4:20 am

Just another "well done", looks pretty cool and I'm going to try it out tomorrow morning!

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

Re: Pure Python camera interface

Sat Jan 11, 2014 8:32 pm

A very quick note (as I'm out at a friend's at the mo), to say picamera 1.0 has been released and Alex informs me the new Debian packages have hit the repository! I'll write a more extensive post once I'm back but checkout the changelog in the docs if you want all the gory details before then!

Comments, bug reports, suggestions welcome as always,

Dave.

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

Re: Pure Python camera interface

Sat Jan 11, 2014 11:20 pm

Right, happy new year to all the picamera users! Many thanks for your excellent bug reports, suggestions, and comments last year. As you've no doubt seen above, 1.0 is now released and the highlights this time are:

Debian packaging!
If you want to transition from using the pypi packages, firstly uninstall your picamera installation, then re-install with apt-get. There's instructions in the docs for each installation method, but assuming you were using the "system installation" it'd go something like this:

Code: Select all

$ sudo pip uninstall picamera
$ sudo apt-get update
$ sudo apt-get install python-picamera
The "sudo apt-get update" bit is only in there to make apt update its list of available packages (as this is a new addition it wouldn't know about it otherwise). If you're using python 3, replace "python-picamera" in the last line with "python3-picamera" (it's fine to have both installed if you switch between 2 and 3 regularly).

For any Arch/other-distro users out there - fear not, the pypi packages won't be going away - this is just an option to make updates a little easier for Raspbian users (I'm more than happy to accept patches for Arch packaging!)

Resizing supported ... mostly
All the capture methods, and the start-recording method now accept a "resize" parameter which will place a resizer before the encoder in the image processing pipeline. Why is this useful? Because the GPU can't handle encoding full resolution video, but with a resizer in place you can record full *frame* video (2592x1944) just at a lower resolution (say, 1024x768). There's a recipe in the docs covering this functionality.

Why do I say "mostly"? Because I've utterly failed to get cropping working with the resizer. What this means for the moment is that you're stuck with 4:3 aspect ratios for full-frame use (anything else will produce squished looking output).

GPIO bug squished
An annoying bug for people trying to use picamera in conjunction with RPi.GPIO has been squashed - many thanks to Martin O'Hanlon for reporting the issue and providing valuable feedback on it!

Circular recording
A new ring-buffer based stream is provided which allows you to record the last n seconds of video and then dump it to disk (or the network, or whatever else you fancy). Again, recipes included.


Anyway, those are the headlines - there's some smaller changes in there too (more raw formats, video-port-based RGB captures are back, MJPEG added as a recording format, current frame meta-data in the new "frame" property, etc. etc.). Do feel free to file bug reports, feature suggestions, and so forth at GitHub (or post something to the camera board here - I can't promise I monitor that quite as closely, but you'll likely get a wider audience!).

Have fun!

Dave.

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

Re: Pure Python camera interface

Wed Jan 15, 2014 3:35 pm

Some great features in this new release! But can anyone tell me why this code gives me an error after running for a while? I believe this code worked reliably under the previous version of the library.

Code: Select all

#!/usr/bin/python
# R-Pi camera simple frame averaging
# 15 Dec 2013 J.Beale

from __future__ import print_function
import io, os, time, datetime, picamera, cv2
import numpy as np

width = 2592/2  # use this much of full 5Mpix resolution
height = 1944/2
fcount_limit = 32  # how many frames to average

np.set_printoptions(precision=2)
stream = io.BytesIO()
with picamera.PiCamera() as camera:
   camera.resolution = (width, height)
   camera.exposure_mode = 'night'         # goes up to 1 second and 1600
   # camera.brightness = 55
   # camera.start_preview()
   time.sleep(2)  # 10 seconds delay needed for exposure to reach ISO 1600
   fcount = 0
   while True:
      camera.capture(stream, format='jpeg')
      time.sleep(0.2)
      stream.seek(0)
      data = np.fromstring(stream.getvalue(), dtype=np.uint8)
      image = cv2.imdecode(data, 1)
      image = image.astype(np.uint16)
      if (fcount > 0):
        sum = sum + image  # 2D floating-point matrix with accumulated frames
      else:
        sum = image
      fcount = fcount + 1
      daytime = datetime.datetime.now().strftime("%y%m%d-%H_%M_%S.%f")
      daytime = daytime[:-3]  # remove last three digits (xxx microseconds)
      if (fcount >= fcount_limit):
         imgName = daytime + ".jpg"
         average = sum / fcount  # average is total divided by number of elements
         image2 = average.astype(np.uint8)  # convert float back to single bytes
         cv2.imwrite(imgName, image2)  # save as an image
         print(" %s" % daytime)
         fcount = 0
Here is the error:

Code: Select all

[email protected] ~/pycam $ ./longavg.py &
[1] 8815
[email protected] ~/pycam $  140115-07_14_59.756
Traceback (most recent call last):
  File "./longavg.py", line 23, in <module>
    camera.capture(stream, format='jpeg')
  File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 859, in capture
    if not encoder.wait(30):
  File "/usr/lib/python2.7/dist-packages/picamera/encoders.py", line 326, in wait
    raise self.exception
picamera.exc.PiCameraError: Unable to return a buffer to the encoder port: Argument is invalid

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

Re: Pure Python camera interface

Wed Jan 15, 2014 3:45 pm

jbeale wrote: Here is the error:

Code: Select all

[email protected] ~/pycam $ ./longavg.py &
[1] 8815
[email protected] ~/pycam $  140115-07_14_59.756
Traceback (most recent call last):
  File "./longavg.py", line 23, in <module>
    camera.capture(stream, format='jpeg')
  File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 859, in capture
    if not encoder.wait(30):
  File "/usr/lib/python2.7/dist-packages/picamera/encoders.py", line 326, in wait
    raise self.exception
picamera.exc.PiCameraError: Unable to return a buffer to the encoder port: Argument is invalid
Interesting - I saw something similar on one of my test runs but wasn't able to replicate it on a later one, which means it's probably a race condition of some sort (eurgh). Still, I suppose that's what we get for messing around with threads! I'll open a ticket and see if I can figure out what's going on in the background encoder thread.

In the meantime, if you want to roll back to a previous version of the library:
  • If you installed from the raspbian packages, you'll need to uninstall those first (as only 1.0 is packaged that way at the mo). "sudo apt-get remove python-picamera" (or python3-picamera) will deal with that
  • Install the old version with pip: "sudo pip install picamera==0.8" (change 0.8 to whichever version you fancy - versions all the way back to 0.3 are actually available from pypi but I tend to hide the older ones as I do new releases, just to discourage people from using versions with known bugs in them)

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

Re: Pure Python camera interface

Thu Jan 16, 2014 2:58 pm

thanks, going back to 0.8 did prevent the crash and the program ran all night until I stopped it the next morning. I did notice one glitch though:

Code: Select all

 ...
 140116-05_18_02.905
 140116-05_20_49.204
 140116-05_23_35.502
Corrupt JPEG data: 32767 extraneous bytes before marker 0xd9
 140116-05_26_21.798
 140116-05_29_08.099
 140116-05_31_54.394
 140116-05_34_40.698

bootsmann
Posts: 28
Joined: Thu Jan 23, 2014 7:07 am

Re: Pure Python camera interface

Thu Jan 23, 2014 8:34 am

Hi,

How can I commit the file path of the captured image as a parameter to another function? (Otherwise, how I get the current filname?)
The other function is called "send_mail" and sends the captured image to an email address. For this reason I need the filename incl. path like /home/pi/camera/images/2014-46-18-46-42.jpg.

Code: Select all

image_path = '/home/pi/camera/images/'


def take_picture():
    with picamera.PiCamera() as camera:
        camera.exposure_mode = 'night'
        camera.resolution = (1024, 768)
        camera.start_preview()
        # Camera warm-up time
        time.sleep(2)
        camera.capture(image_path + '%s.jpg' % time.strftime("%H-%M-%S", time.gmtime()))
        
def send_mail(to, subject, text, files=[]):
    ....
    
take_picture()
send_mail(["[email protected]"], "Motion detected!", "Picture attached", picture])
Thx

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

Re: Pure Python camera interface

Thu Jan 23, 2014 9:08 am

bootsmann wrote:Hi,

How can I commit the file path of the captured image as a parameter to another function? (Otherwise, how I get the current filname?)
The other function is called "send_mail" and sends the captured image to an email address. For this reason I need the filename incl. path like /home/pi/camera/images/2014-46-18-46-42.jpg.

Code: Select all

image_path = '/home/pi/camera/images/'


def take_picture():
    with picamera.PiCamera() as camera:
        camera.exposure_mode = 'night'
        camera.resolution = (1024, 768)
        camera.start_preview()
        # Camera warm-up time
        time.sleep(2)
        camera.capture(image_path + '%s.jpg' % time.strftime("%H-%M-%S", time.gmtime()))
        
def send_mail(to, subject, text, files=[]):
    ....
    
take_picture()
send_mail(["[email protected]"], "Motion detected!", "Picture attached", picture])
Thx
I'd suggest using a variable to compute the filename (and os.path.join instead of simple string concatenation - just because it's good practice), and having your take_picture function return the filename of the picture it's captured, which you can then use in your send_mail function:

Code: Select all

import os
import time
import picamera

image_path = '/home/pi/camera/images/'

def take_picture():
    with picamera.PiCamera() as camera:
        camera.exposure_mode = 'night'
        camera.resolution = (1024, 768)
        camera.start_preview()
        # Camera warm-up time
        time.sleep(2)
        filename = os.path.join(image_path, '%s.jpg' % time.strftime("%H-%M-%S", time.gmtime()))
        camera.capture(filename)
        return filename
        
def send_mail(to, subject, text, files=[]):
    ....
    
send_mail(["[email protected]"], "Motion detected!", "Picture attached", [take_picture()])
Do let me know if you need a hand with the e-mail bit - I recently had to code something very similar so I've got a fairly simple routine handy that'll deal with constructing a MIME-based e-mail containing HTML and text alternatives, combined with an image attachment.


Dave.

bootsmann
Posts: 28
Joined: Thu Jan 23, 2014 7:07 am

Re: Pure Python camera interface

Thu Jan 23, 2014 9:26 am

@ waveform80

Thank you very much for your replay. My mail function looks like:

Code: Select all

def send_mail(to, subject, text, files=[]):
    assert type(to)==list
    assert type(files)==list

    msg = MIMEMultipart()
    msg['From'] = USERNAME
    msg['To'] = COMMASPACE.join(to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach( MIMEText(text) )

    for file in files:
        part = MIMEBase('application', "octet-stream")
        part.set_payload( open(file,"rb").read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"'
                       % os.path.basename(file))
        msg.attach(part)

    server = smtplib.SMTP('smtp.gmail.com:587')
    server.ehlo_or_helo_if_needed()
    server.starttls()
    server.ehlo_or_helo_if_needed()
    server.login(USERNAME,PASSWORD)
    server.sendmail(USERNAME, to, msg.as_string())
    server.quit()

send_mail(["[email protected]"], "Motion detected!", "Picture attached", filename])

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

Re: Pure Python camera interface

Thu Jan 23, 2014 9:39 am

bootsmann wrote:@ waveform80

Thank you very much for your replay. My mail function looks like:

Code: Select all

def send_mail(to, subject, text, files=[]):
    assert type(to)==list
    assert type(files)==list

    msg = MIMEMultipart()
    msg['From'] = USERNAME
    msg['To'] = COMMASPACE.join(to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach( MIMEText(text) )

    for file in files:
        part = MIMEBase('application', "octet-stream")
        part.set_payload( open(file,"rb").read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"'
                       % os.path.basename(file))
        msg.attach(part)

    server = smtplib.SMTP('smtp.gmail.com:587')
    server.ehlo_or_helo_if_needed()
    server.starttls()
    server.ehlo_or_helo_if_needed()
    server.login(USERNAME,PASSWORD)
    server.sendmail(USERNAME, to, msg.as_string())
    server.quit()

send_mail(["[email protected]"], "Motion detected!", "Picture attached", filename])
Looks pretty similar to what I've got (although I think the double EHLO/HELO is redundant). Here's what I wound up with for sending an HTML+text e-mail with an image attachment:

Code: Select all

import io
import os
import time
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
import smtplib
import ConfigParser
import picamera

CONFIG = None

def setup(config_filename):
    global CONFIG
    # Read the configuration file
    CONFIG = ConfigParser.RawConfigParser()
    if not CONFIG.read([config_filename]):
        raise ValueError('Unable to read configuration file %s' % config_filename)

def take_picture():
    stream = io.BytesIO()
    with picamera.PiCamera() as camera:
        camera.resolution = (640, 480)
        camera.start_preview()
        # Give the camera some warm-up time (to adjust exposure)
        time.sleep(2)
        # Capture to a temporary file
        camera.capture(stream, format='jpeg')
    # "Rewind" the stream so we can read it later
    stream.seek(0)
    return stream

def create_message(image_stream):
    # Set up the individual bits of the message, and their content
    root_container = MIMEMultipart(_subtype='related')
    root_container['From'] = CONFIG.get('email', 'sender')
    root_container['To'] = CONFIG.get('email', 'recipient')
    root_container['Subject'] = CONFIG.get('email', 'subject')
    root_container.preamble = 'This is a multi-part message in MIME format.'
    body_container = MIMEMultipart(_subtype='alternative')
    # The filename is entirely arbitrary as the image doesn't exist on disk
    s = 'image.jpg'
    html_body = MIMEText(CONFIG.get('email', 'html_body') % s, _subtype='html')
    text_body = MIMEText(CONFIG.get('email', 'text_body') % s, _subtype='plain')
    image_attachment = MIMEImage(image_stream.read())
    image_attachment.add_header('Content-Id', '<%s>' % s)
    # Mark the image as an attachment for plain-text clients
    image_attachment.add_header('Content-Disposition', 'attachment', filename=s)
    # Now structure the message as follows:
    #
    # var                   MIME-type
    # =================     =====================
    # root_container        multipart/related
    # +-- body_container    multipart/alternative
    # |   +-- text_body     text/plain
    # |   +-- html_body     text/html
    # +-- image_attachment  image/jpeg
    root_container.attach(body_container)
    body_container.attach(text_body)
    body_container.attach(html_body)
    root_container.attach(image_attachment)
    return root_container

def send_email(message):
    server = smtplib.SMTP(CONFIG.get('smtp', 'server'))
    try:
        server.ehlo()
        if CONFIG.getboolean('smtp', 'usetls'):
            server.starttls()
        if CONFIG.has_option('smtp', 'username') and CONFIG.get('smtp', 'username'):
            server.login(CONFIG.get('smtp', 'username'), CONFIG.get('smtp', 'password'))
        server.sendmail(
            message['From'],
            message['To'],
            message.as_string())
    finally:
        server.quit()

def main(config_filename='post.ini'):
    setup(config_filename)
    send_email(create_message(take_picture()))

if __name__ == '__main__':
    main()
And post.ini looks something like this:

Code: Select all

[smtp]
server   = smtp.gmail.com:587
usetls   = true
username = [email protected]
password = my_gmail_password

[email]
sender    = Me <[email protected]>
recipient = [email protected]
subject   = An image captured with picamera!

; %s in the following settings will be replaced by the filename
; of the image that the camera takes
text_body =
    Please see the attachment named %s.

html_body =
    <html>
    <head></head>
    <body>
        <b>Please see the attachment below!</b>
        <br/>
        <br/> 
        <img src="cid:%s"/>
    </body>
    </html>

Dave.

iain1940
Posts: 16
Joined: Sat Dec 22, 2012 8:53 pm

Developing picamera away from the Pi

Sat Jan 25, 2014 12:40 am

I'm developing some software for my new Pi Camera - which is working fine from the CLI.
I like to use an IDE (Wing) to develop python apps and would like to build the basic software on that and then transfer to the rpi for 'real' testing.

I tried to install picamera_1.0 on my Intel machine & it wouldn't install - Understandably ?!

Is there any way I can enter picamera code ? - I know it can't work but it would be nice to check as much as possible before downloading.

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

Re: Pure Python camera interface

Sun Jan 26, 2014 1:55 am

Picamera 1.1 - just released!

Not much to report in this version as it's just a bug-fix release: the issue causing long-running processes which captured lots of pictures to die should be fixed. I say "should" because, being a heisenbug (more specifically a race condition) I can't be 100% sure. I've had a camera capturing images continually for two days with the new version but that either means I've fixed it, or that I've just got lucky and not encountered the bug in that time. If anyone runs across the same issue in 1.1 I'd be most interested to hear about it!

There's also a fix for raw-captures which invoke the resizer to down-size an image. Other than that, no new functionality and a few documentation updates.

Dave.


P.S. My apologies for the delay between the tagging of 1.1 and the release of the package to PyPI and Raspbian - seems like something got broken (yet again) in either Debian or Python's packaging system (whichever it was, the docs failed to build first time round).

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

Re: Developing picamera away from the Pi

Sun Jan 26, 2014 1:54 pm

iain1940 wrote:I'm developing some software for my new Pi Camera - which is working fine from the CLI.
I like to use an IDE (Wing) to develop python apps and would like to build the basic software on that and then transfer to the rpi for 'real' testing.

I tried to install picamera_1.0 on my Intel machine & it wouldn't install - Understandably ?!

Is there any way I can enter picamera code ? - I know it can't work but it would be nice to check as much as possible before downloading.
How did you attempt to install the library? Theoretically you should be able to install it on any architecture (as the library is just pure Python), and even import it in Python, but it won't be able to control any camera.

The reason it can be imported on any architecture is actually a dirty hack to allow the docs to be built on ReadTheDocs: when the package is imported it tries to load libmmal (a library specific to the RPi); if that fails it simply replaces it with a mock object which doesn't do anything but doesn't throw any errors either.


Dave.

BorisS
Posts: 15
Joined: Fri Oct 11, 2013 7:08 pm

Re: Pure Python camera interface

Tue Jan 28, 2014 8:39 pm

I see following issue under latest 1.1 version (simple merge of two example recipes):

Code: Select all

#!/usr/bin/python

import time
import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (2592, 1944)
    camera.start_recording('full_res_1.h264', format='h264', resize=(1024, 768))
    camera.wait_recording(5)
    for i in range(2, 5):
        camera.split_recording('full_res_%d.h264' % i)
        camera.wait_recording(10)
        camera.capture('pic_%d.jpg' % i, use_video_port=True)
    camera.stop_recording()

the error seen on the console (after dumping two video segments and one picture) is

Code: Select all


Traceback (most recent call last):
  File "../full_res_rec.py", line 11, in <module>
    camera.split_recording('full_res_%d.h264' % i)
  File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 736, in split_recording
    self._video_encoder.split(output)
  File "/usr/lib/python2.7/dist-packages/picamera/encoders.py", line 533, in split
    raise PiCameraRuntimeError('Timed out waiting for an SPS header')
picamera.exc.PiCameraRuntimeError: Timed out waiting for an SPS header



Any ideas what is wrong? Same error is also seen without resizing option - and inline_headers should be on by default. BTW, do I see it right that capturing the video port means snapshots are taken using the original resolution and not the resized one?

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

Re: Pure Python camera interface

Tue Jan 28, 2014 9:00 pm

Hi Boris,
BorisS wrote:I see following issue under latest 1.1 version (simple merge of two example recipes):

Code: Select all

#!/usr/bin/python

import time
import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (2592, 1944)
    camera.start_recording('full_res_1.h264', format='h264', resize=(1024, 768))
    camera.wait_recording(5)
    for i in range(2, 5):
        camera.split_recording('full_res_%d.h264' % i)
        camera.wait_recording(10)
        camera.capture('pic_%d.jpg' % i, use_video_port=True)
    camera.stop_recording()

the error seen on the console (after dumping two video segments and one picture) is

Code: Select all


Traceback (most recent call last):
  File "../full_res_rec.py", line 11, in <module>
    camera.split_recording('full_res_%d.h264' % i)
  File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 736, in split_recording
    self._video_encoder.split(output)
  File "/usr/lib/python2.7/dist-packages/picamera/encoders.py", line 533, in split
    raise PiCameraRuntimeError('Timed out waiting for an SPS header')
picamera.exc.PiCameraRuntimeError: Timed out waiting for an SPS header



Any ideas what is wrong? Same error is also seen without resizing option - and inline_headers should be on by default. BTW, do I see it right that capturing the video port means snapshots are taken using the original resolution and not the resized one?
I can definitely reproduce the issue, but I'm not sure what the root cause is yet. My apologies - the test suite didn't pick it up as it currently only tests a single split (in a variety of resolutions and formats). I'll open a ticket and see if I can figure out what's going on for 1.2.

To answer your other question, capturing stills from the video port takes images at whatever resolution the camera is configured for (same as non-video-port captures), but only uses the full area of the sensor if the camera is configured for the maximum resolution (unlike non-video-port captures which always uses the full sensor area). The resize parameter is specific to the method that it's called with, so in the case of your code above you should capture full-frame video (from the full sensor area of 2592x1944), down-sized to 1024x768, and full-frame images without any down-sizing.

Incidentally, there's a ticket to improve the docs in this area as it's a confusing subject and I don't think I've adequately explained it in the docs at the moment.


Dave.

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

Re: Pure Python camera interface

Fri Jan 31, 2014 6:22 pm

waveform80 wrote: <snip>
I can definitely reproduce the issue, but I'm not sure what the root cause is yet. My apologies - the test suite didn't pick it up as it currently only tests a single split (in a variety of resolutions and formats). I'll open a ticket and see if I can figure out what's going on for 1.2.
<snip>
Issue #49 is tracking this over at github and I've figured out what's going wrong. There's a workaround mentioned in the ticket's comments but I'll try and get out another release this weekend with a "proper" fix.


Dave.

BorisS
Posts: 15
Joined: Fri Oct 11, 2013 7:08 pm

Re: Pure Python camera interface

Sat Feb 01, 2014 9:02 pm

Hi Dave,
thank you very much! Workaround works like a charm.

Boris

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

Re: Pure Python camera interface

Sun Feb 02, 2014 3:43 am

Well, another week, another bug fix release - 1.2 is currently building and should be uploaded to PyPI within the next hour (and Raspbian in the next day or two - my apologies to Alex for yet again releasing in the middle of a weekend!).

Nothing terribly interesting this time, other than the fix to ensure that split_recording works after performing a video-port based capture (which means that the advanced recipe for splitting to/from a circular stream should finally work properly!).

The docs have seen a bit more work (as usual), including a new section which tries to explain some of the detail behind picamera's inner workings (partially for the benefit of anyone who fancies hacking on the code, and partially so I can keep it all straight in my head!).

Other than that - many thanks for all the support so far and keep the comments, bug reports, suggestions, and so on coming!


Dave.

Chris_Reynolds
Posts: 72
Joined: Mon May 14, 2012 7:25 am

Re: Pure Python camera interface

Sun Feb 02, 2014 10:45 pm

Quick post to say thanks for your work on this. I'm playing with the circular capture at the moment and I really appreciate the quality of the work and the docs. Thanks again.

Return to “Camera board”