Edited at

ruby-opencv よく使いそうなところのまとめメモ

ruby-opencvの学習も兼ねてよく使いそうなところをまとめメモ。誤っているところ・追加があれば、編集リクエストお願いします:nose_tone1:

require "opencv"

include OpenCV

GUI::Window.new("title").show image

GUI::wait_key

など一部省略しています。


目次


画像のインスタンスを生成

new(rows, cols, type = 5, channnel = 3) -> CvMat



  • rows (Integer) - 縦の長さ


  • cols (Integer) - 横の長さ


  • type (Integer) - 画素値の種類


変数imgに生成したCvMatのインスタンスを割り当てる

img = CvMat.new 255, 255



画像の読み込み

load(filename, iscolor = 1) -> CvMat

ファイルから画像を読み込みます。



  • filename (String) - ファイル名


  • iscolor (Integer)


    • > 0 3チャンネルカラー画像

    • = 0 白黒画像


    • < 0 元画像 - アルファチャンネル付きの画像をそのまま読み込む場合は負の値にします。




カラー画像


読み込んだ画像を変数imgに割り当てる

img = CvMat.load "img/Lenna.bmp"



モノクロ画像


画像をモノクロ画像として読込み変数imgに割り当てる

img = CvMat.load "img/Lenna.bmp", 0



画像の保存

save_image(filename) -> CvMat



  • filename (String) - ファイル名


変数imgで参照される画像を"image.png"で保存する

img = CvMat.load "img/Lenna.bmp"

img.save_image "image.png"


画像のサイズを取得

size -> CvSize

img = CvMat.load "img/Lenna.bmp", 1

p img.size.to_a # [256, 256]


画像の高さを取得

rows -> Integer

画像の高さを取得します。

img = CvMat.load "img/Lenna.bmp"

p img.rows # 256


画像の幅を取得

cols -> Integer

画像の幅を取得します。

img = CvMat.load "img/Lenna.bmp"

p img.cols # 256


画素値の取得と代入

CvScalar#[nth] -> Float

nthチャンネルの画素値を取得します。



  • nth (Integer) - チャンネルの番号

CvScalar#[nth]=(value) -> CvScalar

nthチャンネルに画素値を代入します。



  • nth (Integer) - チャンネルの番号


  • value (Float / Integer / Rational) - 値

s = CvScalar.new

s[0]= 5
p s[0] # 5.0


画素を配列に変換

to_a -> Array

to_ary -> Array

画素を配列に変換します。

s = CvScalar.new(1, 2, 3, 4)

p s.to_ary # [1, 2, 3, 4]


配列を画素に変換

s = CvScalar.new()

arr = [1, 2, 3, 4]
4.times do |i|
s[i] = arr[i]
end


画像から画素を取得

[](i, j) -> CvScalar

at(i, j) -> CvScalar



  • i (Integer) - 上からの位置


  • j (Integer) - 左からの位置

img = CvMat.load "img/Lenna.bmp"

p img.[](16, 16)[0] # 117.0
p img.at(16, 16)[0] # 117.0
p img[16, 16][0] # 117.0


画像の平均

avg(mask = nil) -> CvScalar

画像の画素の平均を返します。



  • mask (cvMat) - マスク画像。

img = CvMat.load "img/Lenna.bmp"

p img.avg.to_a # [104.89314270019531, 98.53480529785156, 179.74319458007812, 0.0]

img = CvMat.load "img/Lenna.bmp"

img_avg = CvMat.new 255, 255, CV_8U
img_avg = img_avg + img.avg


画像のリサイズ

resize(size) -> CvMat

画像をリサイズします。



  • size (CvSize) - 出力画像のサイズ

img = CvMat.load "img/Lenna.bmp"

img = img.resize CvSize.new(100, 100)


色空間の変換


BGR色空間をHSV色空間に変換

BGR2HSV -> CvMat

BGR色空間をHSV色空間に変換します。

img = CvMat.load "img/Lenna.bmp", 1

img = img.BGR2HSV


BGR色空間をLab色空間に変換

BGR2Lav -> CvMat

