1. 程式人生 > >picamera 1.10 教程及api中文簡譯(三)picamera的基本使用

picamera 1.10 教程及api中文簡譯(三)picamera的基本使用

4、picamera基本使用方法

如果你是一個python程式設計師,那麼你將輕鬆的掌握以下例項,請隨時提出改進或新的例項。

4.1、捕捉一個影象輸出至檔案

使用capture方法可以輕鬆將捕捉到的影象輸出至指定檔案。
下面這個例項是捕捉一個解析度為1024*768的影象,並將之輸出到foo.jpg中:

import time
import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (1024, 768)
    camera.start_preview()
    #攝像頭預熱2秒
    time.sleep(2
) camera.capture('foo.jpg')

需要注意的是,若目錄中有同名檔案,picamera將會重置該圖片。

4.2、捕捉一個流

這個例項是通過capture()方法將捕捉的一個影象轉成一個以jpeg解碼的流(bytes流):

import io
import time
import picamera

# 建立一個流
my_stream = io.BytesIO()
with picamera.PiCamera() as camera:
    camera.start_preview()
    # 攝像頭預熱
    time.sleep(2)
    camera.capture(my_stream, 'jpeg'
)

需要注意的是,這不像輸出到一個檔案,該流捕捉以後會自動關閉指令碼,因為在這個例項中沒有對流進行其他操作。若物件有flush方法的話,在捕捉完畢後,會呼叫物件的flush方法,如下:

import time
import picamera

# 開啟一個副檔名為jpg的檔案
my_file = open('my_image.jpg', 'wb')
with picamera.PiCamera() as camera:
    camera.start_preview()
    time.sleep(2)
    camera.capture(my_file)
# 在此時capture會呼叫my_file的flush方法,完成流封裝。
# 但並未關閉檔案,需要呼叫close進行關閉 my_file.close()

上邊這個例項需要注意的是,我們並沒有指定捕捉檔案的解碼格式,所以capture會獲取輸出的檔名的副檔名來尋找解碼屬性。

4.3、捕捉一個影象轉化為PIL imag物件

首先我們要捕捉一個影象流,然後通過流讀取將影象的資料轉換成PIL image物件。

import io
import time
import picamera
from PIL import Image

# 建立一個流
stream = io.BytesIO()
with picamera.PiCamera() as camera:
    camera.start_preview()
    time.sleep(2)
    camera.capture(stream, format='jpeg')
# 將指標指向流的開始
stream.seek(0)
image = Image.open(stream)

4.4、捕捉一個影象轉化為open cv物件

首先我們捕捉一個影象流,然後將影象資料轉換為open cv物件:

import io
import time
import picamera
import cv2
import numpy as np

# 建立一個流
stream = io.BytesIO()
with picamera.PiCamera() as camera:
    camera.start_preview()
    time.sleep(2)
    camera.capture(stream, format='jpeg')
# 從流構建numpy
data = np.fromstring(stream.getvalue(), dtype=np.uint8)
# 通過opencv解碼numpy
image = cv2.imdecode(data, 1)
# opencv解碼後返回以RGB解碼的影象資料
image = image[:, :, ::-1]

如果你不想使用有損JPEG編碼,並希望加快這一解碼過程的話,可以使用picamera自帶的picamera.array模組。可以使用PiRGBArray類簡單的捕獲’brg’格式的資料。(假定RGB與BGR是解析度相同的資料,只是具有相反的顏色)

import time
import picamera
import picamera.array
import cv2

with picamera.PiCamera() as camera:
    camera.start_preview()
    time.sleep(2)
    with picamera.array.PiRGBArray(camera) as stream:
        camera.capture(stream, format='bgr')
        # 此時就可以獲取到bgr的資料流了
        image = stream.array

4.5、調整捕捉影象的解析度

有時,我們需要將圖片進行某種分析或處理,你希望儘可能的捕獲比較小解析度的影象,雖然這種解析度的調整可以交給PIL或者opencv來完成,但是通過picamera可以更搞笑的完成這個操作:

import time
import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (1024, 768)
    camera.start_preview()
    # 攝像頭預熱
    time.sleep(2)
    camera.capture('foo.jpg', resize=(320, 240))

