F#でOpenCvSharpを使ってカメラキャプチャする

OpenCvSharp を使ってカメラキャプチャをする | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/6258

の F# 版です。WPF で作ってあります。

module MainApp

open System
open System.Windows
open System.Windows.Controls
open FsXaml
open OpenCvSharp.CPlusPlus
open OpenCvSharp.Extensions

type MainWindow = XAML<"MainWindow.xaml">

let mutable _frame:Mat = null

/// <summary>
/// カメラを表示
/// </summary>
/// <param name="id"></param>
let camera(id:int) =
    let cap = new VideoCapture()
    cap.Open(id)
    if cap.IsOpened() then
        let fs = FrameSource.CreateCameraSource(0)
        let win = new Window("camera")
        let frame = new Mat()
        _frame <- frame
        let mutable loop = true
        while loop do
            cap.Read( frame )
            if frame.Empty() = false then
                win.ShowImage( frame )
                let key = Cv2.WaitKey(100)
                if key = 27 then
                    loop <- false
            else
                loop <- false

let loadWindow() =
   let window = MainWindow().CreateRoot()
   let accessor = MainWindow.Accessor(window)
   // ボタンクリック時のイベント
   accessor.btnCamera.Click.Add( fun e -> camera(0) )
   accessor.btnCapture.Click.Add( fun e -> 
        accessor.img.Source <- WriteableBitmapConverter.ToWriteableBitmap(_frame)
       )
   // ウィンドウを返す
   window

[<STAThread>]
(new Application()).Run(loadWindow()) |> ignore

やっていることは、C# 版と同じで、カメラ用のウィンドウを開くのとボタンを押したときにキャプチャする処理が入っています。ファイルに保存する処理はほとんど同じなので省略。

F# で WPF を扱うときは FsXaml のタイププロバイダを使います。ボタンイベントとかはボタン自身に名前を付けて Add.Click 等で追加すれば ok.
フォームの場合は Bitmap に落とすのに BitmapConverter.ToBitmap を使いますが、WPF の Image.Source に対しては WriteableBitmapConverter.ToWriteableBitmap を使って Mat から WritableBitmap に落とします。
Mat と Bitmap の相互変換と、float/double で処理した自前の Pixcels クラスを使えば、画像解析のトライアンドエラーがしやすいかなと、奮闘中です。もう少しできたら github にでも。

ひとまず、動作サンプルはこちら。直ぐ動くように opencv の dll も含んでいるのでちょっと大きいです。

カテゴリー: F#, OpenCV パーマリンク