BGR色空間をLab色空間に変換します。

img = CvMat.load "img/Lenna.bmp", 1

img = img.BGR2Lab


2つの画像の画素の値を足す

add(val, mask = nil) -> CvMat

+(val) -> CvMat



  • val (CvMat / CvScalar) - 加算する画像。


  • mask (CvMat) - マスク画像(8ビット1チャンネル)。変更する箇所を指定する。

img = CvMat.load "img/Lenna.bmp"

img = img.add CvScalar.new(0, 128, 0)
img = img + CvScalar.new(0, 128, 0)


チャンネル数の取得

channel -> Integer

チャンネル数を返します。

img = CvMat.load "img/Lenna.bmp", 0

img.channel #=> 1
img = CvMat.load "img/Lenna.bmp"
img.channel #=> 3


チャンネルの分割

split -> Array<CvMat>

チャンネルを分割します。

img1 = CvMat.load "img/Lenna.bmp"

b, g, r = img1.split

b
g
r




チャンネルの合成

merge(src1 = nil, src2 = nil, src3 = nil, src4 = nil) -> CvMat

単純にチャンネルを合成します。

img1 = CvMat.load "img/Lenna.bmp"

b, g, r = img1.split
img = CvMat.merge g, r, b


画像の加重和

add_weighted(src1, alpha, src2, beta, gamma) -> CvMat

2つの行列の加重和を計算し、行列を返します。



  • src1 (CvMat) - 画像1


  • alpha (Flaot / Integer / Rational) - 画像1に対する重み


  • src2 (CvMat) - 画像2


  • beta (Float / Integer / Rational) - 画像2に対する重み


  • gamma (CvMat) - 画像にプラスする値

$M = \alpha M_{src1} + \beta M_{src2} + \gamma$

img1 = CvMat.load "img/Earth.bmp"

img2 = CvMat.load "img/Parrots.bmp"
img = CvMat.add_weighted img1, 0.4, img2, 0.6, -30

img1
img2
img




画像のノルム

norm(src1, src2 = nil, norm_type = 4, mask = nil) -> Float

画像2つのノルムが返る。



  • src1 (CvMat) - 画像1


  • src2 (CvMat) - 画像2。画像1と同じサイズに限る。


  • norm_type (Integer) - ノルムの種類

  • mask (CvMat) - マスク画像。サイズは画像1と同じで1チャンネルで1バイト整数CV_8UC1に限る。


  • Norm L1

    $\displaystyle \sum_{k=1}^{n} |x_k|$


  • Norm L2

    $\displaystyle \sqrt{\sum_{k=1}^n x_k^2}$


NORM_INF = 1

NORM_L1 = 2
NORM_L2 = 4
NORM_L2SQR = 5

lenna = CvMat.load "img/Lenna.bmp"
pepper = CvMat.load "img/Pepper.bmp"

p CvMat.norm(pepper, lenna) # 35705.911653394316
p CvMat.norm(pepper, lenna, NORM_INF) # 238.0
p CvMat.norm(pepper, lenna, NORM_L1) # 12836087.0
p CvMat.norm(pepper, lenna, NORM_L2) # 35705.911653394316
p CvMat.norm(pepper, lenna, NORM_L2SQR) # 1274912127.0


画像の回転

warp_affine(map_matrix, flags = 9, fillval = 0) -> CvMat

画像をアフィン変換します。



  • map_matrix (CvMat) - 2x3の変換行列


  • flags (Integer) - 補完方法と逆変換の組合せ


  • fillval (Integer) - 対応のない点を埋める値

rotation_matrix2D(center, angle, scale) -> CvMat

2Dの回転行列を計算します。



  • center (CvPoint) - 回転の中心


  • angle (Integer / Float / Rational) - 半時計回りの回転(度)


  • scale (Integer / Float / Rational) - 拡大率

img = CvMat.load "img/Earth.bmp"

rotate_img = img.warp_affine(CvMat.rotation_matrix2D CvPoint.new(128, 128), 20, 0.5)


参考

https://www.rubydoc.info/github/gonzedge/ruby-opencv/