ochalog

Ruby と MediaWiki が好きな電子・情報系の学生のブログ。

SICP:問題2.17

とても久しぶりにSICPの問題をやってみた。前回の問題から飛んでいるけど(一応間の問題も解いてはある)、今回初めて使ってみたGauche単体テストでの確認が便利だったので、思わず先に書いてしまった。

ochaochaocha3.hateblo.jp

問題 2.17

与えられた(空でない)リストの最後の要素だけからなるリストを返す手続き last-pair を定義せよ:

(last-pair (list 23 72 149 34))
(34)

計算機プログラムの構造と解釈 第二版 2.2.1 並びの表現」より

length と同じようにリスト全体の cdr ダウンで。Schemeの組み込みライブラリに同名の手続きが入っているので、my-last-pair という名前にした。

(define (my-last-pair items)
  (if (null? (cdr items))
    items
    (my-last-pair (cdr items))))

gauche.testを使ったテスト

ところで、今まではテストを手でやっていたのだけど、試すときに使っていたGauche単体テストのライブラリgauche.testが含まれていることを知り、今回初めて使ってみた。

上の手続きをex-2-17.scmというファイルに入れ、以下の内容のex-2-17-test.scmというファイルを作った。

;; 問題2.17のテスト

(use gauche.test)
(test-start "問題2.17")

(load "./ex-2-17.scm")

(test "要素数1の場合"
      (list 1)
      (lambda () (my-last-pair (list 1))))

(test "問題文の例"
      (list 34)
      (lambda () (my-last-pair (list 23 72 149 34))))

