その他の画像変換

cv::adaptiveThreshold

void adaptiveThreshold(const Mat& src, Mat& dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)

配列に対して,適応的な閾値処理を行います.

パラメタ:
  • src – 8ビット,シングルチャンネルの入力画像
  • dstsrc と同じサイズ,同じタイプの出力画像
  • maxValue – 条件を満足するピクセルに割り当てられる非0の値.説明を参照してください
  • adaptiveMethod – 利用される適応的閾値アルゴリズム: ADAPTIVE_THRESH_MEAN_C または ADAPTIVE_THRESH_GAUSSIAN_C (説明を参照してください)
  • thresholdType – 閾値の種類. THRESH_BINARY または THRESH_BINARY_INV のどちらか
  • blockSize – ピクセルの閾値を求めるために利用される近傍領域のサイズ.3, 5, 7, など
  • C – 平均または加重平均から引かれる定数(説明を参照).通常,これは正値ですが,0や負値の可能性もあります

関数 adaptiveThreshold は,以下の式にしたがってグレースケール画像を2値画像に変換します:

  • THRESH_BINARY

    dst(x,y) =  \fork{\texttt{maxValue}}{if $src(x,y) > T(x,y)$}{0}{otherwise}

  • THRESH_BINARY_INV

    dst(x,y) =  \fork{0}{if $src(x,y) > T(x,y)$}{\texttt{maxValue}}{otherwise}

ここで T(x,y) は,個々のピクセルに対して求められる閾値です.

  1. ADAPTIVE_THRESH_MEAN_C メソッドの場合,閾値 T(x, y) は, (x, y) の近傍 \texttt{blockSize} \times \texttt{blockSize} の平均から C を引いた値になります.
  2. ADAPTIVE_THRESH_GAUSSIAN_C メソッドの場合,閾値 T(x, y) は, (x, y) の近傍 \texttt{blockSize} \times \texttt{blockSize} の加重平均(つまり,ガウシアン窓による相互相関)から C を引いた値になります.デフォルトのシグマ(標準偏差)は,指定された blockSize から求められます. getGaussianKernel() を参照してください.

この関数は,置換モードでも動作します.

参考: threshold() , blur() , GaussianBlur()

cv::cvtColor

void cvtColor(const Mat& src, Mat& dst, int code, int dstCn=0)

画像の色空間を変換します.

パラメタ:
  • src – 8ビット符号なし整数型,16ビット符号なし整数型( CV_16UC... ),または単精度浮動小数型の入力画像
  • dstsrc と同じサイズ,同じタイプの出力画像
  • code – 色空間の変換コード.説明を参照してください
  • dstCn – 出力画像のチャンネル数.この値が 0 の場合,チャンネル数は srccode から自動的に求められます

関数 cvtColor は,入力画像の色空間を別の色空間に変換します.RGB 色空間との相互変換の場合,チャンネルの順序を明示的に指定する必要があります(RGB あるいは BGR).

R, G, B チャンネルの値の標準的な範囲は,以下のようになります:

  • CV_8U 画像の場合,0 から 255
  • CV_16U 画像の場合,0 から 65535
  • CV_32F 画像の場合,0 から 1

もちろん,線形変換の場合は,この範囲は問題にいけません.しかし,RGB \rightarrow L*u*v* 変換のような非線形変換の場合,RGB入力画像を適切な範囲にある値に正規化しなければいけません.例えば,8ビット画像をスケーリングなしで32ビット浮動小数点型画像に変換すると,この関数では0から1の範囲を仮定しているにも関わらず,実際には0から1の範囲の値になります.したがって, cvtColor を呼ぶ前に,まず画像をスケーリングする必要があります:

img *= 1./255;
cvtColor(img, img, CV_BGR2Luv);

