こんにちは。
画像処理と動物が大好きな現役エンジニアの”はやぶさ”@Cpp_Learningです。
すごい真面目に『動物の行動観測カメラ』を開発し、良い成果が出せたので…
このカメラシステム開発を題材にした『ソフトウェア開発入門のチュートリアル記事』を書きました!
本サイトで動物といえば…そう!可愛い”あの子”のことです!!
以降から茶番を交えながら、真面目に!楽しく!カメラシステム(ソフトウェア)開発手順を説明します。興味のある人は肩の力を抜いて続きをご覧ください(*・ω・)ノ♪
Contents
ゆーちゅーばー”くるる”のお願い
てくてく…てくてくてく……てく 小気味よい小さな足音が聞こえてくる。
本サイトに再び!あの人気フクロウ”くるる”@kururu_owl が遊びに来てくれました!
飛ぶという行動は非常にエネルギーを使うため、飛ぶよりも歩くことを好むフクロウもいる。
- 種族:アフリカオオコノハズク
- 出身:ヨーロッパ
- 育ち:日本
↑なかなか凄いワードが並ぶ”くるる”から東北弁の「んだー」が飛び出たことに少々驚いたが、小刻みに頷くだけにして、話しを促す。
あぁ”スサー”ね……
マジで分からない…YouTuberの間で流行ってる言葉なのか?(くるるは自分のチャンネルをもつ正真正銘のYouTuberです!)
くるるが目を輝かせながらお願いしている!断れるわけがない!!
わーい!足元でぴょんぴょん跳ねる”くるる”が今日も可愛い!笑
要求分析
”スサー”が何か分からないことには開発しようがない…
クライアント”くるる”に対し、なんとなく”様”を付けたが”くるる”は全く動揺しない。実に堂々とした2歳児だ!!
人間界の常識じゃないことに少し安心しました。
「しょうがないなぁー」と言いながら”くるる”が1枚の写真を見せてくれた↓

