[Computer Vision] 画像処理の基本操作

画像平滑化フィルタ処理

画像の平滑化とは、センサーや大気などの影響により、リモートセンシング画像に明るさが過度に変化する部分や輝点(ノイズとも呼ばれます)が現れることを意味します。このノイズを抑えるために画像の明るさを平滑化する処理方法が画像平滑化です。画像のスムージングは​​実際にはローパス フィルター処理であり、スムージング プロセスにより画像のエッジがぼやけます。

平均フィルター

線形フィルタリングは画像マトリクス全体に作用します。

  • 特徴: ウィンドウサイズが大きいほどノイズ除去効果は高くなりますが、当然計算時間も長くなり、画像の歪みも大きくなります。実際の処理では、歪み効果とノイズ除去効果のバランスをとり、適切なウィンドウ サイズを選択する必要があります。
  • 【メリット】 アルゴリズムがシンプルで複雑な画像処理技術を必要とせず、多くの時間とスペースを必要としません。また、ノイズを効果的に除去し、画質を向上させることができます。
  • 【短所】 平均値フィルター自体に欠陥があり、画像の細部をしっかり保護できず、画像のノイズを除去する際に画像の細部を破壊してしまうため、画像がぼやけてしまい、ノイズ点をうまく除去できません。
  • 【適用範囲】ソルトアンドペッパーノイズ
  • 【不適な範囲】低照度、ノイズの強い画像
計算プロセス

特定のウィンドウ サイズに対して、ウィンドウ内の値が平均され、中央値がウィンドウの中心値として使用されます。たとえば、「3」と入力すると、3 × 3 3 \times 3を使用することになります。3×3ウィンドウは、指定された画像マトリックスのピクセル値を再計算します。[注: エッジ上のピクセル (3 × 3 3 \times 33×3 )、いくつかの有効なピクセルを計算します]
以下の図に示すように、最初の行と最初の列のピクセル 1 について、それを中心として、オレンジ色の領域の平均値を新しい値として取得します。
画像の説明を追加してください

Pythonの実装
import cv2
import numpy as np

x = np.array([[1, 3, 2, 4, 6, 5, 7]])
# 对图像进行均值滤波,指定核大小为5x5
result1 = cv2.blur(x, (3, 3))
print(result1)

ガウスフィルター

線形フィルタリングは画像マトリクス全体に作用します。

  • 【特徴】
    1. ガウス フィルタリングでは、カーネルの幅と高さは異なっていてもかまいませんが、両方とも奇数である必要があります。
    2. 平均フィルタリングの場合、その近傍の各ピクセルの重みは等しくなります。ガウス フィルタリングでは、中心点の重み値が増加し、中心点から遠い点の重み値が減少します。これに基づいて、近傍の各ピクセル値の異なる重み値の合計が計算されます。 。
    3. ガウス カーネルは、同じく 2 次元のフィルタ行列であるコンボリューション カーネルとみなすことができます。違いは、ガウス カーネルが通常のコンボリューション カーネルに基づいて重み付けされることです (重み行列はガウス関数によって計算されます)。 )。
  • 【メリット】 画像のノイズや詳細情報を除去しつつ、画像の主な特徴(画像の輪郭やエッジなど)を保持し、ガウスフィルターのぼけ具合をサイズや標準偏差を調整することで制御できるガウスカーネルの。
  • 【デメリット】 ガウスフィルターは畳み込み演算が必要なため、計算量が高くなります。
  • 【適用範囲】ガウスノイズの除去
計算プロセス

ガウス フィルタリングは通常 2 つの方法で実装され、1 つは離散化ウィンドウ スライディング ウィンドウ畳み込み、もう 1 つはフーリエ変換によるものです。以下は、離散化ウィンドウ スライディング ウィンドウ畳み込みを使用して実装されたガウス フィルター処理です。
一般的に使用されるガウス テンプレートは次のとおりです。画像の説明を追加してください上記のパラメータはガウス関数を通じて計算されます。ガウス フィルタリングに関するいくつかの理解を参照してください。
具体的な操作は次のとおりです。テンプレート (またはコンボリューション、マスク) を使用して画像内の各ピクセルをスキャンし、テンプレートによって決定された近傍のピクセルの加重平均グレー値を使用して、テンプレートの中心ピクセルの値を置き換えます。 詳細については、ガウス フィルタリング
を参照してください。

Pythonの実装
import numpy as np
import cv2