この関数では,以下の変換が可能です:

  • RGB 空間内での変換,アルファチャンネルの追加や削除,チャンネル順序の反転,16ビットRGBカラー(R5:G6:B5 または R5:G5:B5)との相互変換,グレースケールとの相互変換.これには,以下の式を利用します:

    \text{RGB[A] to Gray:} \quad Y  \leftarrow 0.299  \cdot R + 0.587  \cdot G + 0.114  \cdot B

    \text{Gray to RGB[A]:} \quad R  \leftarrow Y, G  \leftarrow Y, B  \leftarrow Y, A  \leftarrow 0

    RGB画像からグレースケールへの変換は,次のようになります:

    cvtColor(src, bwsrc, CV_RGB2GRAY);
    

    より高度なチャンネル順序の変更は, mixChannels を利用して行うことができます.

  • RGB \leftrightarrow CIE XYZ ,Rec 709仕様,D65 白色点 ( CV_BGR2XYZ, CV_RGB2XYZ, CV_XYZ2BGR, CV_XYZ2RGB ):

    \begin{bmatrix} X  \\ Y  \\ Z
  \end{bmatrix} \leftarrow \begin{bmatrix} 0.412453 & 0.357580 & 0.180423 \\ 0.212671 & 0.715160 & 0.072169 \\ 0.019334 & 0.119193 & 0.950227
  \end{bmatrix} \cdot \begin{bmatrix} R  \\ G  \\ B
  \end{bmatrix}

    \begin{bmatrix} R  \\ G  \\ B
  \end{bmatrix} \leftarrow \begin{bmatrix} 3.240479 & -1.53715 & -0.498535 \\ -0.969256 &  1.875991 & 0.041556 \\ 0.055648 & -0.204043 & 1.057311
  \end{bmatrix} \cdot \begin{bmatrix} X  \\ Y  \\ Z
  \end{bmatrix}

    X , Y および Z は,全範囲をカバーします(浮動小数点型の画像の場合, Z は1を越える可能性があります).

  • RGB \leftrightarrow YCrCb JPEG (YCCとも呼ばれます) ( CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB )

    Y  \leftarrow 0.299  \cdot R + 0.587  \cdot G + 0.114  \cdot B

    Cr  \leftarrow (R-Y)  \cdot 0.713 + delta

    Cb  \leftarrow (B-Y)  \cdot 0.564 + delta

    R  \leftarrow Y + 1.403  \cdot (Cr - delta)

    G  \leftarrow Y - 0.344  \cdot (Cr - delta) - 0.714  \cdot (Cb - delta)

    B  \leftarrow Y + 1.773  \cdot (Cb - delta)

    ここで,

    delta =  \left \{ \begin{array}{l l} 128 &  \mbox{for 8-bit images} \\ 32768 &  \mbox{for 16-bit images} \\ 0.5 &  \mbox{for floating-point images} \end{array} \right .

    Y, Cr および Cb は,全範囲をカバーします.

  • RGB \leftrightarrow HSV ( CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB )

    8ビット および 16ビット画像の場合,R, G, B は浮動小数点型のフォーマットに変換され,0から1の範囲に収まるようにスケーリングされます.

    V  \leftarrow max(R,G,B)

    S  \leftarrow \fork{\frac{V-min(R,G,B)}{V}}{if $V \neq 0$}{0}{otherwise}

    H  \leftarrow \forkthree{{60(G - B)}/{S}}{if $V=R$}{{120+60(B - R)}/{S}}{if $V=G$}{{240+60(R - G)}/{S}}{if $V=B$}

    もし H<0 ならば H \leftarrow H+360 出力値の範囲は, 0 \leq V \leq 1 , 0 \leq S \leq 1 , 0 \leq H \leq 360 .

    これらの値は,出力されるべき型に変換されます:

    • 8ビット画像

      V  \leftarrow 255 V, S  \leftarrow 255 S, H  \leftarrow H/2  \text{(to fit to 0 to 255)}

    • 16ビット画像

      現在はサポートされていません

      V <- 65535 V, S <- 65535 S, H <- H

    • 32ビット画像

      H, S, V は,そのまま

  • RGB \leftrightarrow HLS ( CV_BGR2HLS, CV_RGB2HLS, CV_HLS2BGR, CV_HLS2RGB ).

    8ビット および 16ビット画像の場合,R, G, B は浮動小数点型のフォーマットに変換され,0から1の範囲に収まるようにスケーリングされます.

    V_{max}  \leftarrow {max}(R,G,B)

    V_{min}  \leftarrow {min}(R,G,B)

    L  \leftarrow \frac{V_{max} + V_{min}}{2}

    S  \leftarrow \fork { \frac{V_{max} - V_{min}}{V_{max} + V_{min}} }{if  $L < 0.5$ }
    { \frac{V_{max} - V_{min}}{2 - (V_{max} + V_{min})} }{if  $L \ge 0.5$ }

    H  \leftarrow \forkthree {{60(G - B)}/{S}}{if  $V_{max}=R$ }
  {{120+60(B - R)}/{S}}{if  $V_{max}=G$ }
  {{240+60(R - G)}/{S}}{if  $V_{max}=B$ }

    if H<0 then H \leftarrow H+360 出力の範囲は, 0 \leq L \leq 1 , 0 \leq S \leq 1 , 0 \leq H \leq 360 .

    これらの値は,出力されるべき型に変換される:

    • 8ビット画像

      V  \leftarrow 255 \cdot V, S  \leftarrow 255 \cdot S, H  \leftarrow H/2 \; \text{(to fit to 0 to 255)}

    • 16ビット画像

      現在はサポートされていません

      V <- 65535 \cdot V, S <- 65535 \cdot S, H <- H

    • 32ビット画像

      H, S, V は,そのまま

  • RGB \leftrightarrow CIE L*a*b* ( CV_BGR2Lab, CV_RGB2Lab, CV_Lab2BGR, CV_Lab2RGB )

    8ビット および 16ビット画像の場合,R, G, B は浮動小数点型のフォーマットに変換され,0から1の範囲に収まるようにスケーリングされます.

    \vecthree{X}{Y}{Z} \leftarrow \vecthreethree{0.412453}{0.357580}{0.180423}{0.212671}{0.715160}{0.072169}{0.019334}{0.119193}{0.950227} \cdot \vecthree{R}{G}{B}

    X  \leftarrow X/X_n,  \text{where} X_n = 0.950456

    Z  \leftarrow Z/Z_n,  \text{where} Z_n = 1.088754

    L  \leftarrow \fork{116*Y^{1/3}-16}{for $Y>0.008856$}{903.3*Y}{for $Y \le 0.008856$}

    a  \leftarrow 500 (f(X)-f(Y)) + delta

    b  \leftarrow 200 (f(Y)-f(Z)) + delta

    ここで,

    f(t)= \fork{t^{1/3}}{for $t>0.008856$}{7.787 t+16/116}{for $t\leq 0.008856$}

    および

    delta =  \fork{128}{for 8-bit images}{0}{for floating-point images}

    出力の範囲は, 0 \leq L \leq 100 , -127 \leq a \leq 127 , -127 \leq b \leq 127 これらの値は,出力されるべき型に変換されます:

    • 8ビット画像

      L  \leftarrow L*255/100, \; a  \leftarrow a + 128, \; b  \leftarrow b + 128

    • 16ビット画像

      現在はサポートされていません

    • 32ビット画像

      L, a, b は,そのまま

  • RGB \leftrightarrow CIE L*u*v* ( CV_BGR2Luv, CV_RGB2Luv, CV_Luv2BGR, CV_Luv2RGB )

    8ビット および 16ビット画像の場合,R, G, B は浮動小数点型のフォーマットに変換され,0から1の範囲に収まるようにスケーリングされます.

    \vecthree{X}{Y}{Z} \leftarrow \vecthreethree{0.412453}{0.357580}{0.180423}{0.212671}{0.715160}{0.072169}{0.019334}{0.119193}{0.950227} \cdot \vecthree{R}{G}{B}

    L  \leftarrow \fork{116 Y^{1/3}}{for $Y>0.008856$}{903.3 Y}{for $Y\leq 0.008856$}

    u'  \leftarrow 4*X/(X + 15*Y + 3 Z)

    v'  \leftarrow 9*Y/(X + 15*Y + 3 Z)

    u  \leftarrow 13*L*(u' - u_n)  \quad \text{where} \quad u_n=0.19793943

    v  \leftarrow 13*L*(v' - v_n)  \quad \text{where} \quad v_n=0.46831096

    出力の範囲は, 0 \leq L \leq 100 , -134 \leq u \leq 220 , -140 \leq v \leq 122 .

    これらの値は,出力されるべき型に変換されます:

    • 8ビット画像

      L  \leftarrow 255/100 L, \; u  \leftarrow 255/354 (u + 134), \; v  \leftarrow 255/256 (v + 140)

    • 16ビット画像

      現在はサポートされていません

    • 32ビット画像

      L, u, v は,そのまま

    上に示したRGBと各種の色空間との変換式は,Web上の複数の情報を参考にしています.特に Charles Poynton のサイト http://www.poynton.com/ColorFAQ.html からは多くの情報を得ました.

  • Bayer \rightarrow RGB ( CV_BayerBG2BGR, CV_BayerGB2BGR, CV_BayerRG2BGR, CV_BayerGR2BGR, CV_BayerBG2RGB, CV_BayerGB2RGB, CV_BayerRG2RGB, CV_BayerGR2RGB ) Bayer パターンは,CCD カメラや CMOS カメラなどで広く利用されています.R,G,B の各ピクセル(ある特定のセンサ)が次ように交互に配置された1つのプレーンから,カラー画像を得ることができます.

    \newcommand{\Rcell}{\color{red}R} \newcommand{\Gcell}{\color{green}G} \newcommand{\Bcell}{\color{blue}B} \definecolor{BackGray}{rgb}{0.8,0.8,0.8} \begin{array}{ c c c c c } \Rcell & \Gcell & \Rcell & \Gcell & \Rcell \\ \Gcell & \colorbox{BackGray}{\Bcell} & \colorbox{BackGray}{\Gcell} & \Bcell & \Gcell \\ \Rcell & \Gcell & \Rcell & \Gcell & \Rcell \\ \Gcell & \Bcell & \Gcell & \Bcell & \Gcell \\ \Rcell & \Gcell & \Rcell & \Gcell & \Rcell \end{array}

    出力される各ピクセルのRGB値は,同色のピクセルの 1隣接,2隣接 あるいは4隣接を用いた補間により求められます. 上述のパターンには,いくつかのバリエーションが存在します.それらは,パターンを1ピクセルだけ左にシフト,さらに(あるいは)1ピクセルだけ上にシフトすることで得られます. また,変換定数

    CV_Bayer C_1 C_2 2BGR

    CV_Bayer C_1 C_2 2RGB に現れる2つの文字 C_1C_2 は,パターンの種類を表しています. つまり,この2文字は,あるパターンの2行目の2,3番目の成分であり,例えば,上述の図で表されたパターンは,まさに “BG” タイプです.

cv::distanceTransform

void distanceTransform(const Mat& src, Mat& dst, int distanceType, int maskSize)
void distanceTransform(const Mat& src, Mat& dst, Mat& labels, int distanceType, int maskSize)

入力画像中の非0ピクセルから,最も近い0ピクセルまでの距離を,全ての非0ピクセルに対して計算します.

パラメタ:
  • src – 8ビット,シングルチャンネル(2値)の入力画像
  • dst – 求められた距離を値とする出力画像. src と同じサイズの,32ビット,浮動小数点型,シングルチャンネル画像
  • distanceType – 距離の種類. CV_DIST_L1, CV_DIST_L2 あるいは CV_DIST_C
  • mask_size – 距離変換マスクのサイズ.3,5 あるいは CV_DIST_MASK_PRECISE (後者のオプションは,1番目の関数形式でのみサポートされます). CV_DIST_L1 または CV_DIST_C の場合,距離の種類は強制的に 3 になります.なぜなら,この場合 3\times 3 のマスクは 5\times 5 以上のマスクと同じ結果で計算速度が速いからです
  • labels – オプション.出力されるラベルの2次元配列.離散ボロノイ図.このタイプは CV_32SC1 で, src と同じサイズになる.説明を参照してください

関数 distanceTransform は,2値画像の各ピクセルから,最も近い値0のピクセルまでの近似距離または正確な距離を求めます(値が0のピクセルからの距離は,もちろん0).

maskSize == CV_DIST_MASK_PRECISE かつ distanceType == CV_DIST_L2 の場合,この関数は Felzenszwalb04 で述べられているアルゴリズムを実行します.

その他の場合は, Borgefors86 のアルゴリズムが利用されます.つまり,基本移動の組み合わせで0ピクセルに至るまでの最短距離を見つけます. この基本移動とは,水平,垂直,斜め,桂馬飛び(これは 5\times 5 サイズのマスクを利用した場合のみ)移動です. これらの基本移動距離の合計が全長距離となります. 距離関数は対称性をもつはずなので,水平および垂直移動のコスト(これを a で表します)は全て等しくなければいけません.同様に,斜め移動のコスト(これを b で表します)もすべて等しく,桂馬飛び移動のコスト(これを c で表します)もすべて等しくなくてはいけません.距離の種類が CV_DIST_CCV_DIST_L1 の場合,距離は正確に計算されますが, CV_DIST_L2 (ユークリッド距離)の場合は,距離にいくらかの相対誤差( 5\times 5 マスクを用いると精度が向上する)が含まれます.OpenCVでは, a , b および c の値として,元論文で述べられている値を利用しています:

CV_DIST_C (3\times 3) a = 1, b = 1
CV_DIST_L1 (3\times 3) a = 1, b = 2
CV_DIST_L2 (3\times 3) a=0.955, b=1.3693
CV_DIST_L2 (5\times 5) a=1, b=1.4, c=2.1969

通常は,高速化のために,粗い距離推定 CV_DIST_L1 では 3\times 3 のマスクが利用され, より正確な距離推定 CV_DIST_L2 では 5\times 5 のマスクが利用されます.

粗い推定と正確な推定のどちらのアルゴリズムも,ピクセル数に対して線形であることに注意してください.

2番目の関数形式は,各ピクセル (x, y) に対する最小距離だけでなく,0ピクセルで構成された連結成分のうち最も近いものを特定します. そして,その連結成分のインデックスが \texttt{labels}(x, y) に格納されます.検出された0ピクセルの連結成分は,この関数によってマークされます.

このモードでも,計算量は線形です.つまり,この関数を使って,2値画像に対するボロノイ図を非常に高速に計算できるということです.現在のところ,この2番目の形式では,近似距離変換アルゴリズムのみが利用可能です.

cv::floodFill

int floodFill(Mat& image, Point seed, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4)
int floodFill(Mat& image, Mat& mask, Point seed, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4)

連結成分を指定した色で塗りつぶします.

パラメタ:
  • image – 1または3チャンネル,8ビットまたは浮動小数点型の入出力画像.フラグ CV_FLOODFILL_MASK_ONLY が指定されている場合を除き,この関数によって書き換えられます(2番目の関数形式の場合.以下を参照してください)
  • mask – (2番目の形式の場合のみ)オプション.8ビット,シングルチャンネルのマスク画像.入力画像よりも,幅高さ共に2ピクセルずつ大きくなります.関数はこのマスク画像を利用し更新を行うので,ユーザは mask の中身をきちんと初期化しておかなければいけません.この塗りつぶしは,マスク画像中の0ではないピクセルを飛び越えることはできません.例えば,エッジ検出の出力画像は,塗りつぶしをエッジ部分で堰き止めるためのマスク画像として利用できます.また,塗りつぶされる領域同士が重ならないよう,複数回の関数呼び出しで同じマスク画像を利用することができます. 注意 :マスク画像は塗りつぶされる画像よりも大きいので, image 中のピクセル (x,y) に対応する mask 中のピクセルは (x+1,y+1) となります
  • seed – 連結成分の開始点
  • newVal – 領域の塗りつぶしに使う新しいピクセル値
  • loDiff – 現在の対象ピクセルと,その連結成分に属する隣接ピクセルの1つとの間での,あるいは連結成分に追加されるシードピクセルとの間での,輝度値/色の差の許容下限値
  • upDiff – 現在の対象ピクセルと,その連結成分に属する隣接ピクセルの1つとの間での, あるいは連結成分に追加されるシードピクセルとの間での,輝度値/色の差の許容上限値
  • rect – オプション.この関数によって塗りつぶされた領域の最小の包含矩形がセットされる出力パラメータ
  • flags

    処理フラグ.下位ビットには,連結性を表す値である 4(デフォルト)あるいは 8 が含まれ,これらの値は関数内部で利用されます.この連結性は,どの隣接ピクセルを処理するべきかを定義します.上位ビットは,0 あるいは以下のフラグの組み合わせ:

    • FLOODFILL_FIXED_RANGE これが指定されている場合,現在のピクセルとシードピクセルとの間の差だけが考慮されます.指定されていなければ,隣接ピクセル同士の差が考慮されます(つまり,差の許容範囲が変動します)
    • FLOODFILL_MASK_ONLY (2番目の関数形式の場合のみ)これが指定されている場合,この関数は画像を塗りつぶさずに(引数 new_val は無視されます),マスクを塗りつぶします

関数 floodFill は,指定された色で連結成分を塗りつぶします.塗りつぶしは,シードピクセルから開始されます.連結しているかどうかは,隣接ピクセル値同士の色/輝度値の距離によって決まります. (x,y) のピクセルが塗りつぶされる領域に属していると見なされるのは,以下の場合です:

  • グレースケール画像,変動範囲

    \texttt{src} (x',y')- \texttt{loDiff} \leq \texttt{src} (x,y)  \leq \texttt{src} (x',y')+ \texttt{upDiff}

  • グレースケール画像,固定範囲

    \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)- \texttt{loDiff} \leq \texttt{src} (x,y)  \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)+ \texttt{upDiff}

  • カラー画像,変動範囲

    \texttt{src} (x',y')_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} (x',y')_r+ \texttt{upDiff} _r

    \texttt{src} (x',y')_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} (x',y')_g+ \texttt{upDiff} _g

    \texttt{src} (x',y')_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} (x',y')_b+ \texttt{upDiff} _b

  • カラー画像,固定範囲

    \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_r+ \texttt{upDiff} _r

    \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_g+ \texttt{upDiff} _g

    \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_b+ \texttt{upDiff} _b