おお~確かに”スサー”って感じだ!要するに鳥が”羽を伸ばす行動”を”スサー”というらしい。
課題抽出
”スサー”が何か分かったところで疑問が沸いてきた。
「ぶっぶー!!」今日一番の大きな声でダメ出しされた…
言われてみれば。。
- ”スサー”を撮る前にバッテリーが切れた
- 数時間分の映像を全部録画したらメモリがパンクした
鳥は1時間に何度も”スサー”するときもあれば、3時間待っても”スサー”しない日もあります。
また”スサー”してからカメラを構えると警戒して、しばらく”スサー”してくれない…
…だそうです。意外と難しそうだけど”スサー”撮れたら希少映像で話題沸騰かも!!
燃えてきた!!
クライアントやチームメンバーと開発するソフトについて、しっかり議論することで、課題を明らかにしましょう!
仕様検討
課題をまとめてみる↓
【課題】
- ”スサー”を撮る前にバッテリーが切れた
- 数時間分の映像を全部録画したらメモリがパンクした
- ”スサー”するタイミングは本人すら分からない
- 警戒しているときは”スサー”しない
この課題を解決するには『”スサー”するタイミングで定点カメラのシャッターを切る』という方法がスマートだと考えた。
では『”スサー”するタイミングとは?』休日にフクロウをじっくり観察します(・ω・)じーーっ
すると以下のことが分かってきました。
【くるるの行動パターン】
- お気に入りの場所からは基本的に動かない
- 首だけ動かして周辺を監視している
- ”スサー”を含む大きな行動の前兆として頭が上下に動く
- ”スサー”は初動から終了までに5~10秒かかる
一般的なフクロウも↑と同じ行動パターンなのかは不明だが、少なくとも”くるる”の行動パターンはこんな感じでした。
ここまで分かれば開発するソフトの仕様が見えてきます↓
- 画像上の指定座標(頭)の動きを常に観測する(トラッキング)
- 指定座標が上方向に動いたときにシャッターを切る(差分検出)
- シャッターを切ってから25秒間の映像を録画する(マージン確保)
- システムを停止させるまで❶~➌を何度でも繰り返す(自動化)
”クライアントの有無”や”チーム・個人での開発”など、ケースバイケースですが、仕様検討のざっくりとしたポイントは以下の通りです。
- やりたいことを実現するために調査(今回は”くるる”の観察)を行う
- 情報整理のために分かったことを箇条書き等でメモする
- 整理した情報をもとに開発ソフトの仕様を決める
機能(アルゴリズム)検討
仕様が固まったら、今度はその仕様を満たすための機能を検討・調査します。具体的には以下のことを検討⇒調査しました。
【調査リスト】
- どうやって画像上の座標(”くるる”の頭)を指定するか?
- どんなアルゴリズムで指定座標を追跡(トラッキング)するか?
- 追跡(トラッキング)座標の方向をどう算出するか?
- 録画中の25秒間は他の操作をロック(排他制御)する方法は?
- 保存した動画ファイルを上書き保存せずに何度も”スサー”を撮るには?
ソフト屋の『調査する』=『徹底的に”ググる”』だと思って問題ないと思います。
…で!検討・調査の結果、以下の機能で仕様を満たせることが分かりました。
【開発する機能(アルゴリズム)】
- マウスクリックで座標(”くるる”の頭)を指定
- オプティカルフローで追跡(トラッキング)
- 指定座標のy方向の移動量を算出
- システムの状態を観測する
- シャッターを切った時間を保存ファイル名に追記する
次は【開発する機能】を実現するための、ソフトウェア設計図(UMLによるモデル図)を作成後、ソースコードを作成するのですが…その前に大事なことを確認しておかねば!!
なるはや…だと!?誰だ”くるる”にこんな恐ろしい言葉教えたやつは!!
「なるはや」とは「なるべく早く」の略で、何が大変って人によって「なるはや」の感覚が違うのだ!2週間以内という人も知れば、1日という人もいる…
今回の開発はスピード勝負!とりあえず3日後の完成を目標に開発を進めます。
- 仕様検討の時点ではアルゴリズムを限定しない方が良いです。アルゴリズムは「手段」であり「目的」ではないからです。視野を広くして、多くのアルゴリズムから最適な機能ものを選択しましょう!
- 納期…コワイ!
ソースコード作成
開発期間が長い場合は、ソフトウェア設計図(UMLによるモデル図)を作りこみ、メンテナンス性・保守性・変更容易性などを考慮した構造やソースコードの振る舞い(動作)をモデル図で確認した後でソースコードを作るのですが…
今回は、もう時間がないので…いきなりソースコードを作り始めます!
まずは開発予定のソースコードに近いサンプルソースがないか”ググって”探します。
あった!開発者様ありがとう!!参考元ソースコードで機能の❶~❷は実現できます。
残りの機能も参考ソースコードをベースに作りこみます。…で完成したソフト”Animal_Cam.py”が以下です。
Anaconda 5.2 / Python 3.6.1 / OpenCV3.4.1で動作確認しました。
以降からの説明は「ソフトウェア設計の勉強に関する内容」なので、一度ソースコードをコピーして、ソースコードを別ウィンドウに表示させて、本記事と見比べながら学習を進めると効果的です(*・ω・)ノ♪
Animal_Cam.pyのポイント
参考ソースコードと同じ部分は説明を割愛し、改造(追記)した部分のみ説明します。
【変更点】
- コード3~4行目:タイマーと列挙型のライブラリをimport
- コード6~9行目:システムの状態を定義
- コード32行目:出力ウィンドウを追加
- コード46行目:動画保存用の変数を追加
- コード93~132行目:状態遷移図の実装
- コード145~153行目:録画処理
(Gitでソフトをバージョン管理すると変更点が簡単に確認できるけど、Gitがよく分からない人のために、今回は手書きしました。Gitってツールがあることは覚えておいてね!)
➎状態遷移図の実装 以外は、そんなに難しくないと思います。➎については少々複雑だったので、状態遷移図を書いてから実装しました。状態遷移図を見せる前に…振る舞いについて少し勉強しましょう(*・ω・)ノ♪
システム(ソフトウェア)の振る舞いについて
今回に限らずソフトウェアの振る舞い(処理の流れ)を検討するとき、【行動ベース】か【状態ベース】で考えると”スッキリ”します。
例えば、以下のような『ボタンの色に合わせてライトが点灯するシステム』を作ったとします。