(test-end :exit-on-failure #t)

実行すると以下のように出力され、テストが成功したことが分かる。

$ gosh ex-2-17-test.scm
Testing 問題2.17 ...
test 要素数1の場合, expects (1) ==> ok
test 問題文の例, expects (34) ==> ok
passed.

テストが失敗するように、わざと以下のテストケースを入れるとどうなるか。

(test "絶対失敗する!"
      (list 23)
      (lambda () (my-last-pair (list 23 72 149 34))))

出力はこのようになり、失敗した場合の結果が分かりやすく表示された。

$ gosh ex-2-17-test.scm
Testing 問題2.17 ...
test 要素数1の場合, expects (1) ==> ok
test 問題文の例, expects (34) ==> ok
test 絶対失敗する!, expects (23) ==> ERROR: GOT (34)
failed.
discrepancies found.  Errors are:
test 絶対失敗する!: expects (23) => got (34)

かなり便利なので、今後答えがはっきりと決まる問題を解くときには、積極的に使っていきたい。

MroongaをTravis CIのVM上のUbuntu 14.04で動作させる

今年の9月に入ったあたりから、全文検索用のMySQLストレージエンジンMroongaを使っているRailsアプリ*1Travis CIでのテストが、エラーにより実行できなくなった。ログを調べてみると、Travis CIのVM上で動作しているUbuntu 14.04へのMroongaのインストールに失敗し、そこで止まっていたことが分かった。

その後なかなか時間が取れず放置していたが、先日試行錯誤したところ、Mroongaのインストールに成功し、テストを実行できるようになった。今回はその際の修正方法をまとめてみる。

原因

原因は、Travis CIのVM上のUbuntu 14.04に標準でインストールされているMySQLと、MroongaのUbuntu 14.04用のパッケージが要求するMySQLのバージョンが異なることだった。前者は5.6系で、後者は5.5系となっていた。

ログ(例:Job #416.4 - cre-ne-jp/log-archiver - Travis CI)の該当部分は以下のようになっていた。

Build system information
(中略)
mysql version
mysql  Ver 14.14 Distrib 5.6.33, for debian-linux-gnu (x86_64) using  EditLine wrapper

(中略)

$ sudo apt-get install -y -V mysql-server-mroonga
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 mysql-server-mroonga : Depends: mysql-server-5.5-mroonga (= 7.06-2~trusty1) but it is not going to be installed
                        Depends: mysql-server (= 5.5.57-0ubuntu0.14.04.1) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

対策

対策として、標準でインストールされているMySQL 5.6をアンインストールし、Mroongaのパッケージが要求するMySQL 5.5をインストールできるようにすることが浮かんだ。問題発生前はVM上でMySQL 5.5のインストールされているUbuntu 12.04が動作していて、mroonga-server-5.5-mroonga パッケージが問題なくインストールできていた。

Mroongaのインストール手順

以下では.travis.ymlの before_install: 欄に書く内容を示す。

まず、Mroonga公式のUbuntu向けインストール方法の説明にしたがって、パッケージのインストールのための準備を行う。

universeリポジトリとセキュリティアップデートリポジトリを有効にする。

sudo apt-get install -y -V software-properties-common lsb-release
sudo add-apt-repository -y universe
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu $(lsb_release --short --codename)-security main restricted"

ppa:groonga/ppa PPAをシステムに追加する。

sudo add-apt-repository -y ppa:groonga/ppa
sudo apt-get update

通常は以上の準備の後 mysql-server-mroonga パッケージをインストールするが、ここでMySQL 5.6関連のパッケージをアンインストールする。アンインストール手順については、Benjamin Morel氏のGist「Install MySQL 5.7 on Travis-CI」を参考にした。

sudo apt-get remove --purge "^mysql.*"
sudo apt-get autoremove
sudo apt-get autoclean
sudo rm -rf /var/{lib,log}/mysql

これでMySQL 5.6関連のパッケージとデータがすべて除かれるので、MySQL 5.5系がベースになっている mysql-server-mroonga パッケージをインストールすることができる。

sudo apt-get install -y -V mysql-server-mroonga

ただ、このパッケージだけでは開発用のヘッダファイルがインストールされず、後に mysql2 gemのインストールで失敗してしまう。そのため libmysqlclient-dev を忘れずにインストールしておく。念のため、上記のパッケージの後でインストールするようにし、互換性のあるバージョンが確実に選ばれるようにした。

sudo apt-get install -y -V libmysqlclient-dev

ここまでの手順はシェルスクリプトにまとめておいた。

テスト用のMySQLアカウントの変更

Travis CIのVMに標準でインストールされているMySQLでは travis ユーザーが使えるように設定されているので、テスト時はそのユーザーを使うようにアプリ側で設定されているかもしれない。新しく入れたMySQLではそのような設定はされていないので、以降のテストでデータベースに接続できなくなる可能性がある。

そこで、テスト時に travis ユーザーを使うように設定している場合は、そのユーザーを用意するか、使わないようにする。今回はとりあえず root にパスワードなしで接続するように設定を変えたが、セキュリティ面ではよくないかもしれない。

Mroongaのインストール成功

以上の対策を行った結果、Mroongaのインストールに成功し、テストが無事実行できるようになった。

例:Job #434.4 - cre-ne-jp/log-archiver - Travis CI

まとめ

Travis CIのVM上のUbuntu 14.04では、Mroongaのインストールに失敗してテストが停止してしまう。その原因は、標準でインストールされているMySQLとMroongaのUbuntu 14.04用のパッケージが要求するMySQLのバージョンが異なることだった。

標準でインストールされているMySQL 5.6関連のパッケージをアンインストールした後でMroongaをインストールするという対策により、問題を解決することができた。

*1:irc.cre.jp系IRCサーバ群で使われているIRCログ記録・閲覧システム「log-archiver

研究分野への興味の喪失

夏休みに入り、興味を持ったソーシャルデータの分析の研究室の先生とお会いしてお話を伺った。その後、提出しなければならない修士課程の研究計画書を書くために調査をしていたが、調べているうちに興味がなくなってきた。

先生との面談の際には、ここ何年かの実習で災害についての情報を扱う機会が何回かあったこともあり、ソーシャルメディアへの投稿から災害についての情報を検出し、物理センサを補完するような仕組みを作りたいと伝えた。特にこの時期に多く起こる豪雨災害を対象にしようと考えていた。そのまま話が進んだので、研究計画書を書くためにさらに調査を進めたが、調べていくと成功する見込みが少ないと感じられるようになった。

例えば代表的なソーシャルデータであるツイートを収集するボットを作るのは今からすぐにできると思う。作っていたIRCボットのcre-ne-jp/rgrbTwitter gemを使っている経験があるから、APIについて調べて利用し、得られたデータを整形すれば良いだろう。自然言語処理を利用した必要なデータの抽出も、頑張って勉強しながらなんとかできるようになりそうだとは思った。その後の他データとの比較は、時刻や位置情報に注目しながら地道にやっていくことになるだろう。

問題はテーマに当てはまる投稿がそもそもあるのかどうか。調べていくうちに、これが心配になってきた。

最近の関連研究はほとんどない。東日本大震災の直後は結構多いように見えたが、最近は下火になっているようだった。これは興味を持っている人が少ないか、やってみたが成果がほとんどないということを示しているように感じられた。

それなりに上手くいっていそうな例は、早稲田大の「人間科学研究」に載っていた、服部による「位置情報付きツィートから事象 (自然現象・異常気象)・災害を可視化する手法の開発」だけだった。ただ、修士論文の要旨なので詳細は分からなかった。

他に、災害情報No. 14(2016)に掲載された潮崎・牛山による「豪雨時における災害危険度の高まりを推定するための電話通報数の活用について」の参考文献に載っていた、影澤らによる「Twitterを用いたセンシングシステムの提案と考察」(「マルチメディア、分散協調とモバイルシンポジウム2014論文集」に掲載)が気になったが、人が多い新宿でも降雨初期のツイートが数件というのを見て愕然とした。一応降雨を検出できたことになっているが、1時間に少なくとも数千件のツイートを収集しているのに対象ツイートがこの件数になるというのでは、多少のシステムの改良ではどうしようもないほど関連するツイートの絶対数が少ないということではないだろうか。

さらに同じ日に読んだ2015年関東・東北豪雨災害土木学会・地盤工学会合同調査団関東グループによる調査報告書を読んでより悲観的になった。p. 135の「避難情報の入手手段」の図の「SNSTwitter、LINE、Facebook等)」の割合が0.4%(N = 516)というのは、要するに、そんな大災害のときに呑気にSNSに興じているような人はほとんどいないことを示していると思われた。一応「入手手段」なので投稿数もそれくらい少ないとは限らないが、平時に近い上の新宿の場合と比べれば、非常時には普通は減るだろう。また、別の豪雨災害の2014年広島豪雨は深夜に酷い被害が出たことから、そのような場合もSNSへの投稿はほぼなくなるだろうと推測した。

というわけで、ここ数日集中して調べた限りでは、豪雨災害を研究対象とすると投稿のサンプルが集められずに挫折する可能性が高いという予想になった。そのため、自分はこのテーマに賭けようという気持ちになれなかった。

他には研究室の本流らしい観光に関連したデータの抽出が流行っているようだったが、利用者に合わせた推薦の手法の提案ばかりで、差別化が難しいと感じた。あまり興味が持てなかったこともあり、今は独自のテーマが浮かびそうにない。


当初は個々の技術がおもしろそうだと思っていたが、適用できそうな範囲の狭さを知り、ソーシャルデータの分析への興味がなくなってきた。代わりの案はまだ浮かんでいない。

gstreamermmでGStreamerのチュートリアル1

卒研で使うThe Imaging Source社の産業用カメラをLinuxで制御する1ためにマルチメディアフレームワークGStreamerを使うことになりそうなので、その練習をしている。

卒研ではOpenCVと組み合わせる予定なので、C++で書けると扱いやすい。GStreamerはC言語で書かれたライブラリだが、C++ラッパーのgstreamermmが用意されているので、これを使うことにした。

GStreamer公式の説明ページにはチュートリアルがいくつか用意されている。今回は最初のチュートリアル1を、gstreamermmを使って書いてみた。

開発環境

ライブラリのインストール

Homebrewを使って必要なライブラリをインストールした。

サンプル動画を再生するために、libvpxおよびlibvorbisとのリンクが必要。また brew link --force gettext が必要になる。これを行わないと、書いたプログラムのリンクの際に「libintlが見つからない」というエラーが出た。後に問題が発生したら brew unlink gettext を行う必要があるかもしれない。

brew install pkg-config gstreamer gst-plugins-good gettext
brew install gst-plugins-base --with-libogg --with-libvorbis
brew install gst-plugins-bad --with-libpng --with-libvpx
brew link --force gettext

ソースコード

CMakeLists.txt

CMake 簡易まとめ」を参考にした。

cmake_minimum_required(VERSION 3.0)
project(tutorial CXX)

find_package(PkgConfig)
pkg_check_modules(GSTREAMERMM REQUIRED gstreamermm-1.0)

set(CMAKE_CXX_FLAGS "-std=c++11 -Wall")
set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0 -pg")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s -DNDEBUG -march=native")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g3 -Og -pg")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -s DNDEBUG -march=native")

