======== 画像処理 ======== .. highlight:: cpp 画像を単色で塗りつぶす ====================== 画像を単色で塗りつぶす方法を示します. また,この例には示しませんが, 画像中の部分矩形を塗りつぶす場合には、ROIまたは ``cv::rectangle`` を利用します. :ref:`draw_rectangle` などを参考にしてください. .. literalinclude:: code/cpp/sample_img_filled.cpp 実行結果: .. image:: image/filled_red.png :scale: 30% .. image:: image/filled_white.png :scale: 30% .. image:: image/filled_black.png :scale: 30% .. image:: image/filled_green.png :scale: 30% 色空間を変換する ================ 入力画像の型として可能なものは, ``CV_8U`` , ``CV_16U`` , ``CV_32F`` です. RGB画像のチャンネル順序は,変換コードで明示的に指定する必要があります.例えば,RBGからHSVならば, ``CV_RGB2HSV`` ,BGRからグレースケールならば ``CV_BGR2GRAY`` となります. また,すべての色空間が相互に変換可能なわけではないことに注意してください. .. literalinclude:: code/cpp/sample_cvt_color.cpp .. _image_resize: 画像サイズを変更する ==================== 補間手法を指定して画像サイズを変更することができます. * INTER_NEAREST 最近傍補間 * INTER_LINEAR バイリニア補間(デフォルト) * INTER_AREA ピクセル領域の関係を利用したリサンプリング.画像を大幅に縮小する場合は,モアレを避けることができる良い手法です.しかし,画像を拡大する場合は, INTER_NEAREST メソッドと同様になります * INTER_CUBIC 4x4 の近傍領域を利用するバイキュービック補間 * INTER_LANCZOS4 8x8 の近傍領域を利用する Lanczos法の補間 .. literalinclude:: code/cpp/sample_img_resize.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果(縦横0.5倍,縦0.5倍+横2.0倍): .. image:: image/lenna_resize_0505.png :scale: 30% .. image:: image/lenna_resize_0520.png :scale: 30% .. _image_flip: 画像を垂直・水平に反転する ========================== 2次元行列反転と同様です. :ref:`mat_flip` も参照してください. .. literalinclude:: code/cpp/sample_img_flip.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果(垂直反転,水平反転,垂直反転+水平反転): .. image:: image/lenna_vflip.png :scale: 30% .. image:: image/lenna_hflip.png :scale: 30% .. image:: image/lenna_bflip.png :scale: 30% .. _image_nega_posi: 画像をネガポジ反転する ======================== .. literalinclude:: code/cpp/sample_img_np.cpp 入力画像: .. image:: image/lenna_gray.png :scale: 30% 実行結果: .. image:: image/sample_img_np.png :scale: 30% .. _image_binarize: 画像を2値化する =============== 画素値を閾値処理して,画像の2値化を行います.閾値処理の手法には,以下のものがあります: * THRESH_BINARY:閾値以下の値は0に,それ以外は指定した値(maxVal)になります. * THRESH_BINARY_INV:上記とは逆に,閾値より大きい値が0に,それ以外は指定した値(maxVal)になります. * THRESH_TRUNC:閾値より大きい値は閾値まで切り詰められ,それ以外はそのまま残ります. * THRESH_TOZERO:閾値より大きい値はそのまま残り,それ以外は0になります. * THRESH_TOZERO_INV:上記とは逆に,閾値以下の値はそのまま残り,それ以外は0になります. さらに,特殊な値 ``THRESH_OTSU`` を,上述のものと組み合わせて使うこともできます.この場合,関数は大津のアルゴリズムを用いて最適な閾値を決定し,それを引数 thresh で指定された値の代わりに利用します.つまり,自分で閾値を決める必要がありません. また, ``adaptiveThreshold`` は適応的な閾値処理を行います.この適応的というのは,閾値が入力によって適応的に決まることを意味します.閾値決定の手法は,以下のものがあります: * ADAPTIVE_THRESH_MEAN_C:閾値 T(x,y) は,(x,y) の近傍 blockSize x blockSize の平均から C を引いた値 * ADAPTIVE_THRESH_GAUSSIAN_C:閾値 T(x,y) は,(x,y) の近傍 blockSize x blockSize の(ガウス分布を用いた)加重平均から C を引いた値になります.このガウス分布の標準偏差は,blockSize から決定されます. .. literalinclude:: code/cpp/sample_binarize.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_bin.png :scale: 30% .. image:: image/lenna_bin_inv.png :scale: 30% .. image:: image/lenna_trunc_bin.png :scale: 30% .. image:: image/lenna_tozero_bin.png :scale: 30% .. image:: image/lenna_tozero_bin_inv.png :scale: 30% .. image:: image/lenna_adaptive_bin.png :scale: 30% .. image_rotation: 画像を回転する ============== :ref:`image_affine_transform` の :ref:`affine_with_param` を参照してください. .. _image_affine_transform: 2次元のアフィン変換を行う ========================= .. math:: A= \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ \end{bmatrix} 変換元と変換先の3点を指定して,変換行列を決定する -------------------------------------------------- .. literalinclude:: code/cpp/sample_getaffinetransform.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_affine_3points_input.png :scale: 30% .. image:: image/lenna_affine_3points.png :scale: 30% .. literalinclude:: output/cpp/sample_getaffinetransform.txt .. _affine_with_param: 変換パラメータを指定して,変換行列を決定する -------------------------------------------- .. literalinclude:: code/cpp/sample_warpaffine_parameters.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_affine_parameters.png :scale: 30% .. literalinclude:: output/cpp/sample_warpaffine_parameters.txt 透視変換を行う ============== .. literalinclude:: code/cpp/sample_perspective_transform.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_perspective_input.png :scale: 30% .. image:: image/lenna_perspective.png :scale: 30% .. _image_pyramid: 画像ピラミッドを作る ==================== 画像ピラミッドは,解像度の異なる同一画像の集合から構成されます. このような構造は,画像の拡大縮小表示,空間方向に関する極大点を求める処理の高速化,coarse-to-fine(最初に低解像度に対する荒い処理を行い,徐々に高精度化する)手法などに利用されます. buildPyramid ------------- 元画像に対して,ダウンサンプリングするだけの画像ピラミッドの場合 buildPyramid() を利用します. .. literalinclude:: code/cpp/sample_pyramid.cpp 実行結果: .. image:: image/lenna_level0.png :scale: 30% .. image:: image/lenna_level1.png :scale: 30% .. image:: image/lenna_level2.png :scale: 30% PyrDown/PyrUp -------------- 元画像に対して,ダウンサンプリング,アップサンプリングの両方を適用する場合は,それぞれ, PyrDown, PyrUp を利用します. .. literalinclude:: code/cpp/sample_image_pyramid.cpp 入力画像: .. image:: image/opencv-logomini.png :scale: 30% 実行結果: .. image:: image/opencv-logominiDown.png :scale: 30% .. image:: image/opencv-logominiUp.png :scale: 30% 画像の膨張・収縮処理を行う ========================== マルチチャンネル画像の場合,各チャンネルが個別に処理されます. デフォルトの構造要素で膨張・収縮 --------------------------------- デフォルトの構造要素は,3x3の矩形です. .. literalinclude:: code/cpp/sample_dilate_erode.cpp 入力画像(をpngに変換した画像): .. image:: image/lenna_bw.png :scale: 30% 実行結果(膨張1回,膨張3回,収縮1回,収縮3回): .. image:: image/lenna_dilate1.png :scale: 30% .. image:: image/lenna_dilate3.png :scale: 30% .. image:: image/lenna_erode1.png :scale: 30% .. image:: image/lenna_erode3.png :scale: 30% 構造要素を指定して膨張・収縮 ---------------------------- .. literalinclude:: code/cpp/sample_dilate_erode2.cpp 入力画像(をpngに変換した画像): .. image:: image/lenna_bw.png :scale: 30% 実行結果(1x7行列+膨張1回,5x5単位行列+膨張1回,1x7行列+収縮1回,5x5単位行列+収縮1回): .. image:: image/lenna_dilate_horizon.png :scale: 30% .. image:: image/lenna_dilate_slant.png :scale: 30% .. image:: image/lenna_erode_horizon.png :scale: 30% .. image:: image/lenna_erode_slant.png :scale: 30% 高度なモルフォロジー演算 ------------------------ .. literalinclude:: code/cpp/sample_morphology.cpp 入力画像: .. image:: image/ball.png :scale: 30% 実行結果(Open, Close, Gradient, TopHat, BlackHat) .. image:: image/ball_open.png :scale: 30% .. image:: image/ball_close.png :scale: 30% .. image:: image/ball_gradient.png :scale: 30% .. image:: image/ball_tophat.png :scale: 30% .. image:: image/ball_blackhat.png :scale: 30% 画像を平滑化する(ぼかす) =========================== ガウシアンフィルタを用いた平滑化を行います. GaussianBlur ------------ .. literalinclude:: code/cpp/sample_gaussianblur.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_gaussianblur1.png :scale: 30% .. image:: image/lenna_gaussianblur2.png :scale: 30% medianBlur ----------- メディアンフィルタを用いた平滑化を行います. .. literalinclude:: code/cpp/sample_medianblur.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_medianblur1.png :scale: 30% .. image:: image/lenna_medianblur2.png :scale: 30% BilateralFilter ------------------ バイラテラルフィルタを用いた平滑化を行います. .. literalinclude:: code/cpp/sample_bilateral.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_bilateral1.png :scale: 30% .. image:: image/lenna_bilateral2.png :scale: 30% BoxFilter, Blur ------------------ ボックスフィルタを用いた平滑化を行います. :: blur(src, dst, ksize, anchor, borderType); という呼び出しは, :: boxFilter(src, dst, src.type(), anchor, true, borderType); と等価です.つまり,BoxFilterを必ず正規化するメソッドが ``blur`` と言えます. ビット深度=8 の画像で正規化を行わない場合,多くの画素が飽和する可能性があります. .. literalinclude:: code/cpp/sample_blur.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果(blur): .. image:: image/lenna_blur1.png :scale: 30% .. image:: image/lenna_blur2.png :scale: 30% 実行結果(BoxFilter): .. image:: image/lenna_BoxFilter1.png :scale: 30% .. image:: image/lenna_BoxFilter2.png :scale: 30% 微分画像・エッジ画像を求める ============================ .. literalinclude:: code/cpp/sample_edge.cpp 入力画像: .. image:: image/lenna_gray.png :scale: 30% 実行結果(Sobel,Laplacian,Canny): .. image:: image/lenna_sobel.png :scale: 30% .. image:: image/lenna_laplacian.png :scale: 30% .. image:: image/lenna_canny.png :scale: 30% 点座標集合に外接する図形を求める ================================== 外接矩形を求める ------------------ .. literalinclude:: code/cpp/sample_bounding_rect.cpp 実行結果: .. image:: image/sample_bounding_rect.png :scale: 30% 回転を考慮した外接矩形を求める -------------------------------- .. literalinclude:: code/cpp/sample_bounding_box.cpp 実行結果: .. image:: image/sample_bounding_box.png :scale: 30% 外接円を求める ------------------ .. literalinclude:: code/cpp/sample_bounding_circle.cpp 実行結果: .. image:: image/sample_bounding_circle.png :scale: 30% 凸包を求める -------------- .. literalinclude:: code/cpp/sample_convexhull.cpp 実行結果: .. image:: image/sample_convexhull.png :scale: 30% 画像の修復・不要オブジェクトを除去する ======================================= 以下のいずれかの方法で,ノイズや不要なオブジェクトを削除して画像を修復します. * INPAINT_NS:ナビエ・ストークス(Navier-Stokes)ベースの手法. * INPAINT_TELEA:Alexandru Telea による手法 ``Alexandru Telea, “An Image Inpainting Technique Based on the Fast Marching Method”. Journal of Graphics, GPU, and Game Tools 9 1, pp 23-34 (2004)`` .. literalinclude:: code/cpp/sample_inpaint.cpp 入力画像: .. image:: image/lenna_inpaint.png :scale: 30% .. image:: image/inpaint_mask.png :scale: 30% 実行結果(INPAINT_NS, INPAINT_TELEA): .. image:: image/lenna_inpaint_ns.png :scale: 30% .. image:: image/lenna_inpaint_telea.png :scale: 30% 直線を検出する ============== 古典的Hough変換 --------------- .. literalinclude:: code/cpp/sample_houghlines.cpp 入力画像: .. image:: image/building.png :scale: 30% 実行結果: .. image:: image/building_houghlines.png :scale: 30% マルチスケールHough変換 ----------------------- 確率的Hough変換 --------------- .. literalinclude:: code/cpp/sample_houghlinesP.cpp 入力画像: .. image:: image/building.png :scale: 30% 実行結果: .. image:: image/building_houghlinesP.png :scale: 30% 円を検出する ============ 直線検出の ``cv::HoughLines`` や ``cv::HoughLinesP`` が,2値画像から直線を検出するのに対して, ``cv::HoughCircles`` はグレースケール画像から円を検出することに注意してください (内部的には2値画像に変換されていますが). .. literalinclude:: code/cpp/sample_houghcircles.cpp 入力画像: .. image:: image/circles.png :scale: 30% 実行結果: .. image:: image/circles_houghcircles.png :scale: 30% 楕円フィッティングを行う ======================== 画像に対する楕円フィッティング ------------------------------- 画像から輪郭を検出し,その輪郭に対して楕円フィッティングを行う. .. literalinclude:: code/cpp/sample_fitellipse.cpp 入力画像: .. image:: image/stuff.jpg :scale: 30% 実行結果(輪郭画像,フィッティング結果): .. image:: image/stuff_bin.png :scale: 30% .. image:: image/stuff_fit_ellipse.png :scale: 30% 画像からテンプレート画像を探す ============================== テンプレートマッチング ---------------------- .. literalinclude:: code/cpp/sample_template_matching.cpp 入力画像(探索対象画像,テンプレート画像): .. image:: image/lenna.png :scale: 30% .. image:: image/lenna_left_eye.png :scale: 100% 実行結果(相関値マップ,最大相関の場所): .. image:: image/lenna_matching_map.png :scale: 30% .. image:: image/lenna_matched_place.png :scale: 30% .. literalinclude:: output/cpp/sample_template_matching.txt .. ヒストグラムベースのマッチング .. ------------------------------- .. 輪郭ベースのマッチング .. ---------------------- .. _image_alpha_blending: .. 画像のアルファブレンディング .. ============================ .. .. OpenCV では,現在のところ(OpenCV2.3.1),アルファチャンネル付の画像をサポートしていません.画像読み込みの際に,アルファチャンネルは無視されます. .. よって,アルファチャンネルを利用して画像を合成したい場合は,多少煩雑な手続きが必要になります. .. ユーザは,あらかじめ画像のアルファチャンネルを別ファイルに保存しておくか,あるいは libpng などを直接利用して自分でアルファチャンネルを取り出す必要があります. .. 以下の例では,あらかじめ別ファイルに保存されたアルファチャンネルを利用して画像の合成を行う方法を示します. .. .. .. literalinclude:: code/cpp/sample_alpha_blending.cpp .. .. 入力画像(入力1,入力1のアルファチャンネル画像(全画素がRGB=(100,100,100)),入力2,入力2のアルファチャンネル画像: .. .. .. image:: image/lenna.png .. :scale: 30% .. .. .. image:: image/gray100.png .. :scale: 30% .. .. .. image:: image/earth.png .. :scale: 30% .. .. .. image:: image/ellipse_mask.png .. :scale: 30% .. .. 実行結果: .. .. ..image:: image/alpha_blending.png .. :scale: 30% K-meansによるピクセル値のクラスタリング(減色) =============================================== .. literalinclude:: code/cpp/sample_kmeans_rgb.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_kmeans.png :scale: 30% 画像のヒストグラムを計算・描画する ================================== .. literalinclude:: code/cpp/sample_histogram.cpp 入力画像: .. image:: image/lenna_gray.png :scale: 30% 実行結果: .. image:: image/lenna_histogram.png :scale: 50% .. ヒストグラム同士を比較する .. =========================== 複数の画像をつなげる ==================== ROIを利用して複数の画像をつなげる --------------------------------- .. literalinclude:: code/cpp/sample_combine.cpp 入力画像(入力画像1,入力画像2): .. image:: image/lenna.png :scale: 30% .. image:: image/fruit.png :scale: 30% 実行結果: .. image:: image/lenna_fruit.png :scale: 30% サイズの等しい複数の画像をつなげる ---------------------------------- 幅または高さの等しい画像同士ならば,より簡単につなげることができます. .. literalinclude:: code/cpp/sample_concatenate.cpp .. image:: image/opencv-logomini.png :scale: 30% 実行結果(横結合): .. image:: image/opencv-logomini_vconcat.png :scale: 30% 実行結果(縦結合): .. image:: image/opencv-logomini_hconcat.png :scale: 30% 画像の一部を切り抜いて保存する ============================== .. literalinclude:: code/cpp/sample_img_clip.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_clipped.png :scale: 30% 画像の一部のみを処理する ======================== ROI(Region Of Interest) を指定すると,画像の一部を新たな画像のように扱うことができます. この際,例えば畳み込みなどで必要になる 「ROI の外側の画素」は,自動的に元の画像全体からのピクセルが利用されます. .. literalinclude:: code/cpp/sample_roi_filter.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_roi_blur.png :scale: 30% 矩形領域のピクセル値をサブピクセル精度で取得する ================================================ ROIを利用して,部分矩形領域のピクセル値をそのまま参照したり,コピーしたりするのとは異なり, ``cv::getRectSubPix`` を用いると,バイリニア補間された浮動小数点座標のピクセル値も得ることができます. .. literalinclude:: code/cpp/sample_img_getRectSubPix.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_getRectSubPix.png :scale: 30% 顔を検出する ============ .. literalinclude:: code/cpp/sample_face_detect.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_face_detect.png :scale: 30% また,Haar-Like特徴の代わりにLBP(Local Binary Pattern)特徴を利用して学習した結果を用いて顔を検出することもできます.それぞれの特徴を利用した学習結果ファイルは,以下の場所に置かれます. * Haar-Like:(OpenCV install path)/data/haarcascades * LBP:(OpenCV install path)/data/lbpcascades 本サンプルでの利用法は,該当ファイルをバイナリと同じ場所にコピーして,対応するXMLファイル(上述のソースでコメントアウトされている箇所)を読み込むだけです. 実行結果: .. image:: image/tiffany_face_detect.png :scale: 30% 目を検出する ============ まず顔を検出して,その検出矩形の中から,さらに目を検出します. .. literalinclude:: code/cpp/sample_eye_detect.cpp 入力画像: .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_eye_detect.png :scale: 30% また,メガネを掛けた人物の目を検出するための学習結果ファイルを利用することもできます.顔検出の場合と同様に,本サンプルでの利用法は,該当ファイルをバイナリと同じ場所にコピーして,対応するXMLファイル(上述のソースでコメントアウトされている箇所)を読み込むだけです. 実行結果: .. image:: image/kate_eye_detect.png :scale: 30% 複数の矩形をグループ化する ============================ オブジェクト検出の際に,同程度に「オブジェクトらしい」箇所に複数の検出矩形が集まることがよくあります. 多くの場合,「オブジェクトらしい」場所の近隣も同様に「オブジェクトらしい」ためです. このような場合に,複数の矩形をグループ化して,同じような矩形は1つのグループに集めるための手法です. .. literalinclude:: code/cpp/sample_group_rect.cpp 実行結果: .. image:: image/group_rect.png :scale: 30% 人を検出する ============ HOG .. literalinclude:: code/cpp/sample_people_detect.cpp 実行結果: .. image:: image/people_detect1.png :scale: 30% .. image:: image/people_detect2.png :scale: 30% .. image:: image/people_detect3.png :scale: 30% 特徴点を検出する ================ 様々な手法で特徴点を検出することができます. detector( ``cv::FeatureDetector`` を継承した様々なクラス)を変えるだけで,検出手法を変更することができます. 固有値に基づく特徴点検出 ------------------------ .. literalinclude:: code/cpp/sample_FeatureDetector_good_feature.cpp 実行結果: .. image:: image/lenna_good_feature_to_track.png :scale: 30% Harris検出器に基づく特徴点検出 ------------------------------ .. literalinclude:: code/cpp/sample_FeatureDetector_harris.cpp 実行結果: .. image:: image/lenna_harris.png :scale: 30% FAST検出器に基づく特徴点検出 ------------------------------ .. literalinclude:: code/cpp/sample_FeatureDetector_fast.cpp 実行結果: .. image:: image/lenna_fast.png :scale: 30% Star検出器に基づく特徴点検出 ------------------------------ .. literalinclude:: code/cpp/sample_FeatureDetector_star.cpp 実行結果: .. image:: image/lenna_star.png :scale: 30% SIFT検出器に基づく特徴点検出 ------------------------------ .. literalinclude:: code/cpp/sample_FeatureDetector_sift.cpp 実行結果: .. image:: image/lenna_sift.png :scale: 30% SURF検出器に基づく特徴点検出 ------------------------------ .. literalinclude:: code/cpp/sample_FeatureDetector_surf.cpp 実行結果: .. image:: image/lenna_surf.png :scale: 30% MSER検出器に基づく特徴点検出 ------------------------------ MSERは本来,領域抽出の手法ですが,OpenCVでは,検出された領域輪郭に楕円をフィッティングさせることで,サイズと方向を考慮する特徴点検出器として利用することもできます. .. literalinclude:: code/cpp/sample_FeatureDetector_mser.cpp 実行結果: .. image:: image/lenna_mser.png :scale: 30% ORB検出器に基づく特徴点検出 ------------------------------ .. literalinclude:: code/cpp/sample_FeatureDetector_ORB.cpp 実行結果: .. image:: image/lenna_ORB.png :scale: 30% FAST検出器+Gridアダプタ に基づく特徴点検出 --------------------------------------------- 入力画像をグリッド状に分割し,その中で特徴点を検出します. .. literalinclude:: code/cpp/sample_FeatureDetector_fast_GridAdapted.cpp 実行結果: .. image:: image/lenna_fast_gridadapted.png :scale: 30% FAST検出器+Pyramidアダプタ に基づく特徴点検出 ----------------------------------------------- 入力画像からガウシアンピラミッドを作成し,各レベルにおいて特徴点を検出します. 特徴点のスケールを指定できない検出器において役立ちます. .. literalinclude:: code/cpp/sample_FeatureDetector_fast_PyramidAdapted.cpp 実行結果: .. image:: image/lenna_fast_pyramidadapted.png :scale: 30% FAST検出器+Dynamicアダプタ(+Adjusterアダプタ)に基づく特徴点検出 ------------------------------------------------------------------ 特徴点検出において,ある決まった個数範囲の特徴点を求めたい場合に,この方法が役にたちます. 求めたい特徴点個数の ``最小値`` と ``最大値`` を指定すると,検出器のパラメータを変更しながら, 指定された ``繰り返し数`` 範囲内で探索を行います. .. literalinclude:: code/cpp/sample_FeatureDetector_fast_DynamicAdapted.cpp 実行結果: .. image:: image/lenna_fast_adjuster.png :scale: 30% .. literalinclude:: output/cpp/sample_fast_adjuster.txt SimpleBlob検出器に基づく特徴点検出 ------------------------------------- #. 適応的閾値処理を行い,入力画像を二値化します.その際に,minThreasholdからmaxThresholdまで,thresholdStepステップで変化させた複数の閾値を利用します. #. 各二値画像から,findContours()を用いて連結成分を抽出し,その中心を求めます. #. 複数の二値画像の中心点を座標でグループ化します.近い中心同士は1つのblobを形成し,これは minDistBetweenBlobsパラメータで制御されます. #. グループの最終的な中心と半径を推定し,それをキーポイントの位置とサイズとして返します. .. literalinclude:: code/cpp/sample_SimpleBlobDetector.cpp 実行結果: .. image:: image/BigBead_SimpleBlob.png :scale: 30% 局所特徴量を計算する ==================== 検出された特徴点に対して,それを記述する様々な局所特徴量を計算することができます. detector と extractor( ``cv::DescriptorExtractor`` を継承した様々なクラス)を変えるだけで,計算する局所特徴量を変更することができます. SIFT ---- .. literalinclude:: code/cpp/sample_DescriptorExtractor_sift.cpp 実行結果(最初の2行): .. literalinclude:: output/cpp/sample_DescriptorExtractor_sift.txt :lines: 1-2 SURF ---- .. literalinclude:: code/cpp/sample_DescriptorExtractor_surf.cpp 実行結果(最初の2行): .. literalinclude:: output/cpp/sample_DescriptorExtractor_surf.txt :lines: 1-2 Calonder -------- .. literalinclude:: code/cpp/sample_DescriptorExtractor_calonder.cpp 実行結果(最初の5行): .. literalinclude:: output/cpp/sample_DescriptorExtractor_calonder.txt :lines: 1-5 ORB --- .. literalinclude:: code/cpp/sample_DescriptorExtractor_ORB.cpp 実行結果(最初の2行): .. literalinclude:: output/cpp/sample_DescriptorExtractor_ORB.txt :lines: 1-2 Brief ----- .. literalinclude:: code/cpp/sample_DescriptorExtractor_Brief.cpp 実行結果(最初の2行): .. literalinclude:: output/cpp/sample_DescriptorExtractor_Brief.txt :lines: 1-2 局所特徴量の集合同士を比較する ============================== ある画像から局所特徴量の集合が計算されると,それらを複数の画像間で比較することができます. matcher( ``cv::DescriptorMatcher`` または ``cv::GenericDescriptorMatcher`` を継承した様々なクラス)を変えるだけで,比較手法を変更することができます. FlannBasedMatcher ------------------ .. literalinclude:: code/cpp/sample_DescriptorMatcher_flannBased.cpp 入力画像(入力画像1,入力画像2): .. image:: image/lenna.png :scale: 30% .. image:: image/lenna_rotated.png :scale: 30% 実行結果: .. image:: image/lenna_DescriptorMatcher_flannBased.png :scale: 30% FlannBasedMatcher+クロスチェック ------------------------------------ .. literalinclude:: code/cpp/sample_DescriptorMatcher_flannBased_crossCheck.cpp 入力画像(入力画像1,入力画像2): .. image:: image/lenna.png :scale: 30% .. image:: image/lenna_rotated.png :scale: 30% 実行結果: .. image:: image/lenna_DescriptorMatcher_flannBased_crossCheck.png :scale: 30% BruteForceMatcher ----------------- .. literalinclude:: code/cpp/sample_DescriptorMatcher_bruteForce.cpp 入力画像(入力画像1,入力画像2): .. image:: image/lenna.png :scale: 30% .. image:: image/lenna_rotated.png :scale: 30% 実行結果: .. image:: image/lenna_DescriptorMatcher_bruteForce.png :scale: 30% 画像のチャンネルの合成と分離 ============================== 画像のチャンネル(R,G,Bなど)の合成と分離も,行列の場合と同様です. :ref:`mat_merge_mix_seperate` を参照してください. 画像に境界領域を追加する ========================= .. literalinclude:: code/cpp/sample_img_border.cpp 入力画像(入力画像1,入力画像2): .. image:: image/lenna.png :scale: 30% 実行結果: .. image:: image/lenna_border_rep.png :scale: 30% .. image:: image/lenna_border_ref.png :scale: 30% .. image:: image/lenna_border_ref101.png :scale: 30% .. image:: image/lenna_border_wrap.png :scale: 30% .. image:: image/lenna_border_const.png :scale: 30% 輪郭の検出 =========== .. literalinclude:: code/cpp/sample_contours.cpp 入力画像: .. image:: image/star_objects.png :scale: 30% 実行結果(index=0, max_level=0): .. literalinclude:: output/cpp/sample_contours_input0.txt .. literalinclude:: output/cpp/sample_contours_output0.txt .. image:: image/sample_contours_0_0.png :scale: 30% 実行結果(index=2, max_level=0): .. literalinclude:: output/cpp/sample_contours_input1.txt .. literalinclude:: output/cpp/sample_contours_output1.txt .. image:: image/sample_contours_2_0.png :scale: 30% 実行結果(index=2, max_level=1): .. literalinclude:: output/cpp/sample_contours_input2.txt .. literalinclude:: output/cpp/sample_contours_output2.txt .. image:: image/sample_contours_2_1.png :scale: 30% 実行結果(index=-1, max_level=1): .. literalinclude:: output/cpp/sample_contours_input3.txt .. literalinclude:: output/cpp/sample_contours_output3.txt .. image:: image/sample_contours_-1_1.png :scale: 30% オプティカルフローを計算する ============================= OpenCVのC++インタフェースには,オプティカルフローを計算する二種類のメソッドが用意されています (CやPythonインタフェースからは,以前の cvCalcPoticalFlowBM や cvCalcPoticalFlowHS, cvCalcPoticalFlowLK なども利用できます). PyrLK ----- .. literalinclude:: code/cpp/sample_of_PyrLK.cpp 入力画像: .. image:: image/blocks1.png :scale: 30% .. image:: image/blocks2.png :scale: 30% 実行結果: .. image:: image/of_PyrLK.png :scale: 30% Farneback ---------- .. literalinclude:: code/cpp/sample_of_Farneback.cpp 入力画像: .. image:: image/blocks1.png :scale: 30% .. image:: image/blocks2.png :scale: 30% 実行結果: .. image:: image/of_Farneback.png :scale: 30% アルファチャンネル付PNG画像の読み書き ====================================== アルファチャンネル付PNG画像を読み込む -------------------------------------- OpenCV2.3.1で,アルファチャンネル付きPNG画像がサポートされました. ただし,現時点ではUndocumentedなので,正式なサポートか否かは不明です. アルファチャンネル付き画像を読み込む際に指定するフラグ(-1)は,highgui.hpp で :: enum { ... IMREAD_UNCHANGED =-1, ... } と定義されている値です. .. literalinclude:: code/cpp/sample_alpha_png.cpp 入力画像: .. image:: image/cvlogo.png :scale: 30% .. image:: image/lenna.png :scale: 30% 実行結果(アルファチャンネル,合成画像): .. image:: image/cvlogo_a.png :scale: 30% .. image:: image/cvblend_lenna.png :scale: 30% アルファチャンネル付PNG画像を書き出す --------------------------------------