同時調整解析度的引數也可以適用於捕獲視訊的start_recording()方法。

4.6、捕獲連續影象

您可能希望連續捕捉到的影象的亮度、色彩與對比度上保持一致(例如,這個可能在延遲攝影中非常有用)。可以設定一些屬性,確保在多個鏡頭中保持畫面的一致。具體來說,您需要保證攝像頭的曝光時間,白平衡和畫面增益都是固定的。

  • 設定曝光時間:shutter_speed
  • 設定畫面增益:首先將 exposure_mode設定為’off’然後將analog_gain和digital_gain設定在合理的範圍值。
  • 設定白平衡:將awb_mode設定為’off’,然後將awb_gains設定為red或者blue或者直接設定iso的值。

設定這些屬性是非常專業的,並且非常難調整到合適的範圍值。在白天,對於iso,100~200是一個簡單的合理範圍,而在低光環境下,需要調整到400~800。對於shutter_speed如果需要確定一個合理的範圍值可以直接查詢exposure_speed屬性。對於曝光增益,通常只需要將analog_gain設定為大於1的值(analog_gain的預設值為1,但這將產生一個全黑的影象幀)。

下面的這個例子提供了一些簡單配置的例項:

import time
import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (1280, 720)
    camera.framerate = 30
    # 等待攝像頭預熱,適應光線環境
    time.sleep(2)
    # 現在設定影象修正值
    camera.shutter_speed = camera.exposure_speed
    camera.exposure_mode = 'off'
    g = camera.awb_gains
    camera.awb_mode = 'off'
    camera.awb_gains = g
    # 最後將採取修正值的影象輸出到檔案
    camera.capture_sequence(['image%02d.jpg' % i for i in range(10)])

4.7、捕獲延時拍攝序列

有一種需求就是,每若干分鐘捕獲一張影象,並存儲起來,若像實現這種需求最簡單的方法就是capture_continuous()函式。呼叫這個函式時,會不斷捕捉攝像頭影象,知道呼叫停止函式。這樣你可以很輕易的控制定時捕獲兩張圖片之間的時間。
接下來這個例子就是演示每5分鐘定時抓拍一張圖片:

import time
import picamera

with picamera.PiCamera() as camera:
    camera.start_preview()
    time.sleep(2)
    for filename in camera.capture_continuous('img{counter:03d}.jpg'):
        print('Captured %s' % filename)
        time.sleep(300) # 休眠5分鐘

除了延時捕獲影象以外,還可以通過datetime來計算時間,在特定的時間開啟攝像頭捕獲影象。

import time
import picamera
from datetime import datetime, timedelta

def wait():
    # 計算時間,將從下一個小時開始捕獲影象
    next_hour = (datetime.now() + timedelta(hour=1)).replace(
        minute=0, second=0, microsecond=0)
    delay = (next_hour - datetime.now()).seconds
    time.sleep(delay)

with picamera.PiCamera() as camera:
    camera.start_preview()
    wait()
    for filename in camera.capture_continuous('img{timestamp:%Y-%m-%d-%H-%M}.jpg'):
        print('Captured %s' % filename)
        wait()

4.8、在光線比較弱的環境下捕獲影象

樹莓派的攝像頭可以在光纖比較弱的環境下捕獲影象,其主要的實現方式是通過設定捕獲屬性,給攝像頭設定一個比較高的光線增益,以及增加曝光的時間以讓攝像頭接收儘可能多的光。我們可以通過設定shutter_speed[設定曝光時間]與framerate[幀率]兩個引數。首先我們要設定一個比較慢的幀率,然後將曝光時間設定為6秒來捕獲影象:

import picamera
from time import sleep
from fractions import Fraction

with picamera.PiCamera() as camera:
    camera.resolution = (1280, 720)
    # 設定幀率為1/6fps,然後將曝光時間設定為6秒
    # 最後將iso引數設定為800
    camera.framerate = Fraction(1, 6)
    camera.shutter_speed = 6000000
    camera.exposure_mode = 'off'
    camera.iso = 800
    # 給攝像頭一個比較長的預熱時間,讓攝像頭儘可能的適應周圍的光線
    # 你也可以試試開啟AWB【自動白平衡】來代替長時間的預熱
    sleep(10)
    # 最後捕捉影象,因為我們將曝光時間設定為6秒,所以拍攝的時間比較長
    camera.capture('dark.jpg')