add_executable(tutorial01 tutorial01.cpp)
target_include_directories(tutorial01 PUBLIC ${GSTREAMERMM_INCLUDE_DIRS})
target_link_libraries(tutorial01 ${GSTREAMERMM_LIBRARIES})
target_compile_options(tutorial01 PUBLIC ${GSTREAMERMM_CFLAGS_OTHER})

tutorial01.cpp

チュートリアルのコードをgstreamermmを使って書き直した。

#include <gstreamermm-1.0/gstreamermm.h>

int main(int argc, char* argv[]) {
  // GStreamerを初期化する
  Gst::init(argc, argv);

  // パイプラインを構築する
  Glib::RefPtr<Gst::Element> pipeline = Gst::Parse::launch(
    "playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm"
  );

  // 再生を開始する
  pipeline->set_state(Gst::STATE_PLAYING);

  {
    // エラーまたはEOSまで待つ
    Glib::RefPtr<Gst::Bus> bus = pipeline->get_bus();
    Glib::RefPtr<Gst::Message> msg = bus->pop(
      Gst::CLOCK_TIME_NONE, Gst::MESSAGE_ERROR | Gst::MESSAGE_EOS
    );
  }

  // リソースを解放する
  pipeline->set_state(Gst::STATE_NULL);

  return 0;
}

