かみのメモ

コンピュータビジョン・プログラムな話題中心の勉強メモ

EDSDKを使ってCanon EOSカメラをPCから制御してみた

またまたニッチなネタ。

Canon一眼レフカメラであるEOSシリーズをPCから制御するプログラムを書いてみたよ、というお話です。

ソースコード

カメラと接続して写真を1枚撮って保存して終了する、という基本動作のソースコードGitHubにアップしました。 言語はC++です。

github.com

詳細はGitHubの方を見ていただくことにして、この記事ではプログラムを書いている間に気付いたことなどを適当にまとめてみます。

SDKの入手方法

まずはEDSDK(EOS Digital Software Development Kit)を入手します。

Canonは日本の企業のはずなんですが、なぜか日本のページからは入手できません。

※ 2019年3月から日本語サイトでも配布を開始したようです:キヤノン:デジタルカメラ開発支援パッケージSDK・APIのご提供(2019/03/06追記)。

Canon EuropeもしくはCanon USAのdeveloper programにアカウント登録することでダウンロードできます。

言語はC++C#VBに対応しているようです。

サンプルプログラム

EDSDKをダウンロードすると、中にCameraControlRawDevelopの2種類のサンプルプログラムが含まれています。 前者はGUIからカメラの露光時間やフォーカスを操作して写真を撮影することができるアプリです。 後者は撮影したRAWデータを使って、自由に色補正やホワイトバランス調整を施すためのアプリです。

今回はとりあえずPCからカメラを制御するのが目的ですので、前者を参考にしました。

とはいえ、このサンプルプログラム、相当古いのかWindows MFCで書かれてるんですよね…。 ロジックとビューの分離とかそういう原則ガン無視なのでかなり読みにくいです。

自前で実装する時は、SDKに同包されてるAPI Refferenceを参照する方が懸命かもしれません。

実装上気をつけた方が良さそうなこと

カメラモード

カメラがP/S/Aモードになっていると露光時間やF値などが自動で設定されます。 プログラムで設定した値を優先させたいときはカメラをMモードにした上でプログラムを実行しましょう。

カメラ側で非同期処理が生じるケース

カメラのシャッターを押す処理やフォーカスを動かす処理など、EdsSendCommand()で指示した処理はカメラ側で非同期実行されます。 非同期処理の実行中は、カメラはビジー状態になり他の処理を受け付けなくなります。

カメラ側での処理を待つ場合は、事前にObjectEventHandler, PropertyEventHandler, CameraStateEventHandlerのうち対応するものにイベント関数を登録した上でEdsGetEvent()を繰り返しコールすればよいようです。 EdsGetEvent()をコールしたときにしかイベントのハンドリングを検証しないようなので注意しましょう。

画像の保存

撮影した画像の保存先はカメラに挿したSDカード or ホストPCから選択できます。 ホストPCに保存する場合は、カメラメモリからホストPCにデータを転送する処理を書かなければなりません。 サンプルコードではホストPC側に保存する処理の方を実装しています。

また、カメラ側での保存形式をJPEGに設定した上でメモリストリームを使ってデータ転送すれば、一時保存することなくOpenCVcv::Matの形式に直接変換することができます。 この辺りもサンプルコードを参照してください。

まずいコードを書いたとき

APIを呼び出す順序を間違えたり、変なパラメータを設定したりするとカメラがエラーを起こすことがあります(カメラのディスプレイにエラーメッセージが表示される)。 こうした場合は一度カメラの電源を切って再起動しましょう。


と、こんなところでしょうか?

使っていて気付いたことがあればまた追記したいと思います。