如果在一個光線不是特別暗的地方使用以上例項,則你會得到一個嚴重曝光以至於可能是全白的影象檔案。

因為我們設定了一個比較長的曝光時間,如果這時移動攝像頭,那麼我們將會得到一個嚴重影象扭曲的照片。

4.9、將捕獲的流轉換為網路流

這是一個將捕獲的圖片通過網路傳給伺服器的例子。在這個例子中我們有兩個指令碼:伺服器端,樹莓派端。然後通過socket進行連線。我們使用一種簡單的資料包協議。首先我們資料包的前4個位元組是型別為int值的資料,代表影象資料的長度,然後是影象的資料。若收到的資料長度為0,則代表picamera已經停止捕獲影象。
資料包格式如下:
這裡寫圖片描述
首先在伺服器執行一下指令碼(這個指令碼是基於PIL包來解析jpeg檔案,你也可以使用其他的圖形庫,比如opencv或graphicsMagick等來替代PIL):

import io
import socket
import struct
from PIL import Image

# 啟動socket,設定監聽埠為8000,接受所有ip的連線
server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 8000))
server_socket.listen(0)

# 接受一個客戶端連線
connection = server_socket.accept()[0].makefile('rb')
try:
    while True:
        # 讀取我們的包頭,也就是圖片的長度
        # 如果長度為0則退出迴圈
        image_len = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
        if not image_len:
            break
        # 構造一個流來接受客戶端傳輸的資料
        # 開始接收資料並寫入流
        image_stream = io.BytesIO()
        image_stream.write(connection.read(image_len))
        # 將流的指標指向開始處,並通過PIL來讀入流
        # 並將之儲存到檔案
        image_stream.seek(0)
        image = Image.open(image_stream)
        print('Image is %dx%d' % image.size)
        image.verify()
        print('Image is verified')
finally:
    connection.close()
    server_socket.close()

樹莓派指令碼如下:

import io
import socket
import struct
import time
import picamera

# 連線之前建立的伺服器端
# 將my_server替換成伺服器的ip
client_socket = socket.socket()
client_socket.connect(('my_server', 8000))

# 建立一個連線
connection = client_socket.makefile('wb')
try:
    with picamera.PiCamera() as camera:
        camera.resolution = (640, 480)
        # 攝像頭預熱 
        camera.start_preview()
        time.sleep(2)

        # 記錄一個開始時間,並構建一個流來儲存捕獲的圖片資料
        # 我們可以直接講捕獲的資料流傳給伺服器,但為了捕獲我們的影象長度,
        # 我們暫且阻礙傳輸,並等待捕獲完成,並獲取圖長度組建資料包
        start = time.time()
        stream = io.BytesIO()
        for foo in camera.capture_continuous(stream, 'jpeg'):
            # 將資料寫入流中
            connection.write(struct.pack('<L', stream.tell()))
            connection.flush()
            # 將資料流的指標指向起始位置
            connection.write(stream.read())
            # 如果我們的等待的連線時間大於30秒則退出迴圈
            if time.time() - start > 30:
                break
            # 重置捕獲流,等待下一次捕獲影象。
            stream.seek(0)
            stream.truncate()
    # 迴圈結束,寫一個長度為0的資料包,告知伺服器我們已經完成了整個操作。
    connection.write(struct.pack('<L', 0))
finally:
    connection.close()
    client_socket.close()

4.10、錄製視訊檔案

錄製一個視訊檔案很簡單:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.start_recording('my_video.h264')
    camera.wait_recording(60)
    camera.stop_recording()

請注意,我們在這裡使用的方法是wait_recording,而不是time.sleep(),以下的例子也是使用這個方法來演示,雖然功能上與time.sleep相同,但是wait_recording會不斷的監聽錯誤的丟擲(比如磁碟空間不足),一旦出現錯誤會立即暫停捕獲影象,來處理當前的錯誤,而不是在sleep以後才進行處理。所以如果我們用time.sleep來替代wait_recording方法的話,這種錯誤只能在stop_recording()後才能被處理,這可能導致了我們未能及時處理錯誤,導致影象資料捕獲失敗。

