大間違い→デストラクタが自動的に呼ばれない
この記事無効です。自分の単純ミスでした。
売り上げランキング: 28,637
気を取り直して自分のミスの暴露記事は下記参照。何卒よろしくお願いいたします。
photo credit: The Arm of Destruction via photopin (license)
テキストを日本語的に傍点(圏点)で強調するJavascript
ふと思いついてテキストに傍点をつけるためのスクリプトを作りましたので、ご紹介。(ソースはGitHubに置いてます)
「傍点」は「圏点」ともいうらしいのですが初耳でした。この文書では以降「傍点」で通します。
「傍点によるテキストの強調」は、CSS3のtext-emphasis
スタイルで定義されていますが、ブラウザによって対応状況が大きく分かれているようなので、このスクリプトを作った次第。
Safari、Chrome等、Webkit系の「傍点対応ブラウザ」では素直にそのままCSSで表現しますが、IEやFirefoxなどの未対応のブラウザでは「ルビ(RUBYタグ)」を利用して、なんとかしました。
ウェブ上で傍点は、あまり使用することがありませんが、強調というよりも単語の区切りをはっきり示すために使いたい事があります。特に、句読点を入れると、文章のリズムに違和感を感じるような場合などですね。
※ ルビに未対応のブラウザでは、かなりおかしな表示になってしまいますが、傍点よりは対応状況が良いようです。2015年11月の時点で、IE、Firefoxの最新版は、全てRUBYに対応してます。Operaはプラグインで対応できると聞きましたが、使用していないので詳しく分かりません。
傍点のスタイル
CSSのtext-emphasis-style
で指定するのと同じ表現が可能です。
style | filled | open |
---|---|---|
dot | 横転 | 好転 |
circle | 争点 | 当店 |
double-circle | 脳天 | 法典 |
sesame | 盲点 | 0点 |
triangle | 栄転 | 経典 |
簡単な適用
class='bauten-text-emphasis'
となった要素に傍点をつけるのなら、bauten.js
を読み込むだけです。この場合は、黒丸(filled dot)付けられます。
要素とスタイルを指定する
傍点を適用する要素や、そのスタイルを指定するには、bauten.jsを読み込んだ後のSCRIPTで、bauten関数を呼び出します。
引数は以下のキーを持つオブジェクトです。
キー | 説明 |
---|---|
className | 傍点を打つ要素のクラスを指定します。複数のクラス名をスペースで区切って指定できます。この場合は全てのクラス名を持つ要素が対象になります。 |
tagName | 傍点を打つ要素のタグ名を指定します。 |
style | 傍点のスタイルを指定します。CSSのtext-emphasis-style と同様の指定方法です。 |
color | 傍点の色を指定します。 |
※ classNameとtagNameのどちらかは指定されなくてはなりません。styleは必須。colorが省略されるとベースの文字色に従います。
※ bauten関数を呼び出した場合、既定の動作は抑制されます。
例:クラス名による指定
例:タグ名による指定
任意の文字を傍点にする
任意の文字を傍点にできます。これもtext-emphasis-style
と同様の機能です。
- たとえばーきみがいるだーけで
- にわにはにわのにわとりがいる。
例
傍点の色を指定する
傍点には色を付けられます。これもtext-emphasis-color
と同等。
ブルー・ノート・スケール(ブルース・スケール、blue note scale)は、ジャズやブルースなどで使われる、メジャー・スケール(長音階)に、その第3音、第5音、第7音を半音下げた音を加えて用いるもの、もしくはマイナー・ペンタトニック・スケールに♭5の音を加えたものである。特に、♭5の音をブルー・ノートと呼ぶ。近代対斜の一種でもある。
例
リポジトリ
SQLiteのSQLのパラメータ化できる箇所
SQLiteのSQLiteDatabase.rawQuery
で、SQLのパラメタライズが、できる場所とできない場所がありまして、調査結果を記しておきます。
「単なる文字列置換」では無いようです(よくよく考えれば当たり前ですね)。
SQLiteDatabase.rawQuery
概要
単純にSQLをそのまま実行するメソッド。SQLのパラメタライズも可能です。
プロトタイプ
Cursor SQLiteDatabase.rawQuery(String sql, String[] paramValues);
引数
使い方例
ざっくり以下のような使い方です。
// android.database. // Cursor // sqlite. // SQLiteOpenHelper // SQLiteDatabase SQLiteDatabase db = openHelper.getWritableDatabase(); Cursor cursor = db.rawQuery( "SELECT id, description, amount, date" + "FROM t_wallet " /* v v */ + "WHERE description like ? AND amount >= ?", new String[] { "'ポテト%'", "100" }); while(cursor.moveToNext()) { int id = cursor.getInt(0); String description = cursor.getString(1); int amount = cursor.getInt(2); byte[] blobDate = cursor.getBlob(3); // ・ // ・ // ・ }
WHERE句の条件にある?
を置き換えています。
条件式などの値を置換できます。
しかし単に文字列置換をしているのではなさそうでして、
【できない】文字列リテラルの中身は置換されない
たとえば、description like ?
の部分を、description like '%?'
とはできません。
あくまでもシングルコーテーションで囲まれている部分は、文字列リテラルとして扱われるので、その中の?
は置換されず、単に?
で終わっているdescriptionを見つけてきます。ただ、第二引数の要素数が合わない場合は例外が投入されます。
【できる】式の一部の置換はOK
以下のように、式の一部は、置換できます。
rawQuery( "SELECT id FROM t_wallet " + "WHERE amount >= ? + 30", /* OK */ new String[] { "100" })`
※ これ、当初「できない」としていましたが、できました。別の要因で例外が出ていたのかも。すみません。
また、以下のように、単独の値でなくてもOKです。
rawQuery( "SELECT id FROM t_wallet " + "WHERE amount >= ? + 30", /* OK */ new String[] { "(80 + 20)" })`
ところが、次のは駄目でした。「構文エラー」になります。
rawQuery( "SELECT id FROM t_wallet " + "WHERE amount >= ? ) + 30", /* NG */ new String[] { "(80 + 20" })`
?
を式として扱って、第1引数のSQL単独で構文エラーになるのは駄目っぽいですね。
【できる】カラム名もOKです
以下のようにSELECT句やWHERE句、ORDER BY句の、カラム名は置換可能でした。
db.rawQuery( "SELECT ? FROM t_wallet " + "WHERE ? <= ? ORDER BY ? DESC",/* OK */ new String[] { "description", "amount", "100", "amount"})`
しかし、
【できない】FROM句のテーブル名はダメでした
予想に反して、テーブル名は置換できないようです。
rawQuery( "SELECT description FROM ? " + /* NG */ "WHERE amount <= 100 " + "ORDER BY amount", new String[] {"t_wallet"})
そして、
【できない】ORDER BY の DESCもダメですね
これ、できても良い気がしましたが、しっかり例外が投入されました。
rawQuery( "SELECT description FROM t_wallet " + "WHERE amount <= 100 " + "ORDER BY id ?", /* NG */ new String[] {"DESC"})`
まとめ
結果をまとめると、以下のようになりました。
置換可能
- カラム名
- 値
置換できない
カラム名も構文的には式ですから、?
は式を置換できるということで良いのかな。
キャリブレーションしてステレオマッチングやってみた
例によって、百均で購入した2台のWEBカメラをステレオキャリブレーションして、ステレオマッチングをやってみました。
低価格&低品質のウェブカメラで、マジメにキャリブレーションする意味なんてあるのかどうかわかりませんが、今後とも頑張ってやっていきます。いくつになってお勉強です。
高級ステレオカメラシステム(笑)紹介
今回から以下のように、カメラをキチンと固定しました。位置がずれたらキャリブレーション取り直しですからね。
押入れから引っ張り出してきた金属製のブックエンドに、そこらに転がっていたマスキングテープで固定しました。有り合わせ感たっぷりですが、これで充分機能してます。 カメラの後ろのはキャリブレーション用のチェスボードです。
ソフトウェア
全てGitHubに置いています。
利用している画像処理ライブラリについては以下を参照してください。
キャリブレーション機能
ステレオキャリブレーション
ステレオキャリブレーションには、位置関係が固定された2つのカメラと、チェスボードが必要です。 2つのカメラで同時にチェスボードを撮影した複数の画像からキャリブレーションするのです。
stereoShot - ステレオキャリブレーション画像保存ツール
位置関係が固定されているのに、毎回、キャリブレーション画像を撮影しなおすのは無駄ですから、事前に保存した画像を実行時に読み込んで、キャリブレーションするようにしています。
この画像を保存するツールが、stereoShotです。
stereoShotを実行すると左右のカメラ画像が表示されます。各カメラが11x9のチェスボードの内部の交点を検出したら、それぞれ画面に描画します。スペースバーを押せば、両方の画像をファイルへ保存します。
ステレオキャリブレーションのためには、両方のカメラでチェスボードの交点を検出している必要があることに注意してください__
画像ファイルの保存先
画像ファイルの保存先は、既定ではカレントディレクトリとなっています。画像ファイルは、cal_
という名前で始まります。これを変更するには-C
オプションを使用します。このオプションでサブフォルダに出力することも可能です。たとえば、stereoShot -C sub/cal
とすれば、サブディレクトリ sub
にcal_
で始まるファイルが保存されます。
画像は数10枚必要とのことですが、今のところ15セット(左右あわせて30枚)でなんとかなっているようです。
StereoBlockMatchでキャリブレーションを有効にする
stereoShotで保存したキャリブレーション画像を読み込んで、ステレオマッチングを行うには、StereoBlockMatchに、stereoShotと同様の-C
オプションを指定します。-Cを指定しない場合は、従来通りキャリブレーションなしでマッチングします。
パラメータ表示・変更機能
ステレオブロックマッチに使用するパラメータの多くを、実行中に変更できるようにしました。
変更可能なパラメータは画面の左上に表示されており、左端の一文字をキーボードから入力して、[+]
と[-]
で変更できます。変更は即時反映されます。
実行結果
以下は、キャリブレーションなしとありの結果です。パラメータは同一で、「あり」は各々のカメラ画像をキャリブレーション結果でremapしてるかどうかの違いだけです。 ウィンドウの左上が右側カメラで、右上が左側。交差法(より目)で見れば立体的に見えるはず。左下はStereoSGBMで得られた視差画像。右下は視差画像の15回の移動平均画像です。
若干細かい部分の精度が改善しているように思いますが、実際のところ、その差は微妙。
カメラの品質によるところが大きいと思いますが、撮影環境やパラメータの調整でも大きく結果が異なります。
あと、キャリブレーションの有無で出力画像のピクセルが反転していますね。
今後の課題
- ステレオマッチングのパラメータの理解
- キャリブレーションの正当性チェック
- 3次元画像の可視化コードのチェック
(1)パラメータは適当に決めているので、細かく調整しながら様子を見てみます。各々のパラメータの意味も、キチンと理解していません。 また、(2)キャリブレーションのやり方によると思うのですが、補正後の画像が大きく回転したりずれていたりすることがあり、その機序を理解していません。 それから、(3)視差画像の可視化についても、なんとなく適当にやっていますので、このあたりのチェックが必要かと思います。
所感など
キャリブレーションの有無で、あまり差が出なかったので、かなり動揺(笑)。
品質の安定したWEBカメラを買うかどうか思案中。百均は限界かな。
参考サイト
OpenCVステレオキャリブレーション用チェスボードコーナー検出ツール
ステレオカメラのキャリブレーションのために必要になる簡単なツール stereoShot を作りましたので、ご紹介。
stereoShotは、2台のカメラで同時にチェスボードをキャプチャーして、コーナー検出の情報を表示し、複数の画像ファイルを保存します。 複数の画像は、キャリブレーションに使用します。
stereoShot - ステレオキャリブレーション用画像保存ツール
実行中の画面
ちょっと見にくいですが、例によって100均カメラ(笑)。 見ての通り、左右の品質に差がありすぎて、向かって右の品質が悪すぎて検出精度がダメダメです。 ちゃんとしたWEBカメラを使えば問題ないと思います。
使い方
実行すると、2台のカメラのキャプチャー画像が横に並んで表示されます。
カメラデバイスインデックス
それぞれのカメラの、キャプチャーデバイスインデックスは、右が1、左が2となっていますが、コマンドラインオプションで変更可能。 以下の例では、右を2、左を1に変更しています。
$ ./stereoShot -R2 -L1
専用チェスボード
キャリブレーションには11x9のチェスボードが必要です。GitHubのリポジトリからダウンロードできますので、印刷して使ってください。
チェスボードの認識
各カメラがチェスボードを認識すると、そのコーナー(チェスボード内部の交点)を検出して画面に描画します。(検出時点でフレームレートが低下します)
画像の保存
画像ファイルの保存は、スペースバーを押して実行します。左右のカメラのキャプチャ画像がカレントディレクトリに保存します。ファイル名はcap_<連番>_<L or R>.jpg
というようになっています。保存される画像に、画面表示されている検出されたコーナーは描画されません。
この画像を読み込んで、キャリブレーションしステレオマッチングするところは、以下のエントリーで説明しています。
ビルド方法
メイン関数は stereoShot.cpp。 その他、詳細はREADMEを参照してください。
当初チェスボードを8×8にしていたのですが、コーナーの検出順序が安定しませんでした。縦と横が同じだと縦横の判別がつかなくなるようです。 そこで、11x9に変更したら、問題は完全に解消しました。
制限事項
- チェスボードは 11×9に固定しています。
- 今のところ、Windows の Visual Studio 2015でしかビルドが通らない状態です。