青⇒黄⇒赤の順に”自動でライトを点灯”させたい場合、【行動ベース】と【状態ベース】で振る舞いの考え方が変わってきます↓
【行動ベース】
- 青ボタンが押された⇒黄色ボタンを押す
- 黄ボタンが押された⇒赤色ボタンを押す
となり、システム(ソフトウェア)の振る舞いが行動(アクション)により変化すると考えます。これを表現するのに使うモデル図がフローチャートやアクティビティ図です。
【状態ベース】
- 青ライトが点灯した⇒黄色ボタンを押す
- 黄色ライトが点灯した⇒赤色ボタンを押す
となり、システムの振る舞いが状態(ステート)により変化すると考えます。これを表現するのに使うモデル図が状態遷移図やステートマシン図です。
Animal_Camの振る舞い(状態遷移図)
話を戻して、Animal_Camの状態遷移図を示します。

- ●から始まり、マウスクリックをトリガーに「Wait状態」へ遷移
- オプティカルフローでは直前のフレーム情報を使用するため、フレーム情報を取得するまで「Wait状態」
- フレームの取得をトリガーに、いつでもシャッタが切れる「Ready状態」へ遷移
- ”くるる”の頭が上方向に大きく動いたことをトリガーに「SaveVid状態」へ遷移
- 25sec経過をトリガーに「Wait状態」へ遷移
❶~➎を繰り返す。キーボードの「esc」を押すと、どの状態でもシステムを強制終了させます。
(SaveVidのみ「終了の◎」と接続していますが、本当は全ての状態と◎を接続するのが正解です。ただし、矢印だらけで振る舞いが分かりにくいと、モデル図の意味がなく、実装する人が困るので、今回は「上図+言葉の補足」にしました。)
モデル図の”モデル”とは”本物”に似せたものという意味(例.プラモデル)で、ソフトウェア開発でいうモデル図とは以下の通りです。
- 本物:ソフトウェア(ソースコード)
- モデル図:ソフトウェアの構造や振る舞いを表現した図
今回の開発はスピード重視なので、ソフトウェア構造(クラス図)の作りこみはせず、振る舞い図(状態遷移図)のみ作成しました。
ソフトウェアの振る舞い設計(検討)について
【状態ベース】と【行動ベース】どちらで振る舞いを考えるとスマートか?については、開発するソフトウェア(システム)次第ですが…
今回の場合は、「マウスクリック」・「シャッターを切る」という行動で考えるより、「録画中(SaveVid)」という状態で考えた方がスマートだと考えました。
行動のみで考えると、シャッターを切る瞬間は把握できるけど、録画を終了したタイミングがわかりにくい。
この状態遷移図(モデル図)に基づき以下のコードを実装しました。
❷コード6~9行目:システムの状態を定義
➎コード93~132行目:状態遷移図の実装
状態遷移図の実装ポイントは以下の通りです。
- 状態は列挙型で定義するとスマート
- 状態遷移はswitch文で書くとスマート※
- トリガーが発生するまでは、今の状態を維持する
- トリガーが発生したら、次の状態に遷移する
※pythonなどswich文が書けない場合はif文で代用する
状態遷移図などソフトウェアのモデル図を書く作業を『ソフトウェア設計』と呼び、モデル図…言い換えれば、設計図に基づきソースコードを書く作業を『コーディング(実装)』と呼びます。(設計図なしでコーディングする場合もあります。)
「設計はできるけどコーディングができない人」や「コーディングはできるけど設計ができない人」など色んな人がいますが、各チームメンバーの長所/弱点を考慮して、上手に仕事する現場が多いと思います。
ただし…設計・コーディング両方できるとカッコイイので…
今回はカメラシステムだけど、ロボットなどのソフトウェア開発でも使えるテクニックなので、覚えておいて損はないと思いますよ!
Animal_Cam.pyの試験(使い方含む)
完成したソフトが上手く動作するか試験します。
”Animal_Cam.py”に対する入力インターフェース(キーボード・マウス)の操作は参考ソースコードと同じでなので割愛し、追加した機能について説明します。
以下 試験手順
”くるる”の前に定点カメラを設置(私はノートPC内蔵カメラを使用しました)
ターミナルから以下のコマンドで”Animal_Cam.py”を起動
python Animal_Cam.py
「motion」と書かれたウィンドウ内の”くるる”の頭をマウス左クリックし、黄色い点が付いたことを確認する。

