2015年10月1日 星期四

openFrameworks: Control The Raspberry Pi Camera Module

since: 2015/10/01
update: 2016/04/25
reference:
1. jvcleave/ofxRPiCameraVideoGrabber
2. 在 Raspberry Pi 中擷取螢幕畫面(Snapshot)的工具 - G. T. Wang

A. 說明
     在此處會利用 Mac 的 Xcode 當成程式的編輯工具, 而編譯執行皆需在 Pi 上進行. 

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

B. 啟用 Pi 的相機模組功能
    1. $ sudo raspi-config

    2. 選擇 5. Enable Camera

    3. > Enable

    4. > Yes

C. 安裝附加在 openFrameworks 上的相機模組程式
     分別在 Mac 與 Pi 上的 openFrameworksaddons 目錄下安裝:

     // Pi
     $ cd /home/pi/of_v0.8.4_linuxarmv7l_release/addons
     $ git clone https://github.com/jvcleave/ofxRPiCameraVideoGrabber

     // Mac
     $ cd /Lanli/RD/project/openFrameworks/of_v0.8.4_osx_release/addons
     $ git clone https://github.com/jvcleave/ofxRPiCameraVideoGrabber  

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

D. 在 Xcode 上新增 openFrameworks 的 app 專案
      1. 於所安裝 openFrameworks 版本下的 projectGenerator_osx 目錄內,
          點二下: projectGenerator.app

      2. 設定新專案的資訊:
          Name: RPiCamera
          Addons: ofxRPiCameraVideoGrabber
          > 按下: "GENERATE PROJECT"

      3. 完成後, 可於所安裝 openFrameworks 版本下的 apps > myApps 目錄下看到:
          RPiCamera 專案資料夾, 其資料夾下的 addons.make 檔案內容即是附加的
          程式名稱.

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

E. 用 Xcode 開啟 RPiCamera 專案目錄下的 RPiCamera.xcodeproj     
      1. 參考剛剛下載 addons 的 ofxRPiCameraVideoGrabber 目錄下的 example 程式碼

      2. 修改 main.cpp, ofApp.hofApp.cpp 程式碼如下:
          // main.cpp
#include "ofMain.h"
#include "ofApp.h"
#include "ofGLProgrammableRenderer.h"

int main()
{
    ofSetLogLevel(OF_LOG_VERBOSE);
    ofSetCurrentRenderer(ofGLProgrammableRenderer::TYPE);
   
    //ofSetupOpenGL(1280, 720, OF_WINDOW);
    //@update 2015/10/01

    ofSetupOpenGL(1280, 800, OF_FULLSCREEN);
    ofRunApp( new ofApp());
}


*************************************************************************


          // ofApp.h
#pragma once

#include "ofMain.h"
#include "ofAppEGLWindow.h"
#include "TerminalListener.h"
#include "ImageFilterCollection.h"
#include "ofxRPiCameraVideoGrabber.h"

class ofApp : public ofBaseApp, public KeyListener{
   
public:
   
    void setup();
    void update();
    void draw();
    void keyPressed(int key);
   
    void onCharacterReceived(KeyListenerEventData& e);
    TerminalListener consoleListener;
    ofxRPiCameraVideoGrabber videoGrabber;
   
    ImageFilterCollection filterCollection;
   
    bool doDrawInfo;
};


*************************************************************************


          // ofApp.cpp
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup()
{
    ofSetLogLevel(OF_LOG_VERBOSE);
    ofSetLogLevel("ofThread", OF_LOG_ERROR);
    //ofSetVerticalSync(false);
   
    doDrawInfo    = true;
   
    consoleListener.setup(this);
   
    OMXCameraSettings omxCameraSettings;
    //omxCameraSettings.width                = 1280;
    //omxCameraSettings.height                = 720;

    omxCameraSettings.width                    = 1280;
    omxCameraSettings.height                = 800;
    omxCameraSettings.isUsingTexture        = false;
   
    omxCameraSettings.doRecording            = false;        //default: false
    if (omxCameraSettings.doRecording)
    {
        omxCameraSettings.doRecordingPreview    = true;
        omxCameraSettings.recordingFilePath        = "";        //will self generate if left blank
        omxCameraSettings.doConvertToMKV        = false;    //converts file to .mkv using mkvmerge(if present)
    }
   
    videoGrabber.setup(omxCameraSettings);
    filterCollection.setup();
}

//--------------------------------------------------------------
void ofApp::update()
{
}

//--------------------------------------------------------------
void ofApp::draw(){
    //Nothing really to do here as the output is rendered directly to full screen
}

//--------------------------------------------------------------
void ofApp::keyPressed  (int key)
{
    ofLog(OF_LOG_VERBOSE, "%c keyPressed", key);
   
    if (key == 'e')
    {
        videoGrabber.applyImageFilter(filterCollection.getNextFilter());
    }
   
    if (key == 'g')
    {
        doDrawInfo = !doDrawInfo;
    }
    if (key == 'q')
    {
        ofLogVerbose(__func__) << "SENDING QUIT";
        videoGrabber.stopRecording();
    }
    if (key == 't')
    {
        videoGrabber.toggleLED();
    }
}