C言語で書かれたチュートリアルのコードは以下のとおり。

#include <gst/gst.h>

int main(int argc, char *argv[]) {
  GstElement *pipeline;
  GstBus *bus;
  GstMessage *msg;

  /* Initialize GStreamer */
  gst_init (&argc, &argv);

  /* Build the pipeline */
  pipeline = gst_parse_launch ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);

  /* Start playing */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* Wait until error or EOS */
  bus = gst_element_get_bus (pipeline);
  msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

  /* Free resources */
  if (msg != NULL)
    gst_message_unref (msg);
  gst_object_unref (bus);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  return 0;
}

ビルド

CMakeの慣習に従い、buildディレクトリを作ってその中でビルドする。

cd /path/to/tutorial01
mkdir build
cd build
cmake ..
make

実行

ビルドしたら以下のコマンドで実行することができる。

./tutorial01

実行するとウィンドウが表示され、https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm の再生が始まる。最後まで再生されると終了する。

f:id:ochaochaocha3:20170808235748p:plain

C言語で書かれたものとの違い

生ポインタの代わりにGlib::RefPtrを使う

例えば GstElement * 型が返る関数のgstreamermm版では Glib::RefPtr<Gst::Element> が返る。

Glib::RefPtr(リファレンス)はglibmmが提供する参照カウンタ式のスマートポインタクラスで、C++11のstd::shared_ptrに似ている。デストラクタでカウントが1減り、0になったときにリソースが解放される。このスマートポインタのおかげで、gst_object_unref() に相当する ->unreference() を呼び出さなくてもよくなる。

上のコードではポインタを使用する範囲をブロックにした。ブロックを抜ける際にデストラクタが呼ばれ、C言語版とほぼ同じ場所で ->unreference() が呼ばれることになる。

一部の関数のインターフェースが異なる

多くの関数のgstreamermm版はC言語版からの規則的な変換で書けるが、一部インターフェースが異なるものがある。上の例だと、gst_bus_timed_pop_filtered() に対応する関数は Gst::Bus::pop(Gst::ClockTime timeout, Gst::MessageType message_type) と、オーバーロードを利用したものになっている。