ここで, src(x',y') は,ある隣接ピクセルのピクセル値を表します.つまり,対象ピクセルの色/輝度値が,次の値に十分近い場合に連結成分に追加されます:

  • 変動範囲の場合:既に連結成分に属する隣接ピクセルの色/輝度値
  • 固定範囲の場合:シードピクセルの色/輝度値.

これらの関数を利用すると,連結成分を指定色で塗りつぶしてマークする,マスクを作成して輪郭を抽出する,あるいは領域を別の画像にコピーする,といったことが可能になります.この関数の様々なモードは,サンプル floodfill.c でデモされます.

参考: findContours()

cv::inpaint

void inpaint(const Mat& src, const Mat& inpaintMask, Mat& dst, double inpaintRadius, int flags)

選択領域内の画像を修復します.

パラメタ:
  • src – 入力画像.8ビット,1あるいは3チャンネル
  • inpaintMask – 8ビット,1チャンネルの修復マスク.非0のピクセルが,修復が必要な領域を表します
  • dstsrc と同じサイズ,同じタイプの出力画像
  • inpaintRadius – 修復される点(これはアルゴリズムにより判断されます)周りの円形の近傍領域の半径
  • flags

    修復手法.以下のいずれか:

    • INPAINT_NS ナビエ・ストークス(Navier-Stokes)ベースの手法
    • INPAINT_TELEA Alexandru Telea による手法 Telea04

