画像のヒストグラム
画像のヒストグラム(Image histogram) は、明度やRGBの階調値の発生頻度発生頻度を示す統計データです。
棒グラフで可視化することが多い。
画像の特徴を表すものとして、多くの画像編集ソフトで表示できる。
下図は GIMP の例
!
ヒストグラムを計算するサンプルコード
github に公開されているものを試す。
https://github.com/bgaster/opencl-book-samples/tree/master/src/Chapter_14/histogram
このサンプルでは、2段階で計算する。
(1) 画像をタイルに分割して、タイルごとの部分値を並列計算する。
(2) 部分値を合計する。
部分値は、ホスト側からアクセスせず、
ターゲット側からアクセスする 読み書き可能なメモリ領域に格納する。
模式的には下図のようになる。
ホスト側
partial_histogram_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE, num_groups*257*3*sizeof(unsigned int), NULL, &err);
clSetKernelArg(histogram_rgba_unorm8, 0, sizeof(cl_mem), &input_image_unorm8);
clSetKernelArg(histogram_rgba_unorm8, 1, sizeof(int), &NUM_PIXELS_PER_WORK_ITEM);
clSetKernelArg(histogram_rgba_unorm8, 2, sizeof(cl_mem), &partial_histogram_buffer);
clSetKernelArg(histogram_sum_partial_results_unorm8, 0, sizeof(cl_mem), &partial_histogram_buffer);
clSetKernelArg(histogram_sum_partial_results_unorm8, 1, sizeof(int), &num_groups);
clSetKernelArg(histogram_sum_partial_results_unorm8, 2, sizeof(cl_mem), &histogram_buffer);
ターゲット側
kernel
void histogram_image_rgba_unorm8(image2d_t img, int num_pixels_per_workitem, global uint *histogram)
kernel
void histogram_sum_partial_results_unorm8(global uint *partial_histogram, int num_groups, global uint *histogram)
入力画像を画像ファイルから読み込むように修正したものを Github に公開した。
https://github.com/ohwada/MAC_cpp_Samples/tree/master/OpenCL-Histogram
ヒストグラムをグラフ化する
OpenCL のプログラムは、ヒストグラムの値を計算するだけです。
python の matplotlib を使って、棒グラフに表示する。
結果の妥当性
上記の図の妥当性を別の手段で計算作図したものと比較して検証する。
手段1: GIMP
画像編集ソフトの GIMP でヒストグラムを表示したもの。
比較したところ、似ているのか似ていないのか、判定できず。
手段2: matplotlib
matplotlib の hist API で計算作図したもの。
hist API はヒストグラムの計算と作図をまとめてやってくれる。
比較したところ似てますね。
手段2: matplotlib
matplotlib の hist API で計算作図したもの。
hist API はヒストグラムの計算と作図をまとめてやってくれる。
比較したところ似てます。
使用した pythonのコードはこちら。
https://github.com/ohwada/MAC_cpp_Samples/tree/master/OpenCL-Histogram/tools
手段3: OpenCV
OpenCV の calcHist API で計算したものを。
OpenCV の 描画API で作図したもの。
比較したところ似てます。
使用した OpenCV のコード はこちら。
https://github.com/ohwada/MAC_cpp_Samples/tree/master/OpenCV-Histogram