x = np.array([[1, 3, 2, 4, 6, 5, 7]])
# (3,3)为滤波器的大小;1.3为滤波器的标准差,如果标准差这个参数设置为0,则程序会根据滤波器大小自动计算得到标准差。
pic = cv2.GaussianBlur(x, (1, 3), 1.3, 1.3)
print(pic)

メディアンフィルター

非線形フィルタリング。ウィンドウの中間点となる画像マトリクス内のピクセルをターゲットとします。

  • [利点] インパルスノイズの平滑化に非常に効果的であると同時に、画像の鋭いエッジを保護し、適切な点を選択して汚れた点の値を置き換えることができるため、処理効果は良好です。
  • 【デメリット】画像の不連続性が生じやすい、ソート演算のため平均値フィルタに比べて画像サイズが大きいと処理が遅くなる。
  • [適用範囲] ごま塩ノイズ、加算ガウスノイズなどのランダムノイズを除去します。
  • 【不適範囲】 継続的なノイズには不向きです。
計算プロセス

特定のウィンドウ サイズについて、ウィンドウ内の値を並べ替え、中央の値をウィンドウの中心値として使用します。たとえば、「3」と入力すると、3 × 3 3 \times 3を使用することになります。3×3ウィンドウは、指定された画像マトリックスのピクセル値を再計算します。[注: フィルタリングに参加するピクセルはウィンドウの中心点と端のピクセルです (3 × 3 3 \times 3 に3×ウィンドウの中心点3 ) は計算されません。

下の図は6 × 6 6\times 6を示しています6×6 枚の画像マトリックスにメディアン フィルタリングが適用され、青色の値がスライディング ウィンドウ、赤色の値がフィルタリングされた値です。図に示すように、エッジ ピクセルは計算に関与せず、実際に計算に関与するピクセル値はウィンドウの中心点になります。
画像の説明を追加してください

Pythonの実装
import scipy.signal as ss
x = [1, 3, 2, 4, 6, 5, 7]
pic = ss.medfilt(x, 3)
print(pic)

画像エッジ検出

画像エッジとは、一般に画像の階調変化率が最も大きい位置を指す。主な理由は次のとおりです。

  1. 画像のグレー レベルは、表面の法線方向に不連続に変化します。

  2. 画像内のオブジェクトの空間深度は一貫していません。

  3. 滑らかな表面では色が不均一になります。

  4. 画像内のオブジェクトの光と影

エッジ検出とは、画像からエッジ点とエッジ セグメントを検出し、エッジの方向を記述するプロセスを指します。

ロバートオペレーター

一次微分演算子は、斜め偏差の勾配計算方法であり、勾配の大きさはエッジの強さを表し、勾配の方向はエッジの方向に対して垂直(直交)である。

  • 【メリット】 計算が簡単でエッジの位置決めが正確です。
  • 【デメリット】ノイズに敏感
  • 【適用範囲】 急峻な(エッジが目立つ)低ノイズな画像の処理が得意
  • -【対象外】ノイズの多い画像
計算プロセス

x 方向のロバート演算子勾配ウィンドウ:
G x = [ 1 0 0 − 1 ] G_x=\begin{bmatrix}1 &0\\ 0&-1 \end{bmatrix}G×=[100 1]
y 方向のロバート演算子の勾配ウィンドウ:
G x = [ 0 1 − 1 0 ] G_x=\begin{bmatrix}0 &1\\ -1&0 \end{bmatrix}G×=[0 110]
画像行列内のピクセルの勾配合計 (最大絶対値または 2 つの平方根):
G = ∣ G x ∣ + ∣ G y ∣ G=|G_x|+|G_y|G=∣G _×+∣G _はい

上記の 2 つのグラデーション ウィンドウとその加算方法を取得した後、それらを画像マトリックスに適用します。画像マトリックスの最後の行と最後の最初の列は計算に関与せず、直接 0 に設定されることに注意してください。上記の計算の考え方は、(x 1 2, y 1 2) (x_\frac{1}{2},y_\frac{1}{2}) を計算することと同じであるため、( ×21y21)グラデーション。

Pythonの実装
import numpy as np

def Roberts(img_arr,r_x, r_y):
    w, h = img_arr.shape
    res = np.zeros((w, h))  # 取一个和原图一样大小的图片,并在里面填充0
    for x in range(w-2):
        for y in range(h-2):
            sub = img_arr[x:x + 2, y:y + 2]
            roberts_x = np.array(r_x)
            roberts_y = np.array(r_y)
            var_x =sum(sum(sub * roberts_x))#矩阵相乘,查看公式,我们要得到是一个值,所以对它进行两次相加
            var_y = sum(sum(sub * roberts_y))

            var = abs(var_x) + abs(var_y)

            res[x][y] = var#把var值放在x行y列位置上
    return res
pic_arr = np.array([[0, 0, 0, 0], [0, 10, 10, 0], [0, 10, 10, 0], [0, 0, 0, 0]])
r_x = [[1, 0], [0, -1]]
r_y = [[1, 1], [-1, 0]]
pic = Roberts(pic_arr, r_x, r_y)
print(pic)

画像処理

腐食オペレーター

画像マトリクスの各ピクセルに対して計算されます。

  • 特徴: 画像の腐食はハイライト部分と比較され、対応する 2 値画像は白い部分と比較されます。一般的に、腐食とは、白い部分が元の形で縮小し、黒い部分が膨張し、腐食することを指します。拡張操作。
  • 【適用範囲】
    1. ノイズを除去する

    2. 画像の分割と結合

    3. 極大値と極小値を見つける (画像に対する数学的畳み込み演算)

    4. 画像のグラデーションを見つける

計算プロセス

ピクチャ行列 (0/1 行列) とテンプレート行列 (コンボリューション カーネルとも呼ばれる、0/1 値) を入力します。テンプレート マトリックスで「中心」とマークされたピクセルを参照として使用し、画像マトリックスでピクセルごとに変換します。[テンプレート マトリックス内の値 1 を持つピクセル] と [画像マトリックス内の対応するサイズのピクセル] の「AND」をとり、結果の最小値を現在のピクセルに割り当てます。画像行列の値 1 の形状とテンプレート行列の値 1 の形状が同じ部分のみが保持されます。
たとえば、下の図では、B はテンプレート行列 (B の「原点」は中心点を意味します)、X は画像行列、XB は腐食後の結果を意味します。この結果は、B の黒い部分と X の黒い部分の「AND」演算とみなすことができます。
画像の説明を追加してください

Pythonの実装

Hog (勾配方向のヒストグラム) 機能

計算プロセス:
  1. 画像の前処理: 画像をグレースケールに変換し、ピクセル値を正規化します。画像に強い反射などの不安定な明るさがある場合は、照明の正規化などの処理が必要です。

  2. 勾配と方向のヒストグラムを計算します。画像に対して畳み込み演算を実行して勾配の大きさと方向を取得し、画像をいくつかの小さなブロック (たとえば、8 × 8 8\ times8)に分割します。8×8つの小ブロック)を用いて、各小ブロック内の勾配方向をカウントし、小ブロック内の勾配方向ヒストグラムを求める。

  3. 正規化: 照明や影などの要因の影響を避けるために、各小さなブロック内の勾配方向のヒストグラムを正規化します。

  4. スプライシング: すべての小さなブロックの正規化されたヒストグラムを、HOG 特徴ベクトルと呼ばれる大きなベクトルに結合します。