関数 inpaint は,選択された画像領域を,その領域境界付近のピクセルを利用して再構成します.この関数は,スキャンされた写真からごみや傷を除去したり,静止画や動画から不要な物体を削除したりするために利用されます.詳しくは http://en.wikipedia.org/wiki/Inpainting を参照してください.

cv::integral

void integral(const Mat& image, Mat& sum, int sdepth=-1)
void integral(const Mat& image, Mat& sum, Mat& sqsum, int sdepth=-1)
void integral(const Mat& image, Mat& sum, Mat& sqsum, Mat& tilted, int sdepth=-1)

インテグラルイメージを求めます.

パラメタ:
  • image – 入力画像, W\times H の8ビット,あるいは浮動小数点型(32f または 64f)
  • sum – インテグラルイメージ, (W+1)\times (H+1) の32ビット整数,あるいは倍精度浮動小数点型(64f)
  • sqsum – 各ピクセル値を2乗した画像に対するインテグラルイメージ, (W+1)\times (H+1) の倍精度浮動小数点型(64f)
  • tilted – 45度回転した画像に対するインテグラルイメージ, (W+1)\times (H+1) で,データの型は sum と同じ
  • sdepth – インテグラルイメージ,傾いたインテグラルイメージのビット深度. CV_32S , CV_32F あるいは CV_64F