4.11、將錄製的視訊轉換為資料流

這個例子與將錄製的視訊儲存到檔案很像:

import io
import picamera

stream = io.BytesIO()
with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.start_recording(stream, format='h264', quality=23)
    camera.wait_recording(15)
    camera.stop_recording()

在這裡,我們設定了一個視訊質量引數quality,指示解碼器將影象質量維持在23左右。H.264視訊編碼主要取決於兩個引數:

  • 視訊輸出是以秒為單位,單位時間內輸出的視訊最大則質量越高,視訊輸出的預設預設為17000000(17Mbps)最大值為25000000(25Mbps)。我們設定的引數越大,則解碼器會在相應的品質上進行解碼。你可能會發現,除非你使用更高的解析度,否則在預設情況下是不需要限制視訊質量的。
  • 質量引數通知解碼器保持什麼水平的影象進行錄製。quality引數值的的範圍是1(最高質量)~40(最低質量),在普通的4M寬頻下,將視訊質量設定為20~25之間是合理範圍。

4.12、錄製多個視訊檔案

如果你希望將視訊檔案分割多個進行錄製,可以使用split_recording()方法來實現這個功能:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.start_recording('1.h264')
    camera.wait_recording(5)
    for i in range(2, 11):
        camera.split_recording('%d.h264' % i)
        camera.wait_recording(5)
    camera.stop_recording()

在例項中,我們通過split_recording函式來分割錄製10個視訊檔案,每個視訊檔案的時間為5秒。

也可以利用record_sequence()函式來實現這個功能,而且程式碼更加簡潔:

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    for filename in camera.record_sequence(
            '%d.h264' % i for i in range(1, 11)):
        camera.wait_recording(5)

record_sequence這個方法適用於1.3以後的版本。

4.13、迴圈錄製

這個功能類似於將錄製的視訊轉換成檔案流,區別是,picamera將產生一個loop緩衝區,如果在緩衝區已滿,則picamera會將最開頭的視訊替換掉,以保證在緩衝區的視訊是最新的。

一個典型的例子,就是安全監控例項,在這個例項中,我們希望檢測到視訊內有移動的物體,然後將這段視訊記錄起來。本例中我們先進行錄製20秒的視訊,並將其儲存到檔案流中,直到write_now返回true才會將這個快取區域儲存起來(這段實現比較多樣,我們可以使用任意一個檢測影象運動的演算法來實現這個例子)。如果我們檢測到有移動的物體,那麼我們將重新整理快取中錄製10秒的視訊,並將該視訊儲存至磁碟:

import io
import random
import picamera

def write_now():
    # 在這我們做一個假的例子,產生一個隨機的true來代替檢測到運動的物體
    return random.randint(0, 10) == 0

def write_video(stream):
    print('Writing video!')
    with stream.lock:
        # 找到視訊的起始端
        for frame in stream.frames:
            if frame.frame_type == picamera.PiVideoFrameType.sps_header:
                stream.seek(frame.position)
                break
        # 將流輸出到磁碟
        with io.open('motion.h264', 'wb') as output:
            output.write(stream.read())

with picamera.PiCamera() as camera:
    stream = picamera.PiCameraCircularIO(camera, seconds=20)
    camera.start_recording(stream, format='h264')
    try:
        while True:
            camera.wait_recording(1)
            if write_now():
                # 檢測到移動的物體
                # 進行10秒的錄製,並將錄製的視訊存放至快取區
                camera.wait_recording(10)
                write_video(stream)
    finally:
        camera.stop_recording()

在上面的示例中,我們使用了執行緒鎖,以防止我們在儲存視訊時快取區的錄影被修改(因為我們建立的快取流是一個loop緩衝區,是可以讀寫覆蓋的)。如果沒有使用with語句塊,那麼我們在寫入完成時,應該取消對快取的stream.lock鎖。

需要注意的是,快取區最少要有20秒的視訊,因為使用H.264解碼的話,最小位元速率為17Mbps,所以超過或等於20秒的視訊流才是可用的視訊。

這功能支援1.0及以後版本。