ホッグの特徴寸法計算式

例:
指定された解像度H × W = 100 × 100 H\times W = 100 \times 100H×W=100×100の画像の場合、セルのピクセル サイズはcellsize = 8 × 8 cell_{size}=8\times8 でセル_ __=8×8、各セルのヒストグラム ビンの数= 9 bins=9ビン_=9 、 4 × 4 4\times4ごと4×4つのセルがブロックブロックをブロックスキャン ステップ サイズは8 8です8ピクセル。
次に、グラフの Hog 特徴の次元は次のように計算されます。

  1. ブロックサイズ = ( 4 × 8 ) × ( 4 × 8 ) = 32 × 32 block_{size}= (4 \times 8)\times(4 \times 8)=32\times32ブロック_ _ __=( 4×8 )×( 4×8 )=32×32
  2. ブロックストライド = セルサイズ = 8 block_{ストライド} =セル_{サイズ}=8ブロック_ _ _ストライド_ _ _ _ _=セル_ __=8
  3. ブロック H / W = ( H ( W ) − ブロックサイズ ) ブロックストライド + 1 = 9 block_{H/W}=\frac{(H(W)-block_{size})}{block_{stride}}+1=9ブロック_ _ _H / W=ブロック_ _ _ストライド_ _ _ _ _( H ( W ) ブロック_ _ __)+1=9
  4. ブロック番号 = 9 × 9 = 81 ブロック_{番号} =9\times9=81ブロック_ _ _番号_ _=9×9=81
  5. 特徴の次元 =ビン × ブロック番号 × 各ブロックに含まれるセルの数 = 9 × 81 × 16 = 11664 ビン\times block_{num}\times 各ブロックに含まれるセルの数 = 9\times 81\times 16=11664ビン_×ブロック_ _ _番号_ _×ブロックにセル含まれます=9×81×16=11664