関数 integral は,入力画像に対する1つあるいは複数のインテグラルイメージを次のように求めます:

\texttt{sum} (X,Y) =  \sum _{x<X,y<Y}  \texttt{image} (x,y)

\texttt{sqsum} (X,Y) =  \sum _{x<X,y<Y}  \texttt{image} (x,y)^2

\texttt{tilted} (X,Y) =  \sum _{y<Y,abs(x-X+1) \leq Y-y-1}  \texttt{image} (x,y)

このようなインテグラルイメージを用いると,画像中の任意の矩形領域(あるいは45度回転した矩形領域)の画素値の総和,平均,標準偏差を定数時間で計算できます.例えば:

\sum _{x_1 \leq x < x_2,  \, y_1  \leq y < y_2}  \texttt{image} (x,y) =  \texttt{sum} (x_2,y_2)- \texttt{sum} (x_1,y_2)- \texttt{sum} (x_2,y_1)+ \texttt{sum} (x_1,x_1)

これを用いて,例えば,窓サイズ可変な平滑化や相関演算を高速に計算することが可能です.マルチチャンネル画像の場合は,各チャンネルでの総和が個別に累積されます.

実際の例として,次の図では,直立した矩形 Rect(3,3,3,2) のインテグラルイメージと傾いた矩形 Rect(5,1,2,3) のインテグラルイメージの計算について示します.インテグラルイメージ sumtilted 中の関連ピクセルと一緒に,その元画像 image における選択ピクセルが表示されています.