一つ一つドキュメントから探していけば良いのだが、インターネットでは現在の最新版1.8.0のドキュメントのページが空になっているため、少し不便になっている。gstreamermmをHomebrewでインストールした場合は /usr/local/opt/gstreamermm/share/doc/gstreamermm-1.0/reference/html/index.html からDoxygenで生成されたドキュメントを見ることができた。未確認だが、Linuxではlibgstreamermm-1.0-docのようなパッケージをインストールすれば閲覧できそうだ。

感想

常にリソース管理に注意しなければならないC++なので、スマートポインタでリソースの解放し忘れが減ることが嬉しい。慣れていないのでまだドキュメントを何度も見ているが、もともとGStreamerがオブジェクト指向で書かれているので、対応するgstreamermmの関数を見つけるのは難しくなかった。個人的にはC++11以降の書き方が気に入っていて、できるだけC++で書きたいと思うので、今後も積極的にgstreamermmを使っていきたい。


  1. 制御するためのLinux用ライブラリがGitHubで公開されている:
    https://github.com/TheImagingSource/tiscamera

2016-11-18 の日記

「標準課題」というグループ課題で、友達の班に「C言語でメールを送れるようにしたい」という要望があった。おもしろそうだったので、放課後に実験を一緒にやってみた。

構成

学校にはファイアウォールがあってインターネット上のSMTPサーバに直接アクセスすることができないようだったので、とりあえず課題用に配られたRaspberry PiSMTPPOP3/IMAPサーバとすることにした。Raspberry Piにユーザーアカウントを作り、Maildirにメールが届くようにする。

前提

ユーザーアカウントは事前に作ってあり、ログインできるものとする。なければ useradd -m someone で作っておく。

Postfixのインストールと設定

Raspbian Jessieを使っていたので、Debian 8での設定手順がそのまま使える。「Debian 8 Jessie : MAILサーバー : Postfix インストール/設定 : Server World」を参考にした。実験用で外に出すつもりがなかったし、時間の余裕があまりなかったので、以下の点は変えた。

  • インストール中、構成のプリセットの選択で「ローカルのみ」を選んだ。
  • 容量制限やSMTP-Authの設定をしなかった。

SMTPサーバの確認

初めにmailutilsを入れてmailコマンドを使えるようにした。

sudo apt-get install mailutils

また、RaspbianではMAIL環境変数が設定されていなかったようなので、以下の内容で /etc/profile.d/mail.sh を作ってログイン時に設定されるようにした。

export MAIL=$HOME/Maildir

反映させるため、一旦ログアウトして再度ログインする。

続いてsendmailコマンドで自分宛てにメールを送った。

sendmail ocha@example.org
# 以下は標準入力
From: ocha@example.org
To: ocha@example.org
Subject: Hello

Hello world!
.

送信後、mailコマンドで確認すると、送ったメールが届いていた。

C言語でメールを送るプログラムを作る

sendmailコマンドを呼び出して標準入力に書き込めばメールを送信できたので、popen(3)でそれを行う。エラー対策等は厳密ではないので注意。

/*
 * send-hello.c
 */

#include <stdio.h>

int main(int argc, char* argv[]) {
  if (argc != 3) {
    fprintf(stderr, "Usage: %s NAME ADDRESS\n", argv[0]);
    return 1;
  }

  char* name = argv[1];
  char* address = argv[2];

  char sendmail_command[256];
  snprintf(sendmail_command, sizeof(sendmail_command),
           "sendmail %s", address);

  FILE* sendmail = popen(sendmail_command, "w");
  if (sendmail == NULL) {
    perror("popen");
    return 1;
  }

  fputs("From: ocha@example.org\n", sendmail);
  fprintf(sendmail, "To: %s\n", address);
  fputs("Subject: Hello\n\n", sendmail);
  fprintf(sendmail, "Hello, %s!\n", name);
  fputs(".\n", sendmail);

  pclose(sendmail);

  return 0;
}

使うときはこのような形で。

./send-hello ocha ocha@example.org

Dovecotのインストールと設定

最後にPOP3/IMAPサーバとしてDovecotをインストールして、メールソフトから受信したメールを見られるようにした。Postfixと同様に「Debian 8 Jessie : MAILサーバー : Dovecot インストール/設定 : Server World」を参考にした。

