Octave から OpenCV の k-means クラスタリング関数を呼び出す例
OpenCV の機能を利用して,Octave から k-means クラスタリングを行う例
- k-means クラスタリング (Octave bindings for OpenCV を使用)
Octave 言語で書いた k-means クラスタリングのソースコード (OpenCV を使わないもの) は別の Web ページに載せています
前準備
Octave のインストール
その他
【関連する外部ページ】: http://www.eecs.berkeley.edu/Research/Projects/CS/vision/bsds/
* Octave のプロンプトを変えたいときは,次のように操作する.
PS1('> ')
* Octave のインストールによっては,Octave の起動時に毎回次の操作を行う必要があるかもしれない
pkg load image
プログラムのソースコード(書きかけ)
function mat = cvreadl2d_to_mat(cv) # Read2D 型を要素とする CvMat (OpenCV のデータ)cv を,Octave の2次元配列 mat にコピー for x = [1:cv.width] for y = [1:cv.height] mat(y,x) = cvGetReal2D(cv, y-1, x-1); end end endfunction function cv = mat_to_cvreadl2d(mat) # Octave の2次元配列 mat を,Read2D 型を要素とする CvMat(OpenCV のデータ)cv にコピー height = size(mat)(1); width = size(mat)(2); for x = [1:width] for y = [1:height] cvSetReal2D(cv, y-1, x-1), mat(y,x); end end endfunction function rgbplot3d(rgb) # Octave の RGB 画像データ(256階調, 0 から 255 の値,R, G, B プレーン)を使い,画素値の 3次元プロットを行う colormap(map); plot3(rgb(:,:,1), rgb(:,:,2), rgb(:,:,3)); endfunction function rgb_to_cvreal3(rgb, samples) # Octave の RGB 画像データ(256階調, 0 から 255 の値,R, G, B プレーン)を、 # OpenCV のデータ構造である 要素 CV_32FC3 の CvMat (ROW数 > 1, COL数 =1) に [r; g; b; r; g; b; ...] の形で並べる. height = size(rgb)(1); width = size(rgb)(2); for x = [1:width] for y = [1:height] cvSet2D(samples, ((x - 1) * height) + (y - 1), 0, cvScalar( rgb(y,x,1), rgb(y,x,2), rgb(y,x,3) ) ); end end endfunction function vec = rgbvec(rgb) # Octave の RGB 画像データ(256階調, 0 から 255 の値,R, G, B プレーン)を、[r g b r g b ...] の形の行ベクトルに変える height = size(rgb)(1); width = size(rgb)(2); vec = zeros(1,width*height); for x = [1:width] for y = [1:height] # 要素番号は 1 から始まるので - 1, + 1 が必要 vec( ( ((x - 1) * height) + (y - 1) ) * 3 + 1 ) = rgb(y,x,1); vec( ( ((x - 1) * height) + (y - 1) ) * 3 + 2 ) = rgb(y,x,2); vec( ( ((x - 1) * height) + (y - 1) ) * 3 + 3 ) = rgb(y,x,3); end end endfunction function rgb = vecrgb(vec, width, height) # Octave の [r g b r g b ...] の形の行ベクトルを,RGB 画像データ(256階調, 0 から 255 の値,R, G, B プレーン)に変える. rgb = zeros(height,width,3); for x = [1:width] for y = [1:height] # 要素番号は 1 から始まるので - 1, + 1 が必要 rgb(y,x,1) = vec( ( ((x - 1) * height) + (y - 1) ) * 3 + 1 ); rgb(y,x,2) = vec( ( ((x - 1) * height) + (y - 1) ) * 3 + 2 ); rgb(y,x,3) = vec( ( ((x - 1) * height) + (y - 1) ) * 3 + 3 ); end end endfunction rgb1 = imread("20090701001_avi01_001000.png"); height = size(rgb1)(1); width = size(rgb1)(2); samples1 = cvCreateMat(width * height, 1, CV_32FC3); rgb_to_cvreal3(rgb1, samples1); MAX_CLUSTERS = 10; labels1 = cvCreateMat(width * height, 1, CV_32SC1); cvKMeans2(samples1, MAX_CLUSTERS, labels1, cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0)); for x = [1:width] for y = [1:height] mono2(y,x) = cvGetReal2D(labels1, (x-1) * height + (y-1), 0); end end # colormap ... は,カラーマップの設定 colormap( rainbow(MAX_CLUSTERS) ); imshow(mono2, [min(min(mono2)) max(max(mono2))]); # # colormap(map); # imshow(rgb1); input("Please press enter to continue");
実行方法と実行結果の例
- (オプション)Cygwin からリモートログインする場合
startx xhost + ssh -X username@ipaddress
- ソースコードをファイルとして保存
- Octave を起動
- Octave の source コマンドを使って実行
cd <ソースコードのファイルを置いたディレクトリ> source "<ソースコードのファイル名>"
- 実行が終わるまで数十秒待つ
元画像の例
実行手順
上記のファイルを mykmean.m のようなファイル名で保存しておく. 上記のファイル内の画像ファイル名「20090701001_avi01_001000.png」の部分は適切に書き換える
octave source mykmean.m
クラスタリングの結果
およそ数秒程度で次の結果が出る