上記の計算方法により、NNが得られます。N次元の HOG 固有ベクトル。

Pythonの実装
import cv2
import numpy as np

gray_pic = np.ones(shape=(32, 64), dtype=np.uint8)

# 为HOG描述符指定参数

# 像素大小(以像素为单位)(宽度,高度)。 它必须小于检测窗口的大小,
# 并且必须进行选择,以使生成的块大小小于检测窗口的大小。
cell_size = (4, 4)

# 每个方向(x,y)上每个块的单元数。 必须选择为使结果
# 块大小小于检测窗口
num_cells_per_block = (2, 2)

# 块大小(以像素为单位)(宽度,高度)。必须是“单元格大小”的整数倍。
# 块大小必须小于检测窗口。
block_size = (num_cells_per_block[0] * cell_size[0],
              num_cells_per_block[1] * cell_size[1])

# 计算在x和y方向上适合我们图像的像素数
x_cells = gray_pic.shape[1] // cell_size[0]
y_cells = gray_pic.shape[0] // cell_size[1]

# 块之间的水平距离,以像元大小为单位。 必须为整数,并且必须
# 将其设置为(x_cells-num_cells_per_block [0])/ h_stride =整数。
h_stride = 1

# 块之间的垂直距离,以像元大小为单位。 必须为整数,并且必须
# 将其设置为 (y_cells - num_cells_per_block[1]) / v_stride = integer.
v_stride = 1

# 块跨距(以像素为单位)(水平,垂直)。 必须是像素大小的整数倍。
block_stride = (cell_size[0] * h_stride, cell_size[1] * v_stride)

# 梯度定向箱的数量
num_bins = 9


# 指定检测窗口(感兴趣区域)的大小,以像素(宽度,高度)为单位。
# 它必须是“单元格大小”的整数倍,并且必须覆盖整个图像。
# 由于检测窗口必须是像元大小的整数倍,具体取决于您像元的大小,
# 因此生成的检测窗可能会比图像小一些。
# 完全可行
win_size = (x_cells * cell_size[0], y_cells * cell_size[1])

# 输出灰度图像的形状以供参考
print('\nThe gray scale image has shape: ', gray_pic.shape)
print()

# 输出HOG描述符的参数
print('HOG Descriptor Parameters:\n')
print('Window Size:', win_size)
print('Cell Size:', cell_size)
print('Block Size:', block_size)
print('Block Stride:', block_stride)
print('Number of Bins:', num_bins)
print()

# 使用上面定义的变量设置HOG描述符的参数
hog = cv2.HOGDescriptor(win_size, block_size, block_stride, cell_size, num_bins)

# 计算灰度图像的HOG描述符
hog_descriptor = hog.compute(gray_pic)
print(hog_descriptor.shape)

通常のコンボリューション/プーリングの出力サイズと受容野の計算式

通常の畳み込みの出力サイズ

入力サイズをW × HW \times Hとします。W×H、畳み込みカーネルのサイズはk × kk \times kk×kステップ サイズはSSSパッドはPPP
出力サイズ—H=H − k + 2 PS + 1 \frac{H-k+2P}{S}+1SH k + 2 P+1出力
サイズ—W=W − k + 2 PS + 1 \frac{W-k+2P}{S}+1SW k + 2 P+1

プーリング操作の出力サイズ

入力サイズをW × HW \times Hとします。W×H、プーリング カーネル サイズはk × kk \times kk×kステップ サイズはSSS
出力サイズ—H=H − k S + 1 \frac{Hk}{S}+1SH k+1出力
サイズ—W=W − k S + 1 \frac{Wk}{S}+1SW k+1

畳み込みの受容野