begin{center}

_images/integral.png

end{center}

cv::threshold

double threshold(const Mat& src, Mat& dst, double thresh, double maxVal, int thresholdType)

配列の要素に対して,ある定数での閾値処理を行います.

パラメタ:
  • src – 入力配列(シングルチャンネル,8ビット,あるいは32ビット浮動小数点型)
  • dstsrc と同じサイズ,同じタイプの出力配列
  • thresh – 閾値
  • maxVal – 閾値処理の種類が THRESH_BINARYTHRESH_BINARY_INV の場合に利用される,最大値の値
  • thresholdType – 閾値処理の種類(以下の説明を参照してください)

この関数は,シングルチャンネルの配列に対して,ある定数での閾値処理を行います.これは,グレースケールからの2値画像生成(関数 compare も,この目的に利用できます)やノイズ除去(つまり,小さすぎたり大きすぎたりする値をはじく処理)などに利用される場合が多いです.この関数がサポートする閾値処理にはいくつかの種類があり,それは引数 thresholdType によって決定されます:

  • THRESH_BINARY

    \texttt{dst} (x,y) =  \fork{\texttt{maxVal}}{if $\texttt{src}(x,y) > \texttt{thresh}$}{0}{otherwise}

  • THRESH_BINARY_INV

    \texttt{dst} (x,y) =  \fork{0}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{maxVal}}{otherwise}

  • THRESH_TRUNC

    \texttt{dst} (x,y) =  \fork{\texttt{threshold}}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{src}(x,y)}{otherwise}

  • THRESH_TOZERO

    \texttt{dst} (x,y) =  \fork{\texttt{src}(x,y)}{if $\texttt{src}(x,y) > \texttt{thresh}$}{0}{otherwise}

  • THRESH_TOZERO_INV

    \texttt{dst} (x,y) =  \fork{0}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{src}(x,y)}{otherwise}

