Contenu connexe
Similaire à 【第27回コンピュータビジョン勉強会@関東】OpenCV 便利Tips紹介 (20)
【第27回コンピュータビジョン勉強会@関東】OpenCV 便利Tips紹介
- 2. 自己紹介
Twitter ID:@dandelion1124
• 学生時代は画像処理の研究に従事。
• 研究室でOpenCV Tipsサイトを作っていたらOpenCV関連書
籍(OpenCVプログラミングブック)を執筆。
• 現在は都内勤務エンジニア。
• Build InsiderにてOpenCV入門
(http://www.buildinsider.net/small/opencv)を連載中。
blog: http://www.atinfinity.info/blog/
wiki: http://www.atinfinity.info/wiki/
- 5. OpenCVメモリ使用量を計測する
• 「Hacking OpenCV for fun and profit」(http://computer-
vision-talks.com/articles/hacking-opencv-for-fun-and-profit/)
というブログ記事にて「OpenCVを拡張したメモリ使用量計測
方法」が紹介されています。
• 最近、公式へのプルリクエストも行われている模様。
(https://github.com/Itseez/opencv/pull/3640)
– そのうち、公式に取り込まれるかも?
ということで、なんだか便利そうなこの機能を試してみました!
- 7. サンプルコード(OpenCVメモリ使用量計測)
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#define ENABLE_MEASURE_MEMORY
#ifndef ENABLE_MEASURE_MEMORY
#define MEASURE_MEMORY(x) {x;}
#else
#define MEASURE_MEMORY(x) { ¥
size_t memOnStart = cv::memorySnapshot().allocatedMemory; x;¥
size_t memOnEnd = cv::memorySnapshot().allocatedMemory; ¥
std::cout << #x << "," << "¥t" << memOnStart / (1024.0*1024.0) << "[MB]" << ¥
" -> " << ¥
memOnEnd / (1024.0*1024.0) << "[MB]" << std::endl; }
#endif
int main(int argc, char** argv)
{
cv::Mat src, dst;
MEASURE_MEMORY(src = cv::imread("lena.jpg", cv::IMREAD_COLOR));
MEASURE_MEMORY(cv::resize(src, dst, cv::Size(), 5.0, 5.0));
MEASURE_MEMORY(dst.release());
return 0;
}
MEASURE_MEMORYマクロで
囲んで実行
計測用マクロ定義
- 8. サンプルコード(OpenCVメモリ使用量計測)
#define MEASURE_MEMORY(x) { ¥
size_t memOnStart = cv::memorySnapshot().allocatedMemory; x;¥
size_t memOnEnd = cv::memorySnapshot().allocatedMemory; ¥
std::cout << #x << "," << "¥t" << memOnStart / (1024.0*1024.0) << "[MB]" << ¥
" -> " << ¥
memOnEnd / (1024.0*1024.0) << "[MB]" << std::endl; }
ソースコード(計測用マクロ)
MEASURE_MEMORYマクロの概要
① 処理xを行う前のOpenCVメモリ使用量(memOnStart)を取得する
② 処理xを実行する
③ 処理xを行った後のOpenCVメモリ使用量(memOnEnd)を取得する
④ memOnStart、 memOnEndの値を標準出力する
① ② ③
④
- 9. src = cv::imread("lena.jpg", cv::IMREAD_COLOR), 0.332099[MB] -> 1.0821[MB]
cv::resize(src, dst, cv::Size(), 5.0, 5.0), 1.0821[MB] -> 19.8321[MB]
dst.release(), 19.8321[MB] -> 1.0821[MB]
標準出力結果
サンプルコード(OpenCVメモリ使用量計測)
cv::Mat src, dst;
MEASURE_MEMORY(src = cv::imread("lena.jpg", cv::IMREAD_COLOR));
MEASURE_MEMORY(cv::resize(src, dst, cv::Size(), 5.0, 5.0));
MEASURE_MEMORY(dst.release());
ソースコード(抜粋)
実行した処理 処理前のメモリ使用量 処理後のメモリ使用量
- 10. サンプルコード(OpenCVメモリ使用量計測)
src = cv::imread("lena.jpg", cv::IMREAD_COLOR), 0.332099[MB] -> 1.0821[MB]
cv::resize(src, dst, cv::Size(), 5.0, 5.0), 1.0821[MB] -> 19.8321[MB]
dst.release(), 19.8321[MB] -> 1.0821[MB]
cv::Mat src, dst;
MEASURE_MEMORY(src = cv::imread("lena.jpg", cv::IMREAD_COLOR));
MEASURE_MEMORY(cv::resize(src, dst, cv::Size(), 5.0, 5.0));
MEASURE_MEMORY(dst.release());
画像データを解放するとメモリ使用量も減少していることがわかる。
サンプルコードは、https://gist.github.com/atinfinity/6b837b3859a5252d4cb8で公開。
ソースコード(抜粋)
標準出力結果
- 15. サンプルコード(ネガポジ変換)
const char *KernelSource = "¥n" ¥
"__kernel void negaposi_C1_D0( ¥n" ¥
" __global uchar* input, ¥n" ¥
" __global uchar* output) ¥n" ¥
"{ ¥n" ¥
" int i = get_global_id(0); ¥n" ¥
" output[i] = 255 - input[i]; ¥n" ¥
"}¥n";
①OpenCLカーネルを記述
【注意】
カーネルが対象とするチャンネル数、デプスを
表すような関数名にする必要がある。
この例では、
C1:チャンネル数が1
D0:デプスがCV_8U(=0)
向けのカーネルであることを表している。
画素値(出力) = 255 – 画素値(入力)という単純なカーネル
自作OpenCLカーネル
- 16. サンプルコード(ネガポジ変換)
自作OpenCLカーネル実行処理(抜粋)
cv::ocl::ProgramSource program("negaposi", KernelSource);
std::size_t globalThreads[3]={mat_src.cols * mat_src.rows, 1, 1};
std::vector<std::pair<size_t , const void *> > args;
args.push_back( std::make_pair( sizeof(cl_mem), (void *) &ocl_src.data ));
args.push_back( std::make_pair( sizeof(cl_mem), (void *) &ocl_dst.data ));
cv::ocl::openCLExecuteKernelInterop(cv::ocl::Context::getContext(),
program, "negaposi", globalThreads, NULL, args, channels, depth, NULL);
サンプルコードは、https://gist.github.com/atinfinity/8c25c8fb1b3708aa0944で公開。
②①のOpenCLカーネルから
プログラムオブジェクトを作成
③ocl::openCLExecuteKernelInterop関数に画像データ、
②で作成したプログラムオブジェクトを渡して実行
- 20. OpenCVでラベリングを行う(2/2)
今更感はありますが、ついにOpenCV 3.0からラベリング専用APIが
提供されます!嬉しい!!
• 簡易版API
– int connectedComponents(InputArray image, OutputArray labels,
int connectivity=8, int ltype=CV_32S)
• もう少し細かい情報(面積、重心、幅 、高さ etc…)が取れるAPI
– int connectedComponentsWithStats(InputArray image,
OutputArray labels, OutputArray stats, OutputArray centroids, int
connectivity=8, int ltype=CV_32S)
• 詳細は公式ドキュメント
(http://docs.opencv.org/master/modules/imgproc/doc/structural_analysis_and_shape
_descriptors.html#connectedcomponents)を参照ください。
- 21. サンプルコード(抜粋)
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
int main(int argc, char** argv)
{
cv::Mat src = cv::imread("input.png", cv::IMREAD_GRAYSCALE);
cv::Mat bin;
cv::threshold(src, bin, 0, 255, cv::THRESH_BINARY|cv::THRESH_OTSU);
cv::Mat labelImage(img.size(), CV_32S);
int nLabels = cv::connectedComponents(bin, labelImage, 8);
return 0;
}
画像読み込み
二値化
ラベル用画像生成
※CV_32S or CV_16Uとする必要あり
ラベリング実行。
戻り値がラベル数。
ラベリングAPIは
imgprocモジュールにて提供
このサンプルでは8近傍で
ラベリング処理を行う