PCのThunderbirdIMAPサーバとしてRaspberry PiIPアドレスとポート番号143を指定して、上のプログラムを使って送信したメールを受信できることを確認した。

感想

調べながら作業を行ったので時間がかかったが、要点を押さえればそれほど複雑ではない印象だった。

sendmailコマンドはなかなか便利。ちょうど学校でプロセス関連のシステムコールやライブラリ関数の使い方を習った後だったので、良い応用例だった。Raspberry Piなら、ハードウェアの制御と合わせればおもしろいものができそう。

HHVMのコンパイルエラー対策

スーパーロボット大戦Wiki等のMediaWikiを動かすためのHHVMを3.14.2に更新しようとしたときに、まずCMakeで失敗した。これはサブモジュールを再帰的にすべてダウンロードできていなかったためで、以下のコマンドを実行することで次に進めた。

# gitでcloneしたHHVMのディレクトリで
rm -rf third-party
git submodule update --init --recursive

しかし、その後makeするとコンパイルエラーが起きて止まってしまった。コンパイルに失敗するのは hphp/hack/src/server/serverError.ml で、探してみたところ以下のissueが見つかった。

Fixed Datetime comparison with milliseconds involved by wjzijderveld · Pull Request #6888 · facebook/hhvm

新しいバージョンではだめなのかと3.14.1等バージョンを戻して試してみるもどうもうまくいかない。さらに探してみると、以下のissueが見つかり、そこに衝撃の事実が。

jwatzman commented on 31 Dec 2015

ocaml's build systems are terrible when it comes to incremental builds. Can you try rm -rf hphp/hack/src/_build and try again?

Error: Unbound value ServerMonitor.start_monitoring · Issue #6701 · facebook/hhvm」より

訳すと「OCamlのビルドシステムはインクリメンタルビルドになるとひどい。rm -rf hphp/hack/src/_build をやってもう一度試してもらえる?」といったところか。こんな罠は知らなかった…

というわけで、上記のとおりにできたファイルを削除してもう一度ビルドをかけたらすんなり進んだ。しかし3コアのVPSではビルドにかなり時間がかかるようで、2時間弱も待つことに。

OSC 2016 Nagoyaに出展します

2016年5月28日(土)に開催されるオープンソースカンファレンス2016 Nagoyaの浜松職業能力開発短期大学校ブースにて、避難所支援システム「避難所てだすけくん」の展示を行います。

続きを読む

どどんとふの CGI 処理:トップレベル

TRPG のオンラインセッション環境「どどんとふ」の CGI 処理についての解説。前回はこちら。

ochaochaocha3.hateblo.jp

今回からサーバープログラムが書かれている DodontoFServer.rb(コミット 94c3c04)を見ていく。

続きを読む

どどんとふの CGI 処理(構成・インターフェース)

最近は TRPG のオンラインセッション環境どどんとふのソースを読んだり変えたりしていることが多い。TRPG.NET ではオンラインセッションが多く行われる夜間に結構重くなるので、負荷を下げることを目標としている。ソースコードの規模が大きいので、テストコードを追加しながら機能単位での分割などを行い、改善点を見つけやすくしたり部品の再利用を行いやすくしたりしている。

今回から、備忘録を兼ねて、これまで調べたどどんとふの CGI 処理について数回書く。コードへのリンクは ver. 1.47.24 リリース時のコミット 94c3c04 を使うことにする。

続きを読む

2016-04-22 授業日誌

1〜3限

Java等の先生の出張により、まるまる画像処理の時間に。以下のように結構多くのことをやった。

  1. OpenCVの開発環境構築
  2. Webカメラから取り込んだ画像をリアルタイムでウィンドウに表示する
  3. 光とか色とか行列とか基礎事項
  4. 行列演算
  5. 色の分解

OpenCV、グラフィックまわりを手軽に扱えるのでなかなか便利そう。標準課題という今年の後半で行うプチ卒研くらいの量の実習でも使うとのことなので、いろいろと試してみたい。

ところでこの時間のレポートはExcelに全部貼り付ける形で、水曜日のものといい本質的でない部分に時間がかかるので最後は少しうんざり。内容は面白いのだけれど。