ターミナルの表示が「State:Wait」から「State:Ready」に変わった(状態が遷移した)ことを確認後…4時間ほど昼寝して待ちます。
私が寝ている間に、くるるが”すさー”すると「State:Wait」が「State:SaveVid」に状態遷移し、Animal_Camが録画を開始します。(Visual Studio Codeのターミナルです)

録画中は”くるる”が何をしても25秒間の動画ファイルを生成します。
Animal_Cam.pyと同じ階層に”output_vid”というフォルダを作ってください。そこに動画ファイルが保存されます。(この作業は最初の1回だけで大丈夫です)
目が覚めたらキーボードの「escキー」を押してAnimal_Camを終了させ、ニヤニヤしながら動画ファイルを確認します(・∀・)ニヤニヤ
Visual Studio CodeからAnacondaのターミナルを使う方法が気になった人は以下の記事を確認!

Animal_Cam.pyの改良
実は1回目の昼寝1回目の試験では、動画ファイルを大量に生成してしまい、かつ”スサー”は撮れていませんでした(´・ω・)
開発機能『➌指定座標のy方向の移動量を算出』の実装はコード102~105行目で、当初は”くるる”の頭がy方向+5pixel移動したらシャッターを切るという設定でした。
しかし、これだと感度が良すぎて、”スサー”以外の小さな動きにも反応してしまいました。
なので、y方向+8pixel移動したらシャッターを切るように105行目のコードを修正!
if fy_diff >= 8.0:
この”8.0”というパラメータを決定するためにも、簡単な試験を実施してました。
以下 パラメータ調整試験の手順
コード106~109行目で移動量などのパラメータをターミナルに表示させ、映像を見ながら、微調整
また、コード119行目が「SaveVid状態」に遷移させるコードなのですが、パラメータ調整試験の最中は録画状態に遷移してほしくないので、この部分をコメントアウト
# state = State.SaveVid.value
これでずっと「Ready状態」をキープできます。
きっちり『状態遷移図を設計⇒実装』という流れでソフトウェア開発を実施すれば、ある状態だけテストするなども簡単に実施できます。
Animal_Cam.py完成!
普段はほとんど動かないフクロウ”くるる”の動く映像だけが撮れる奇跡のカメラができました!
多数撮れたものから、希少映像をピックアップして大公開!
【タイトル:スサーからのエンジェル!!】
あの両羽を伸ばす行動は”エンジェルポーズ”というそうです(鳥業界の常識!)
大喜びで動画を何度も再生する”くるる”マジ天使!!
【タイトル:ダンス!ダンス!ダンス!】
フクロウは眼も耳も良く、危険予知を怠りません!それにしても、すごい遠くのカラス・ぬいぐるみ・飛行機にも反応するので、”くるる”はフクロウの中でも”ビビり”なのかも(?)
…え?『動物の行動観測カメラ』か『録画機能付き物体追跡カメラ』とかにしようかと…
まぁ名前なんて、なんでも良いか!今回は『動物の行動観測用』として、本ソフトを開発しましたが、様々な用途に使えると考えています。なので…色々と遊んでみて下さい!
また、『(移動量や方向などの)パラメータ変更』・『状態の追加』などの改良を行い…
という人が現れたら最高に嬉しいです(*・ω・)ノ♪
まとめ
長文読解お疲れさまでした。本記事を最後まで読んでくれた人は以下のことを学べたと思います。
- ソフトウェア開発プロセス
- ソフトウェア設計手法
- 状態遷移図の書き方と実装方法
- カメラシステム開発の面白さ(←伝わってほしい!)
❶については現場によって開発手法が変わるので、一例だと思ってくださいな。
また、今回の開発期間は3日間(内訳:調査/検討1日・設計/実装1日・試験/改良1日)で、費用も発生しないため、スケージュールはあってないようなものでした。
本来なら、ここに費用・日程・投入する人数などの工数を計画してから、開発作業にとりかかるのですが…
本記事では、スケジュールに関する説明を割愛しました。ただし、大事なことなので興味のある人は『開発手法』を勉強してみてください。(基本情報技術者試験にも出ますよ)
本記事は『ソフトウェア開発の流れを雰囲気だけでも伝えたい!』という想いで書きました。チュートリアルの題材は『”スサー”カメラ』じゃなくても良かったけど…自分の好きなものじゃないと熱量たっぷりの記事を書けない気がしたので、私の好きな題材を選びました!笑
本記事を読んで…
という人が少しでもいたら嬉しいなぁ(*・ω・)ノ♪
(完)
おまけ -メッセージとおすすめの書籍-
時間に余裕のある人は読んでみてね↓
メッセージ
”くるる”ちゃん 本当に何度も”スサー”動画見てるよ…楽しいのかな?
そんな可愛い”くるる”の頭を撫でると動画を見るのを止めて喋りだした
はい!仕事ではバリバリ設計図(モデル図)書いてますᕦ(ò_óˇ)ᕤ
まぁプライベートでは設計しないで、ちゃちゃっとソフト作ることが多いので”くるる”が知らなくても無理はない。
ただ、ちょっと複雑なアルゴリズムになると今回のように振る舞い(フローチャートや状態遷移図)を書くことがあります。
「開発手法」・「ソフトウェア設計」・「実装(プログラミング)」は、どれも本当に重要かつ内容が濃いため、各項目を説明した”良質な記事”や”書籍”は沢山あります。
ただ、少し内容が薄くても3項目をコンパクトにまとまった記事が書けないかなぁと思い、本記事【ソフトウェア開発入門】のチュートリアルを書きました。
長文だし勉強なので、眠くなる人もいると思い、飽きないような文章にしたつもり…
本記事の内容だけでは、全然足りないことは重々承知していますが、参考になると嬉しいなぁ
プログラミング言語の修得だけでなく、ソフトウェア設計や開発手法にも興味を持ってくれる人が増えると嬉しいなぁ(*・ω・)ノ♪
くるるは今日も良い子でした!笑
おすすめの書籍
うずうず…”くるる”が羽毛を揺れしながら呟く
はい!「もっと勉強したい!」というモチベーションの高い人のために以下の本を紹介!
UML徹底活用
本記事では、状態遷移図しか紹介できませんでしたが、その他のモデル図(ソフトウェア設計図)についても丁寧に説明している良本です。図解も多いので、文字だらけの説明資料が苦手な人にもオススメできます。ソフトウェア設計図について学ぶなら、こちらの本が一押しです。
組込みソフトウェア開発のための構造化モデリング
ソフトウェア設計手法には様々なものがあり、組み込みの現場だと『構造化モデリング』という設計手法を採用することがあります。この本は「話題沸騰ポット」の開発を題材に『構造化モデリング』について説明する良本です。
組込みソフトウェア開発のための オブジェクト指向モデリング
上の本と同じシリーズの本です。この本では『オブジェクト指向』という設計手法について説明しています。上の本と同様に、「話題沸騰ポット」の開発を題材に『オブジェクト指向』について説明する良本です。『オブジェクト指向言語』なんて呼ばれるプログラミング言語もあります。組み込み現場はもちろん、その他の現場でも使える一冊です。
モダンC言語プログラミング
C言語は歴史あるプログラミング言語ですが『オブジェクト指向』には向いていない・修得が難しいという理由から初心者から嫌われている印象…。しかし、現場ではC言語がバリバリ現役なところも多いです。『C言語だってモダンなプログラミングができるぜぇ』を説明してくれる良本。本記事の状態遷移図の実装では、この本が大変参考になりました。
プログラミング言語を修得したら、次はソフトウェア設計手法を修得するのはいかがですか?設計スキルを修得して、設計も実装もできるカッコイイ技術者を目指そう!
(完)