LoginSignup
1
1

More than 5 years have passed since last update.

Haskellでv4l2を用いてwebカメラから得られた画像を保存する(自分用メモ)

Last updated at Posted at 2015-05-31

0. インストール環境

・Ubuntu 15.04
・ghc 7.8.3

1. v4l2のパッケージをインストールする・・・が

v4l2のapiをラップしてくれているv4l2パッケージが既に存在します。(作成してくださった方に感謝!)
このパッケージをインストールするだけなのですが、

cabal install v4l2

でインストール出来ませんでした。

原因は
v4l2パッケージが依存しているbindings-linux-videodev2ForeignのunsafePerformIOを使用しており、
ghc 7.8.3ではunsafePerformIOが削除されているからです。
なので、2015/5/31現在では、手動でパッケージをビルドしなければ、使用できません。
ここでは、v4l2のパッケージをインストールしwebカメラの映像を表示させるところまでの手順を記載します。
(手順が合っているかどうかは分からないけど。)

1.1 bindings-linux-videodev2の手動インストール

bindings-linux-videodev2をインストールしないとv4l2パッケージをインストールすることが出来ないので、
まずこちらのパッケージからインストールします。

1.1.1 ソースのダウンロード

ソースはこちらにあります。
git cloneするか、snapshotをクリックすればダウンロードできます。

1.1.2 generate.shの実行

./generate/generate.sh

を実行します。
すると、Bindingsフォルダやdistフォルダなどが作成されます。

1.1.3 Bindingsフォルダ以下のソースを書き換え

generate.shを実行したあと、Bindings/Linuxの中に
・VideoDev2.hsc
・videodev2.h
・videodev2.h.rej
・videodev2_cinline.c
が存在します。

生成されたファイルはどうも上手く生成されていないため、
ここの内容に置き換えてしまいます。
(これが良いのかわからないけど・・・。)

1.1.4 VideoDev2.hscの内容を修正。

import Foreign(unsafePerformIO)

import System.IO.Unsafe(unsafePerformIO)

に書き換えます。

1.1.5 インストール

bindings-linux-videodev2のルートフォルダで

cabal configure
cabal build
cabal install

とすれば、bindings-linux-videodev2がインストールされます。

1.2 v4l2の手動インストール

1.2.1 ソースのダウンロード

ソースはこちらにあります。
git cloneするか、snapshotをクリックすればダウンロードできます。

1.2.2 v4l2.cabalの内容を修正

v4l2.cabalファイルの内容を

bindings-linux-videodev2 >= 0.1 && < 0.2,

のところを

bindings-linux-videodev2 >= 0.2,

に修正します。
(∵インストールしたのはbindings-linux-videodev2のv0.2.0.1だから)

1.2.3 インストール

v4l2のルートフォルダで

cabal configure
cabal build
cabal install

とすれば、v4l2がインストールされます。

2. v4l2パッケージを用いたプログラム例

v4l2パッケージを用いて、webカメラから取り込んだ画像を保存するプログラムの例を作成しました。
丁寧に書かれた例は、v4l2パッケージを作成した方が作成されていますので、そちらを参考にされたほうが良いです。

以下のプログラムは例外処理などを書かず、
「デバイスを開いて、映像を取り込んで、画像を保存する」という
できるだけ最小限のコードにしました。

v4l2_ex.hs
import System.IO
import Control.Monad
import Foreign (Ptr)
import Graphics.V4L2

width :: Int
width = 640

height :: Int
height = 480

imf :: ImageFormat
imf = ImageFormat width height PixelRGB24 FieldNone (width * 3) (width * 3 * height) ColorSRGB

main :: IO()
main = do
  device <- openDevice "/dev/video0"
  format <- setFormat device Capture imf
  forM_ [0..50] $ \i ->
    withFrame device format $ \p _ -> writePPM i (imageWidth format) (imageHeight format) p
  closeDevice device

writePPM :: Int -> Int -> Int -> Ptr a -> IO ()
writePPM idx w h p = do
  handle <- openFile ("writePPM_" ++ show idx ++ ".ppm") WriteMode
  hPutStr handle $ "P6\n" ++ show w ++ " " ++ show h ++ "\n255\n"
  hPutBuf handle p (w * h * 3)
  hClose handle

次はwebカメラで取り込んだ映像をwindow画面に表示したいと思います。

(補足) repa-v4l2のインストール

v4l2のパッケージを更に扱いやすくラップしてくれているパッケージがrepa-v4l2のようです。

cabal install repa-v4l2

とすると、llvm関連のエラーが出ました。

ですので、自分は

sudo aptitude install llvm-3.4

としました。(llvm-3.5とllvm-3.6をインストールしても上手くインストール出来ませんでした。)
更にghc-7.8.3/settingsのファイルを開いて

, ("LLVM llc command","llc-3.4")
, ("LLVM opt command","opt-3.4")

と修正します。

その後、

cabal install repa-v4l2

すれば、インストール出来ました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1