void ofApp::onCharacterReceived(KeyListenerEventData& e)
{
    keyPressed((int)e.character);
}


備註: 在 Xcode 上, 只需用到: Product > Clean , 將在 Mac 上不支援 Pi 的語法清除.

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

F. 編譯與執行
     1. 將 Xcode 建立的整個 RPiCamera 專案資料夾, 拷貝並上傳到 Pi 相對的位置下:
         /home/pi/of_v0.8.4_linuxarmv7l_release/apps/myApps/

     2. 在 Pi 上建立 app 捷徑(symbolic link)
         $ cd
         $ ln -s /home/pi/of_v0.8.4_linuxarmv7l_release/apps/myApps/RPiCamera ./RPiCamera

     3. 編譯
         $ cd
         $ cd RPiCamera
         $ make

     4. 在 Pi 上執行
         $ cd ~/RPiCamera
         $ make run

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

G. 結果

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

H. 加入拍照功能:
     1. 安裝 raspi2png
         a. 先安裝 png 函式庫
             $ sudo apt-get install libpng12-dev

         b. 下載 raspi2png
             $ cd ~
             $ git clone https://github.com/AndrewFromMelbourne/raspi2png.git

         c. 編譯 raspi2png
             $ cd ~/raspi2png
             $ make

     2. 擷取畫面測試
         $ cd ~/raspi2png
         $ ./raspi2png        (預設檔名: snapshot.png)

         備註: ./raspi2png --help
     3. 於程式加上 print screen 功能:
         開啟 ofApp.cpp 檔案, 修改如下:
....
void ofApp::keyPressed  (int key)
{
....
    if (key == 't')
    {
        videoGrabber.toggleLED();
    }

    //@add 2015/10/21: print screen ######################################
    if (key == 'p')
    {
        string mySweetCommand = "/home/pi/raspi2png/raspi2png --pngname ";
       
        // yyyymmddhhmmss
        mySweetCommand += ofToString(ofGetYear()) + ofToString(ofGetMonth())+ ofToString(ofGetDay())+ ofToString(ofGetHours())+ ofToString(ofGetMinutes()) + ofToString(ofGetSeconds());

        mySweetCommand += ".png";
       
        system(mySweetCommand.c_str());
    }
}

....


     4. 於 Pi 上編譯, 並執行. 按下 "p" 即會在 ~/RPiCamera/bin 下產生擷取的影像畫面

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

I. 備註:     
   reference:
   a. Capturing HD Video With The Pi Camera Module 24
   b. Streaming Video Using VLC Player

   c. Raspberry Pi Camera 簡介

   1. 單純拍攝短片或照片
   
         a. raspicam commands
             1. 錄製 10 秒鐘影片:
                 $ raspivid --codec MJPEG -o video.mpg -t 10000
                 在 pi 上播放:
                 $ omxplayer ./video.mpg

         b. Python picamera
             1. install python-picamera
                 $ sudo apt-get install python-picamera
                 $ sudo apt-get install python3-picamera
                 $ sudo apt-get install python-picamera-docs

             2. camera_test.py
#!/usr/bin/python3

import picamera

camera = picamera.PiCamera()

# auto white balance
# off,auto,sun,cloud,shade,tungsten,fluorescent,incandescent,flash,horizon
#camera.awb_mode = 'auto'


camera.start_preview()


#for i in range(100):
#    camera.brightness = i
#    sleep(0.2)


#camera.capture('image.jpg')

camera.start_recording('video.h264')
camera.wait_recording(3)
camera.stop_recording()

camera.stop_preview()


             3. 播放
                 (1). 下載
video.h264 在 Mac 上, 利用 VLC 播放
                 (2). 先將 h264 轉乘 mp4 再播放
                       $ sudo apt-get install gpac
                       $ MP4Box -add video.h264 video.mp4

                       $ omxplayer ./video.mp4                          (亦可下載到 Mac 上播放)     -----------------------------------------------------------------------------------------------
   2. 開機自動執行
RPiCamera 程式
       a. 開機後自動登入
           $ sudo nano /etc/inittab

           ....
           #1:2345:respawn:/sbin/getty --noclear 38400 tty1
           1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1

       b. 登入後自動執行 RPiCamera 程式
           $ sudo nano ~/.bashrc
....
# auto run RPiCamera after start up 10 second, but not SSH sign in
sleep 10
echo "tty = $(tty)"

if [ $(tty) == "/dev/tty1" ]; then

  echo "We have a match."
  cd ~/RPiCamera
  ./bin/RPiCamera

else
  echo "We dont match."
fi


-----------------------------------------------------------------------------------------------
   3. 排程: 每天下午5點整關機
       $ sudo crontab -e
          # shutdown at 17:00 everyday
          00 17 * * * /sbin/shutdown -h now

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

   4. 當要使用一般的 USB Webcam 時, 記得要再執行: $sudo raspi-config ,  
       將 Pi 的相機模組功能停用.

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。