今回もOpenCvSharpネタ。
今度はちょっと脱線気味。
OpenCVでピクセル操作や図形描画機能を使って、いろんな画像を生成してみます。
ノイズ画像の生成
各ピクセルのRGB値を乱数で設定すると、このようなノイズ画像が作成できます。
staticvoid Main(string[] args) { var r = new Random(); var img = new Mat(240, 320, MatType.CV_8UC3, new Scalar(0, 0, 0)); var mat3 = new MatOfByte3(img); var indexer = mat3.GetIndexer(); for (var y = 0; y < img.Height; y++) { for (var x = 0; x < img.Width; x++) { var px = indexer[y, x]; // RGB値すべて同じ値で、乱数値を設定 var val = (byte)(r.Next() * 255); px[0] = val; px[1] = val; px[2] = val; indexer[y, x] = px; } } Cv2.ImShow("image", img); Cv2.WaitKey(); }
各ピクセルのRGB値を同じ値にすると、こんな風にモノクロなノイズになり、
RGB各々を別々なランダム値にすると、色のついたノイズ画像になります。
var px = indexer[y, x]; // RGB値それぞれ、別々の乱数値を設定 px[0] = (byte)(r.Next() * 255); px[1] = (byte)(r.Next() * 255); px[2] = (byte)(r.Next() * 255); indexer[y, x] = px;
グラデーション画像の生成
今度は、各ピクセル値をループ変数で徐々に変化させ、グラデーション画像を描画してみます。
staticvoid Main(string[] args) { var img = new Mat(240, 320, MatType.CV_8UC3, new Scalar(0, 0, 0)); var mat3 = new MatOfByte3(img); var indexer = mat3.GetIndexer(); for (var y = 0; y < img.Height; y++) { for (var x = 0; x < img.Width; x++) { var px = indexer[y, x]; var r = (float)x / img.Width; var b = (float)y / img.Height; px[0] = (byte)(r * 255); px[1] = (byte)0; px[2] = (byte)(y * 255); indexer[y, x] = px; } } Cv2.ImShow("image", img); Cv2.WaitKey(); }
ラインアート
もう、ここまでくると、完全にOpenCVでやるべき内容じゃないですね・・・w
staticvoid Main(string[] args) { var img = new Mat(240, 320, MatType.CV_8UC3, new Scalar(0, 0, 0)); var mat3 = new MatOfByte3(img); var indexer = mat3.GetIndexer(); var lineNum = 20; // 描画する線の数for (var i = 0; i < lineNum; i++) { var val = (float)i / lineNum; var x = val * img.Width; var y = val * img.Height; Cv2.Line(img, new Point(0, y), new Point(x, img.Height), new Scalar(0, val*255, 255-(val*255))); } Cv2.ImShow("image", img); Cv2.WaitKey(); }
こんな風に、OpenCVの図形描画関数を使って、ラインアートを書いたりすることもできます。
ただし、OpenCVの図形描画関数は、α値を用いた透過処理をサポートしていません。
Scalarを引数で受けていて、Scalar型はα値も含んだ値を定義することができますが、α値は無視されて単純にRGBの色で上書きされます。
なので、αブレンドを用いて、キレイなグラフィック描画をする、などには向かないのです。
こういう用途は、OpenGLやDirectXなど、ちゃんとしたグラフィック描画のためのライブラリ/フレームワークを使う方がよいですね。
まぁ、こんな風に使うこともできる、、、ってことで。