4.14、將錄製的視訊用於網路傳輸

這個功能類似於錄製視訊流,但區別在於,我們將建立一個socket物件,這不像我們傳輸影象的資料協議那麼複雜,我們並不需要對視訊流進行資料包的封裝。這一次,我們將持續傳送視訊的幀組成的資料流,以便簡化我們的socket視訊通訊。

首先我們開始編寫伺服器端指令碼:

import socket
import subprocess

# 首先我們建立一個socket監聽,埠為8000,接受所有的ip連線
server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 8000))
server_socket.listen(0)

# 然後我們建立一個socket檔案流
connection = server_socket.accept()[0].makefile('rb')
try:
    # 如果接受到一個客戶端連線,那麼我們將通過終端來開啟一個播放器。
    # 如果你使用的是mplayer,則需要註釋掉vlc這段。
    cmdline = ['vlc', '--demux', 'h264', '-']
    #cmdline = ['mplayer', '-fps', '25', '-cache', '1024', '-']
    player = subprocess.Popen(cmdline, stdin=subprocess.PIPE)
    while True:
        # 建立一個死迴圈,每次讀取1k的資料
        # 然後將資料傳送到播放器
        data = connection.read(1024)
        if not data:
            break
        player.stdin.write(data)
finally:
    connection.close()
    server_socket.close()
    player.terminate()

注意,如果你是在Windows上執行此程式碼,則需要提供完成播放器exe檔案路徑。

你可能會注意到,播放的視訊有幾秒鐘的延遲,不用擔心,這是正常現象,因為媒體播放器為了能夠流暢的播放視訊,會事先換成幾秒的視訊流,以防止網路卡頓。但是一些播放器(比如mplayer)允許使用者跳過快取或減少緩衝區直接播放視訊,雖然這將提高了播放的卡頓和中斷播放的現象,但是視訊的延遲將大大減少。

現在我們來編寫樹莓派端程式碼:

import socket
import time
import picamera

# 建立一個socket連線,來連線我們的伺服器,這裡需要將my_server替換成伺服器的ip
client_socket = socket.socket()
client_socket.connect(('my_server', 8000))

# 建立一個socket檔案流
connection = client_socket.makefile('wb')
try:
    with picamera.PiCamera() as camera:
        camera.resolution = (640, 480)
        camera.framerate = 24
        # 開啟攝像頭,並預熱兩秒
        camera.start_preview()
        time.sleep(2)
        # 開始錄製並傳輸,錄製視訊總長度為60秒
        camera.start_recording(connection, format='h264')
        camera.wait_recording(60)
        camera.stop_recording()
finally:
    connection.close()
    client_socket.close()

還可以指出的是,我們能夠利用netcat和raspivid命令來快速實現這段指令碼,在終端上執行以下程式碼:

server-side: nc -l 8000 | vlc --demux h264 -
client-side: raspivid -w 640 -h 480 -t 60000 -o - | nc my_server 8000

然而,我們可以將連線反過來,通過樹莓派簡歷一個視訊伺服器,等待播放器的連線。當連線簡歷時,我們會錄製60秒的視訊,並實時傳輸過去。這樣我們可以先初始化攝像頭的連線,等待播放器的接入:

import socket
import time
import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.framerate = 24

    server_socket = socket.socket()
    server_socket.bind(('0.0.0.0', 8000))
    server_socket.listen(0)

    # 建立一個socket檔案流
    connection = server_socket.accept()[0].makefile('wb')
    try:
        camera.start_recording(connection, format='h264')
        camera.wait_recording(60)
        camera.stop_recording()
    finally:
        connection.close()
        server_socket.close()

然後我們可以通過播放器來開啟這個網路地址,這裡演示的是利用vlc來開啟攝像頭:

vlc tcp/h264://my_pi_address:8000/

注意的是,目前,VLC或mplayer都不會對視訊流進行GPU解碼,他們會先嚐試利用CPU進行解碼,但這種軟解碼的效率不夠強大。所以為了能夠順利播放,你需要將播放器執行在一個性能比較好的裝置上(廢話。。。)

4.15、在捕捉的影象上疊加圖片

