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
クラスタリングの結果
およそ数秒程度で次の結果が出る