これは深いところから浅いところへのプロセスです。2 層の畳み込み (k=3、s=2、p=1) の後、 128 × 128 128\times128が得られることが知られています。128×128特徴マップ。この特徴マップの受容野を尋ねてから、受容野を逆に計算してください:
RFN − 1 = f ( RFN , kernel , stride ) = ( RFN − 1 ) × stride + kernel RF_{N-1} =f (RF_N,カーネル,ストライド)=(​​RF_N-1)\times ストライド + カーネルR FN 1=f ( R FNカーネル_ _ _ _ストライド_ _ _ _ _=( RF _N1 )×ストライド_ _ _ _ _+ker n e l上記の例: (
((1-1)*2+3)-1)*2+3=7

さまざまな畳み込みの計算量とパラメータ

入力特徴マップの形状をH 1 × W 1 × C in H_1\times W_1\times C_{in}とします。H1×W1×C、畳み込みカーネルのサイズはk × k × C cink\times k \times C_{cin}です。k×k×C_、出力特徴マップの形状はH 2 × W 2 × C out H_2\times W_2 \times C_{out}です。H2×W2×Cあなた_

従来のコンボリューションの計算量とパラメータ

計算量= k × k × C in × H 2 × W 2 × C outk\times k\times C_{in}\times H_{2}\times W_{2} \times C_{out}k×k×C×H2×W2×Cあなた_
参数= k × k × C in × C outk\times k\times C_{in}\times C_{out}k×k×C×Cあなた_

グループ化された畳み込み

計算量= k × k × C in × H 2 × W 2 × C out × 1 gk\times k\times C_{in}\times H_{2}\times W_{2} \times C_{out}\times \frac{1}{g}k×k×C×H2×W2×Cあなた_×g1
参数= k × k × C in × C out × 1 gk\times k\times C_{in}\times C_{out} \times \frac{1}{g}k×k×C×Cあなた_×g1

深度分解コンボリューションの計算量とパラメータ

計算量= k × k × H 2 × W 2 × C in + H 2 × W 2 × C out × C ink\times k\times H_2\times W_2\times C_{in}+H_{2}\times W_ {2} \times C_{out}\times C_{in}k×k×H2×W2×C+H2×W2×Cあなた_×C
参数= k × k × C in + C in × C outk\times k\times C_{in} +C_{in} \times C_{out}k×k×C+C×Cあなた_

深さ分解可能な畳み込みの計算量 従来の畳み込みの計算量 = 1 C out + 1 k 2 \frac{深さ分解可能な畳み込みの計算量}{従来の畳み込みの計算量}=\frac{1}{C_ {out}} +\frac{1}{k^2}従来の畳み込み演算の計算量深さ方向に分解可能な畳み込みの計算=Cあなた_1+k21

バッチノーム層の操作

入力:x = [ x ( 1 ) , x ( 2 ) , . , x ( m ) ] x= [x^{(1)},x^{(2)},...,x^{(m)}]バツ=[ ×( 1 )バツ( 2 )... バツ( m ) ],その中x ( i ) ∈ R nx^{(i)} \in R^{n}バツ()Rn はii 番目の入力私はサンプルを作ります。

平均を計算します: μ = 1 m ∑ i = 1 mx ( i ) \mu = \frac{1}{m}\sum_{i=1}^{m} x^{(i)}メートル=メートル1i = 1メートルバツ()

解: σ 2 = 1 m ∑ i = 1 m ( x ( i ) − μ ) 2 \sigma^{2} = \frac{1}{m}\sum_{i=1}^{m}(x ^ {(i)} - \mu)^{2}p2=メートル1i = 1メートル( ×()メートル2

形式: x^(i) = x(i) − μ σ 2 + ϵ \hat{x}^{(i)} = \frac{x^{(i)} - \mu}{\sqrt{ \sigma ^{2}+\epsilon}}バツ^()=p2 +ϵ バツ( i )m

ここで、ϵ \εϵは非常に小さい数なので、分母0 00

スケーリングとオフセット: y ( i ) = γ x ^ ( i ) + β y^{(i)} = \gamma\hat{x}^{(i)} + \betay()=cバツ^()+βどこγ
\ガンマcb \betaβ は、正規化された結果をスケールおよびオフセットするために使用される学習可能なパラメーターです。

トレーニング中に、各ミニバッチの平均と分散が計算され、入力データの正規化に使用されます。テスト中、すべてのトレーニング サンプルの平均と分散が正規化に使用されます。

Batchnorm 層の学習可能なパラメータ

  1. γ \ガンマγ : スケーリング パラメーター。ネットワークの表現力を高めるために正規化された特徴をスケーリングするために使用されます。

  2. β \ベータβ : オフセット パラメータ。正規化された特徴をオフセットしてネットワークの表現力を高めるために使用されます。

これら 2 つのパラメーターは、バックプロパゲーション アルゴリズムを通じてトレーニングされます。推論フェーズ中、これらのパラメーターの値は、固定されたフィーチャのスケールとオフセットに使用されるため、変更されません。

おすすめ

転載: blog.csdn.net/qq_42312574/article/details/132061458