在攝像頭進行捕捉的同時我們可以執行多層渲染器,然而picamera只允許載入單個渲染器到相機端,所以如果想在捕獲的影象上疊加圖片,我可以需要建立一個附加的渲染器來顯示我們捕捉到的靜態影象。

注意,picamera不支援在捕捉影象或拍攝視訊的同時來疊加影象資訊,如果需要嵌入一些文字資訊請參閱下面的“在捕捉的影象上疊加文字資訊”

疊加圖片工作是一個比較複雜的操作,因為攝像頭模組的大小是32X16,所以渲染的圖片的寬度必須是32的倍數,其高度必須是RGB格式所規定的位元組。不過雖然聽上去很複雜,但是實現起來卻很簡單。

下面這個例項演示的是,載入任意一個影象或PIL,讓他擴充套件到RGB允許的尺寸,這將呼叫add_overlay()函式:

import picamera
from PIL import Image
from time import sleep

with picamera.PiCamera() as camera:
    camera.resolution = (1280, 720)
    camera.framerate = 24
    camera.start_preview()

    # 讀取任意一張圖片
    img = Image.open('overlay.png')
    # 建立一個新的RGB渲染器,並指定渲染器的格式
    pad = Image.new('RGB', (
        ((img.size[0] + 31) // 32) * 32,
        ((img.size[1] + 15) // 16) * 16,
        ))
    # 將原始圖片載入到渲染器中
    pad.paste(img, (0, 0))

    # 在這裡我們使用原始圖片的尺寸來進行疊加
    o = camera.add_overlay(pad.tostring(), size=img.size)
    # 在預設情況下,圖片將疊加在第0層上,下方是我們的攝像頭圖片層(第2層)
    # 這裡我們將圖片設定為盤透明並覆蓋在捕捉的影象上
    o.alpha = 128
    o.layer = 3

    # 建立一個死迴圈,等待使用者終止指令碼
    while True:
        sleep(1)

我們可以不使用一個圖片檔案作為疊加源,我們可以直接從numpy中產生疊加圖片資料。在下面的例子中,我們構建了一個numpy 以捕捉圖片相同的解析度覆蓋在圖片上,並在重心畫一個白色的十字以標示出我們的覆蓋物。

import time
import picamera
import numpy as np

# 建立一個numpy空間,指定解析度為1280*720,並在畫面中間畫一個十字
a = np.zeros((720, 1280, 3), dtype=np.uint8)
a[360, :, :] = 0xff
a[:, 640, :] = 0xff

with picamera.PiCamera() as camera:
    camera.resolution = (1280, 720)
    camera.framerate = 24
    camera.start_preview()
    # 我們通過add_overlay直接將覆蓋物疊加在第3層上,這裡我們可以省略覆蓋物的尺寸
    # 預設為捕獲圖片的尺寸
    o = camera.add_overlay(np.getbuffer(a), layer=3, alpha=64)
    try:
        # 等待使用者終止指令碼
        while True:
            time.sleep(1)
    finally:
        camera.remove_overlay(o)

我們可以調成layer引數以隱藏渲染器(layer預設為2),或者可以通過alpha引數設定渲染器的透明度和調整渲染器的大小,使渲染器不用拉伸顯示在介面上。我們也可以通過疊加圖片來構建簡單的使用者介面。

這功能支援1.8及以後版本。

4.16、在捕捉的影象上疊加文字

相機模組包含一個基本的註釋工具,它最多可允許在圖片上疊加255個ASCII字元(包括在圖片或視訊的捕捉中或捕捉後進行疊加)。想要實現這一功能,只需要將需要疊加的文字填在annotate_text引數上:

import picamera
import time

with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.framerate = 24
    camera.start_preview()
    camera.annotate_text = 'Hello world!'
    time.sleep(2)
    # 將圖片輸出到檔案
    camera.capture('foo.jpg')

我們也可以通過一點技巧來顯示比較長的字串:

import picamera
import time
import itertools

s = "This message would be far too long to display normally..."

with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.framerate = 24
    camera.start_preview()
    camera.annotate_text = ' ' * 31
    for c in itertools.cycle(s):
        camera.annotate_text = camera.annotate_text[1:31] + c
        time.sleep(0.1)

當然,這個功能也可以用在顯示或嵌入錄影的時間戳(該例項還演示了在繪製的時間戳下利用annotate_background屬性填充背景色):

import picamera
import datetime as dt

with picamera.PiCamera() as camera:
    camera.resolution = (1280, 720)
    camera.framerate = 24
    camera.start_preview()
    camera.annotate_background = picamera.Color('black')
    camera.annotate_text = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    camera.start_recording('timestamped.h264')
    start = dt.datetime.now()
    while (dt.datetime.now() - start).seconds < 30:
        camera.annotate_text = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        camera.wait_recording(0.2)
    camera.stop_recording()

該功能支援1.7及以後版本。

4.17、控制攝像頭的led指示燈

攝像頭的led指示燈指示了該攝像頭模組在開啟中,但是在某種情況下,這可能會是一個障礙,比如你在拍攝野外動物的情況下,這個led燈可能會嚇跑動物,而且在近距離拍攝的時候,可能會將led的燈光反射到攝像頭上。

你可以利用一些簡單的方式來解決,比如用膠帶或者一些遮擋物來擋住led燈,也可以通過picamera來設定disable_camera_led屬性關閉led指示燈。

但是這種操作需要有RPi.GPIO庫的支援,以及提供執行該python指令碼足夠的許可權(這意味著你將需要通過root身份來執行這段指令碼)才可以控制Led燈的屬性。

import picamera

with picamera.PiCamera() as camera:
    # 將led指示燈設定為關閉
    camera.led = False
    # 這時拍照時指示燈不會亮起
    camera.capture('foo.jpg')

這裡需要注意的是,當你第一次使用led屬性來控制指示燈時,GPIO庫將設定為BCM模式[GPIO.setmode(GPIO.BCM)]和禁止使用警示燈[GPIO.setwarnings(False)],所以這將使你無法控制板載led燈,如果想控制則需要手動開啟。

相關推薦

picamera 1.10 教程api中文picamera基本使用

4、picamera基本使用方法 如果你是一個python程式設計師,那麼你將輕鬆的掌握以下例項,請隨時提出改進或新的例項。 4.1、捕捉一個影象輸出至檔案 使用capture方法可以輕鬆將捕捉到的影象輸出至指定檔案。 下面這個例項是捕捉一個解析度為10

picamera 1.10 教程api中文在python2.7/3.2+上安裝 picamera

轉自:http://blog.csdn.net/talkxin/article/details/50499950 點選開啟連結 以前做過一個家庭攝像頭,用的是raspivid的命令列來實現,但是功能太少,不得不放棄重構,正好遇到了picamera這個庫,使我能擺脫用命

kafka 1.0 中文文件--Broker的配置

3.1 Broker Configs 基本配置如下:    1. broker.id    2. log.dirs    3. zookeeper.connect 下面將更詳細地討論主題級別的配置和預設設定。 名稱 描述 型別

ElasticSearch6.X版本Java Api中文詳解之Index Api解析

Inde API允許將型別化JSON文件索引到特定索引中,並使其可搜尋。生成JSON文件有幾種不同的方法:1.手動(也就是自己使用)使用本機位元組[]或作為字串。2.使用將自動轉換為其JSON等效的對映

BosonNLP API 中文語義分析筆記

BosonNLP API 中文語義分析 from __future__ import print_function, unicode_literals from bosonnlp import BosonNLP import requests

K8S 1.9.0二進制包部署

無法 emc mod tps -o cal text tor amd 4、k8s node#############kubelet cp kubelet /usr/bin/chmod 755 /usr/bin/kubeletmkdir -p /app/kubernetes/

RedisRedis基本命令操作與API

最新 integer 朋友圈 shm ica 有序集合 object prop hashmap 一Redis 連接 Redis 連接命令主要是用於連接 redis 服務。 實例 以下實例演示了客戶端如何通過密碼驗證連接到 redis 服務,並檢測服務是否在運行: r

Python爬蟲教程-25-數據提取-BeautifulSoup4

運行 .com div 分享 size content bs4 text ont Python爬蟲教程-25-數據提取-BeautifulSoup4(三) 本篇介紹 BeautifulSoup 中的 css 選擇器 css 選擇器 使用 soup.select 返回一個列

UI“重天”之selenium--常用API和問題處理

Selenium常用API: 前面兩篇示例程式碼中用到了一些selenium的API方法,例如定位元素的八種方法、訪問url、等待、操作瀏覽器、獲取title、點選、清理等等。 有關於selenium的常用API在園子中有寫的非常詳細的文章。先貼大佬文章地址:https://www.cnblogs.com

Emscripten教程之連線C++和JavaScript

本文是Emscripten-WebAssembly專欄系列文章之一,更多文章請檢視專欄。也可以去作者的部落格閱讀文章。歡迎加入Wasm和emscripten技術交流群,群聊號碼:939206522。 Emscripten提供了多種方法來連線和互動JavaScript和編譯的C或c++,本文逐一介紹。

RancherDocker快速上手指南

......續接上一篇文章。 六、映象庫及應用 Rancher還有很多功能,在這裡都不細說了,因為這是一篇快速上手指南,講到這已經差不多了。但是還得補充下更重要的內容,上一篇通篇講的都是使用Rancher拉取公共映象來建立容器或應用,那麼如何建立和使用我們自已的私有映象,這也是初學者必須

Spring極學習例項化Bean的方法有兩種

其實例項化一個Bean並沒有那麼複雜,不就是將new Bean()的過程放到Spring這裡來實現了嗎? 其實的確如此,當然了,之前的設計模式中的例項化Bean的方式Spring也得支援支援吧。 一、最直觀例項化(反射模式) xml配置 <bean id="car1

Jedis操作單節點redis,叢集redisTemplate操作redis叢集

package com.dream21th.dream21thredis.controller;import java.util.List;import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;im

JavaWeb學習HttpServletResponse基本應用——使用PrintWriter輸出中文2

使用PrintWriter流向客戶端瀏覽器輸出中文資料 一、使用PrintWriter流輸出中文注意問題 response.setCharacterEncoding("UTF-8");//設定將字元以"UTF-8"編碼輸出到客戶端瀏覽器 PrintWriter out = response.

程式碼—— 歐式距離

可能還不算是最簡單的實現吧,至少形式上,稍微優化一點: def euclidean(x, y): d = 0. for xi, yi in zip(x, y): d

API 限流器 在Spring Cloud 微服務體系中整合RedisRateLimiter

  這篇是API限流器這個系列的終章,就是講述如何在Spring Cloud 微服務開發中應用我發明的先進限流器。開篇明義,基本思路如下:1. 定義一個annotation - RedisLimiter2. 在RestController 中有URL Mapping 的方法上

java網路程式設計:10、基於TCP的socket程式設計緩衝流、flush方法、關閉流

宣告:本教程不收取任何費用,歡迎轉載,尊重作者勞動成果,不得用於商業用途,侵權必究!!! 文章目錄 一、使用緩衝流、註釋流的關閉—帶來的效果 二、使用flush方法—帶來的效果 三、關閉流—帶來的效果 四、系列文章(java網路程式設計) 上篇講了基於tcp的程式設計

spring cloud+.net core搭建微服務架構:Api閘道器

前言 國慶假期,一直沒有時間更新。 根據群裡面的同學的提問,強烈推薦大家先熟悉下spring cloud。文章下面有純潔大神的spring cloud系列。 上一章最後說了,因為服務是不對外暴露的,所以在外網要訪問服務必須通過API閘道器來完成,而spring cloud 提供了現成的Api閘道器元件zuul

基於android的網路音樂播放器-回撥實現音樂播放音樂收藏的實現

作為android初學者,最近把瘋狂android講義和瘋狂Java講義看了一遍,看到書中介紹的知識點非常多,很難全部記住,為了更好的掌握基礎知識點,我將開發一個網路音樂播放器-EasyMusic來鞏固下,也當作是練練手。感興趣的朋友可以看看,有設計不足的地方也

SpringBoot啟動流程

我們在上一節中說了SpringBoot的應用上下文的物件是AnnotationConfigEmbeddedWebApplicationContext,通過名字直譯就是註解配置的可嵌入的web應用上下文。我們對它先不做過多的介紹,在不遠的文章中我們就會對它進行一下