また,特殊な値 THRESH_OTSU を,上述のものと組み合わせて使うこともできます.この場合,関数は大津のアルゴリズムを用いて最適な閾値を決定し,それを引数 thresh で指定された値の代わりに利用します.この関数は,計算された閾値を返します.また現在のところ,大津の手法は 8ビット画像に対してのみ実装されています.

_images/threshold.png

参考: adaptiveThreshold() , findContours() , compare() , min() , max()

cv::watershed

void watershed(const Mat& image, Mat& markers)

watershedアルゴリズムを用いて,マーカベースの画像セグメンテーションを行います.

パラメタ:
  • image – 8ビット,3チャンネルの入力画像
  • markers – 32ビット,シングルチャンネルの,マーカ入出力画像(マップ). image と同じサイズ

この関数は,参考文献 Meyer92 で述べられた,ノンパラメトリックなマーカベースのセグメンテーションアルゴリズムである Watershed のバリエーションの1つを実装したものです. 画像をこの関数に渡す前に,ユーザは画像をどのような領域に分割したいかを大まかに決めて,それを正( >0 )のインデックスで markers 内に書き込んでおく必要があります.つまり,その場合の各領域は,1,2,3と いったピクセル値をもつ1つあるいは複数の連結成分で表現されます(このようなマーカは, findContoursdrawContours を用いて2値マスクから抽出できます. watershed.cpp を参照してください). そして,このような連結成分は,画像領域分割のための「シード」となります.また, markers 内のその他のピクセルは,どの領域に属するかが未知であり,それはこのアルゴリズムによって定義されますが,まずは最初に 0 にセットされなければいけません. この関数の出力である markers 内の各ピクセルには,「シード」成分の値の1つがセットされます.また,領域の境界に位置するピクセルの場合は -1 がセットされます.

2つの隣接した連結成分が,必ずしも watershed 境界(-1 の値をもつピクセル)によって分割されるわけではないことに注意してください.例えば,初期 marker に接線成分が存在する場合などがこれにあたります.この関数の実際のデモと使用例については,OpenCVサンプルディレクトリにある watershed.cpp デモを参照してください.

参考: findContours()

目次

前のトピックへ

画像の幾何学変換

次のトピックへ

ヒストグラム

このページ