रास्पबेरी पाई कैमरा मॉड्यूल का उपयोग करके थोड़े समय में छवियां लें


13

मैं एक ऐसी परियोजना पर काम कर रहा हूं जिसमें मुझे रास्पबेरी पाई कैमरा मॉड्यूल का उपयोग करके प्रति सेकंड (कोई फिल्म) लगभग 30 छवियां लेने की आवश्यकता है।

मैं इसके लिए Picamera लाइब्रेरी ( http://picamera.readthedocs.org/en/latest/api.html ) का उपयोग कर रहा हूं , लेकिन समस्या यह है, कि चित्र लेने में लगभग 0.2 - 0.4 सेकंड लगते हैं, जो लंबे समय तक होता है। मैंने पहले से ही use_video_portसंपत्ति निर्धारित की है True, जिसने थोड़ी मदद की, लेकिन समय अभी भी लंबा है।

क्या आप में से किसी को पता है कि पाइथन और रास्पबेरी पाई कैमरा मॉड्यूल का उपयोग करके थोड़े समय (लगभग 0.025 के दशक) में तस्वीरें कैसे ली जाती हैं?

जवाबों:


18

पिकमेरा के साथ 0.025 में चित्र लेने के लिए आपको 80fps से अधिक या उसके बराबर एक फ्रेम-दर की आवश्यकता होगी। 80 बल्कि 40fps की आवश्यकता का कारण (यह देखते हुए कि 1 / 0.025 = 40) यह है कि वर्तमान में कुछ समस्या है जो हर दूसरे फ्रेम को मल्टी-इमेज एनकोडर में छोड़ देने का कारण बनती है इसलिए प्रभावी कैप्चर रेट आधे कैमरे के फ्रैमरेट के रूप में हवा देता है।

पाई का कैमरा मॉड्यूल बाद के फ़र्मवारों में 80fps के लिए सक्षम है ( पिकामेरा डॉक्स में कैमरा मोड देखें ), लेकिन केवल एक वीजीए रिज़ॉल्यूशन (फ्रैमेरेट्स के साथ उच्च रिज़ॉल्यूशन के लिए अनुरोध> 30fps के परिणामस्वरूप वीजीए के लिए अनुरोध किए गए रिज़ॉल्यूशन में वृद्धि होगी, इसलिए यह है एक सीमा जिसे आप 40fps पर भी सामना करेंगे)। दूसरी समस्या जिसकी आपको सम्भावना है वह है एसडी कार्ड गति सीमाएँ। दूसरे शब्दों में, आपको संभवतः नेटवर्क पोर्ट या इन-मेमोरी स्ट्रीम जैसी कुछ चीज़ों को कैप्चर करने की आवश्यकता होगी (यह मानकर कि आपके द्वारा कैप्चर की जाने वाली सभी छवियां रैम में फिट होंगी)।

निम्नलिखित स्क्रिप्ट मुझे एक कब्जा दर ~ 38fps (यानी प्रति चित्र के 0.025s से ऊपर) एक अति पर 900Mhz पर सेट के साथ एक पाई पर मिलती है:

import io
import time
import picamera

with picamera.PiCamera() as camera:
    # Set the camera's resolution to VGA @40fps and give it a couple
    # of seconds to measure exposure etc.
    camera.resolution = (640, 480)
    camera.framerate = 80
    time.sleep(2)
    # Set up 40 in-memory streams
    outputs = [io.BytesIO() for i in range(40)]
    start = time.time()
    camera.capture_sequence(outputs, 'jpeg', use_video_port=True)
    finish = time.time()
    # How fast were we?
    print('Captured 40 images at %.2ffps' % (40 / (finish - start)))

यदि आप प्रत्येक फ्रेम के बीच में कुछ करना चाहते हैं, तो capture_sequenceआउटपुट की सूची के बजाय एक जनरेटर फ़ंक्शन प्रदान करके भी यह संभव है :

import io
import time
import picamera
#from PIL import Image

def outputs():
    stream = io.BytesIO()
    for i in range(40):
        # This returns the stream for the camera to capture to
        yield stream
        # Once the capture is complete, the loop continues here
        # (read up on generator functions in Python to understand
        # the yield statement). Here you could do some processing
        # on the image...
        #stream.seek(0)
        #img = Image.open(stream)
        # Finally, reset the stream for the next capture
        stream.seek(0)
        stream.truncate()

with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.framerate = 80
    time.sleep(2)
    start = time.time()
    camera.capture_sequence(outputs(), 'jpeg', use_video_port=True)
    finish = time.time()
    print('Captured 40 images at %.2ffps' % (40 / (finish - start)))

ध्यान रखें कि ऊपर दिए गए उदाहरण में, प्रसंस्करण अगली कैप्चर से पहले क्रमिक रूप से हो रहा है (यानी कोई भी प्रसंस्करण जो आप आवश्यक रूप से अगले कैप्चर में देरी करेंगे)। थ्रेडिंग ट्रिक्स के साथ इस विलंबता को कम करना संभव है लेकिन ऐसा करने में एक निश्चित मात्रा में जटिलता शामिल है।

आप प्रसंस्करण के लिए अनएन्कोडेड कैप्चर पर भी ध्यान दे सकते हैं (जो एन्कोडिंग के ओवरहेड को हटा दें और फिर जेपीईजी को डिकोड करें)। हालाँकि, ध्यान रखें कि Pi का CPU छोटा है (विशेषकर VideoCore GPU की तुलना में)। जब आप 40fps पर कैप्चर करने में सक्षम हो सकते हैं , तो कोई तरीका नहीं है कि आप उन फ़्रेमों के किसी भी गंभीर प्रसंस्करण को करने में सक्षम हों, ऊपर बताए गए सभी ट्रिक्स के साथ भी। उस दर पर फ्रेम प्रसंस्करण करने का एकमात्र यथार्थवादी तरीका यह है कि एक नेटवर्क पर फ़्रेम को एक तेज़ मशीन पर भेज दिया जाए, या GPU पर प्रसंस्करण किया जाए।


आपके तेज़ उत्तर के लिए धन्यवाद! लेकिन आपके कार्यक्रम में मैं व्यक्तिगत चित्रों को संसाधित नहीं कर पाऊंगा। क्या इसे करने का कोई तरीका है? क्योंकि मुझे अगले टोकन से पहले हर व्यक्तिगत तस्वीर के साथ काम करने की आवश्यकता है।
टिमो डेनक

1
जनरेटर फ़ंक्शन के साथ फ़्रेम के बीच प्रसंस्करण करने की एक विधि शामिल करने के लिए उत्तर में संशोधन किया।
डेव जोन्स

.capture_fterence KeyboardInterrupts को अनदेखा करता प्रतीत होता है। क्या आप जानते हैं कि इसके आस-पास कैसे काम करना है?
सेरिन

@ इस तरह कुछ पर बिजली की खपत क्या होगी?
टेड टेलर ऑफ़ लाइफ

एफपीएस इस समाधान के लिए तेज़ है लेकिन छवियों को स्ट्रीम से फ़ाइलों में सहेजने के लिए कैसे?
बेकलोलो

4

इस StackOverflow जवाब के अनुसार आप क्या चाहते हैं को पूरा करने के लिए gstreamer और निम्न आदेश का उपयोग कर सकते हैं:

raspivid -n -t 1000000 -vf -b 2000000 -fps 25 -o - | gst-launch-1.0 fdsrc ! video/x-h264,framerate=25/1,stream-format=byte-stream ! decodebin ! videorate ! video/x-raw,framerate=10/1 ! videoconvert ! jpegenc ! multifilesink location=img_%04d.jpg

यह कमांड 25 फ्रेम प्रति सेकंड के साथ वीडियो स्ट्रीम उत्पन्न करने के लिए raspivid के वीडियो आउटपुट को लेने के लिए प्रकट होता है और फिर वीडियो को व्यक्तिगत जेपीईजी छवियों में बदलने के लिए gstreamer का उपयोग करता है।

यह आलेख वैकल्पिक रिपॉजिटरी से gstreamer1.0 स्थापित करने के बारे में निर्देश देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.