2017年2月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28        

Amazonウィジェット

  • miniPC
  • 最近買った本
  • Raspberry Pi
  • クアッドコプター
  • 書籍ランキング

AdSense

  • 広告
無料ブログはココログ

« 2016年11月 | トップページ

2016年12月

2016年12月11日 (日)

C++ VisualStudio2013を使ってopenCVのプロジェクトを簡単に試す

最初にVisualStudioに出会った頃はCDが入ったパッケージ版しかなく(6.0とかそれくらいのころ)、もっぱらLCCとかcygwinに入っているgccとかを使ってチマチマとしたプログラムを書いていました。

今は全部VisualStudio+たまにVimとか使うのですが、一旦VisualStudioの便利さを知ってしまうと、なかなか他のツールには手を出そうとは思わなくなりました。

VisualStudioを使っていてもちょっと大変なのは、openCVを使ったプログラムで、これのライブラリの設定については沢山HPがあるのですが、どれもこれもバージョンが少し違ったりするだけで画面が変わったり、パスがちょっと変更になったりで、なかなか載っている通りにはいかんです。
いまはNuGetパッケージという大変便利なものがあって、ボタンひとつでセットアップが完了します。
この記事は、このサイトを見て試した結果を書いています。

そのまんまopenCV3.0を入れてみたのですが、
なぜかopenCVの中で使っている関数がエラーを起こしてうまく行きませんでした。

そこで2.4.10を入れなおしてみました。
インクルードのパスが少し変わっていて、下記のように書くといけました。

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

このサイト
の、5.1のソースを使ってテストしました。




2016年12月 4日 (日)

C# イベントを発生させる続編 イベントを使って値を受け渡しする

C#のフォームアプリケーションを作っていると、描画の更新などイベントを使わなければ回りくどかったり、難しい場合がある。イベントを使いこなせても、今度は値を渡したいとか、どこで発生したイベントかを知らせたり、渡した値でハンドラの振る舞いを変えたいとかいろいろ出てくる。

イベントに値を追加して、イベントハンドラでその値を受け取らせたい場合は、クラスを作ってそれを入れ物として値を受け渡せばよい。じつはそういう例がMouseイベントでも見られる。マウスMoveはEventArgsではなく、マウスの座標をイベントオブジェクトの中に入れ込んだMouseEventArgsという型をやり取りしている。

MouseEventArgsをMSDNを調べてみると、EventArgsというクラスを継承して作られていることがわかる。

https://msdn.microsoft.com/ja-jp/library/system.windows.forms.mouseeventargs(v=vs.110).aspx

つまり、これと同様にしてEventArgsを継承したクラスを用意し、そのクラスに好きな値を持たせればよいことになる。

※マウスイベントの試し方:pictureBoxやパネルの中にあるマウス系イベントのMouseMoveイベントを、フォームデザイナのプロパティで設定してみると、MouseEventHandlerというハンドラが追加されることがわかる。

※手順:pictureBoxをフォームに追加して、プロパティ画面の雷マークを押すと、イベントのプロパティが現れる。この中に、マウスという項目がある。このなかのMouseDownという項目の右をダブルクリックすると、pictureBox1_MouseDownという関数がフォームデザイナでForm内に自動的に追加される。

//色が変化したときにイベントで飛ばすプロパティを入れたクラス
    class ColorEventArgs : EventArgs
    {
        Color c;
        public ColorEventArgs(Color c)
        {
            this.c = c;
        }
        public Color color
        {
            get { return c; }
        }
    }

上記入れ物をイベントに載せて飛ばすためには、
・その型を持ったイベントの宣言
・その型を持ったオブジェクトを受けられるデリゲートの宣言
の2つが必要。

        //イベント
        public event ColorEventHandler CurrentColorChange;

        //ColorEventArgs型のオブジェクトを返すようにする
        public delegate void ColorEventHandler(object sender, ColorEventArgs e);

デリゲートに、イベントが発生したときにやってほしい関数を渡すのを忘れずに。

//イベントで処理する関数を登録
          ceditor.CurrentColorChange += new ColorEditor.ColorEventHandler(this.currentColorChanged);

イベントを発生させるには

        public void setCurrentColor(Color c)
        {
            currentColor = c;
            if (CurrentColorChange != null)
            {
                CurrentColorChange(this, new ColorEventArgs(currentColor));
            }
        }

という風にして、先ほどのイベントを関数のようにして呼ぶ。 そのときに引数として先ほど作ったデータの入れ物型のオブジェクトを作って渡す。

すると、イベントハンドラ先で入れ物を受け取り、そのなかのメンバにアクセスして データを取り出すことができる。この中には、イベントの送り先とかデータを何でも入れられる。 これによりどこが発生させたイベントかを判別することで振る舞いを変えたりできる。

イベントハンドラはこんな風にかける。

        private void currentColorChanged(object sender, ColorEventArgs e)
        {
            colorNum_t num = e.color;
        }

ちなみに、他のイベントハンドラと共用で使いたい場合は、一旦基底クラスのEventArgsで受けておいて、 ほしいクラスのキャストをしてやってもよい。

        private void currentColorChanged(object sender, EventArgs e)
        {
            colorNum_t num = ((ColorEventArgs)e).getColorNum();
        }

イベントを使うとかなり色々なことが出来るようになった気になるが、あまり使いすぎたりあちこちからイベントを発生させたりすると、プログラムの流れが全く読めなくなって困る。

« 2016年11月 | トップページ