1. 説明
デジタル時代において、画像は私たちのコミュニケーションと表現に不可欠な部分です。ソーシャル メディアから医療画像まで、画像の品質と内容は重要です。ここで、画像フィルタリングとコンボリューションの分野が介入し、これらの視覚的な物語を変換および洗練するためのツールキットを提供します。
画像フィルタリングは、写真の見栄えを良くするだけではなく、画像にストーリーを持たせることも目的としています。医療スキャンのノイズを軽減する場合でも、考古学的遺物の複雑な細部を鮮明にする場合でも、自動運転車のエッジを検出する場合でも、画像フィルターは重要な役割を果たします。彼らは、特定の特徴を強調し、他の特徴を抑制することによって物語を形作ります。
このプロセスのバックボーンは畳み込み演算です。これは、事前定義されたフィルターで画像をオーバーレイしてさまざまな効果を実現できる数学的な驚異です。
2. 畳み込みの概念
畳み込みは、画像処理において重要な役割を果たす基本的な数学演算です。これは、画像にフィルターを適用するための基礎となるテクノロジーであり、ぼかし、シャープ化、エッジ検出などのタスクを可能にします。
畳み込みの核心は、2 つの関数を組み合わせて 3 番目の関数を生成することです。画像処理では、関数の 1 つは入力画像であり、もう 1 つはカーネルまたはフィルターと呼ばれる小さなマトリックスです。カーネルには、フィルターの動作を定義する数値が含まれています。このプロセスには、画像上でカーネルをスライドさせ、その値を画像内の対応するピクセル値と乗算し、結果を合計することが含まれます。この合計は、出力イメージ内の特定の位置に配置されます。
2.1 1次元の畳み込み
1D 畳み込みのコンテキストでは、入力は 1D 配列で構成され、多くの場合特徴ベクトルと呼ばれます。
最も基本的な畳み込みシナリオでは、この配列と数値 (フィルターまたは重みと呼ばれる) との乗算を実行して、特徴マップと呼ばれる出力配列を生成します。
この場合、最初の配列の次元は 12x1 で、フィルターの次元は 1x1 であるため、生成される出力のサイズは 12x1 のままです。
さらに、以下に示すのはサイズ 2x1 のフィルターです。
ここでは、入力の最初の要素とフィルターの最初の要素を乗算し、入力の 2 番目の要素とフィルターの 2 番目の要素を乗算し、それらを加算して、結果を最初の要素の出力配列に書き込みます。
ここでわかるように、フィルターをこれ以上移動することはできないため、出力はサイズ 11x1 と小さくなります。
2.2 充填
パディングとは、画像の端の周囲にピクセルを追加することです。パディングの目的は、特定のカーネルまたはフィルターを使用して畳み込み演算を適用した後の出力イメージのサイズに影響を与えることです。
以下では、入力配列の両端にゼロを追加するので、最終的に同じサイズの出力になります。
ここまではフィルターを 1 つずつ右に移動しましたが、必ずしもこれを続ける必要はなく、たとえば 3 つ移動することもできます。
2.3 1次元の畳み込み
これで、5x5 グリッドを持つ 8 ビットのグレースケール画像ができました。値の範囲は 0 ~ 255 です。
そして、ランダムな 3x3 カーネルがあります。
カーネルを入力に適用すると、次のようになります。
(-1*170)+(0*245)+(1*0)+(2*234)+(1*42)+(2*64)+(1*32)+(-2*53)+ (0*128)=394
中心ピクセルを計算された値に置き換えます。次に、カーネルを 1 つずつ (左上から右下に) 移動し、再度計算を行います。
ここでもエッジ ピクセルにパディングを使用します。
3. フィルター
画像フィルターの多機能性は、その一連の操作によって実現されます。それぞれの操作には異なる目的があり、画像の美しさを形作ったり、より深い分析を促進したりします。
- スムージングフィルター
- シャープニングフィルター
- エッジ強調フィルター
3.1 スムージングフィルター
ぼかしフィルターとも呼ばれる平滑化フィルターは、ノイズを穏やかに低減し、不要なディテールを抑制し、より調和のとれた視覚体験を生み出すことにより、画質を向上させる驚くべき能力を備えています。
基本的に、平滑化フィルターは、画像のピクセル値を隣接するピクセルと平均化することによって機能します。この平均化プロセスは画像に心地よい効果をもたらし、画像の一貫性と均一性を高めます。結果として得られる画像は、その主な特徴を保持していますが、その本質を覆い隠す可能性のある小さな変動や不一致を取り除きます。
- 箱
- ガウス
- 中位数
3.2 フレームブラー
このフィルターは、定義された近傍内のピクセル値の単純な平均を実行します。近傍のサイズはカーネル サイズと呼ばれます。カーネル サイズが大きくなるほど、画像はぼやけます。
シンプルで効率的な平滑化フィルターです。これは、エッジ検出やノイズ低減などの画像処理アルゴリズムの最初のステップとしてよく使用されます。
import cv2
import numpy as np
import matplotlib.pyplot as plt
path = "cath.jpeg"
# read image
image = cv2.imread(path)
# box blur filter
box_blur = cv2.boxFilter(image, -1, (25, 25))
# plot
plt.figure(figsize=(10, 8))
plt.subplot(2, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 2, 2)
plt.imshow(cv2.cvtColor(box_blur, cv2.COLOR_BGR2RGB))
plt.title('Box Blur')
plt.axis('off')
フレームがぼやけています。画像は作者提供。
私たちが使用する方法では、単純な平均化フィルターが生成されます。boxFilter
cv2
cv.boxFilter(src、d Depth、ksize[、dst[、anchor[、normalize[、borderType]]]]) -> dst
src
入力画像です。ddepth
出力画像の望ましい深さです。-1 に設定すると、出力イメージが入力イメージと同じ深度になります。それ以外の場合は、、、、を使用できます。cv2.CV_8U
cv2.CV_16U
cv2.CV_32F
cv2.CV_64F
ksize
ボックスコアのサイズです。カーネルが大きいほど、スムージング効果が強くなります。dst
はオプションであり、画像を出力します。指定しない場合、関数は新しい出力イメージを作成します。anchor
カーネル内のオプションのアンカー ポイントです。通常、カーネルの中心を表すように設定されます。この設定を変更すると、フィルターされた出力の位置に影響を与える可能性があります。-1, -1
normalize
カーネルがその中の要素の数によって正規化する必要があるかどうかを示すオプションのフラグです。正規化は、画像の明るさを比較的一定に保つのに役立ちます。borderType
画像の境界線を処理する方法を示すオプションのフラグです。
3.3 ガウスフィルター
ガウス分布によって決定される重みを使用して、ピクセル値の加重平均を取得します。隣接するピクセルの重みは、中心ピクセルから遠ざかるにつれて減少します。
ボックスブラーよりも複雑なスムージングフィルターです。ノイズを低減しながら、画像のエッジとディテールをより良く保存します。
gaussian_blur = cv2.GaussianBlur(image, (25, 25), 0)
plt.figure(figsize=(10, 8))
plt.subplot(2, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 2, 2)
plt.imshow(cv2.cvtColor(gaussian_blur, cv2.COLOR_BGR2RGB))
plt.title('Gaussian Blur')
plt.axis('off')
ガウスぼかし。画像は作者提供。
cv.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) -> dst
sigmaX
は、水平方向のガウス カーネルの標準偏差です。値が大きいほどぼかし効果が強くなります。sigmaY
はオプションで、垂直方向のガウス カーネルの標準偏差です。指定しない場合、デフォルトは と同じ値になります。sigmaX
3.4 メディアンフィルター
メディアン フィルターは、画像内の各ピクセル値を隣接するピクセルの中央値に置き換えます。中央値は、並べ替えられた値のリストの中央の値です。これは、メディアン フィルターがノイズ スパイクなどの外れ値の影響を受けないことを意味します。
median_filtered = cv2.medianBlur(image, 25)
plt.figure(figsize=(10, 8))
plt.subplot(2, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title( 'Original Image' )
plt.axis( 'off' )
plt.subplot(2, 2, 2)
plt.imshow(cv2.cvtColor(median_filtered, cv2.COLOR_BGR2RGB))
plt.title( 'Median Filter' )
plt.axis( 'off' )
メディアンフィルター。画像は作者提供。
cv.medianBlur(src、ksize[、dst]) -> dst
4.シャープネスフィルター
シャープニング フィルターは、画像のエッジや細部を強調するために使用される画像処理技術の一種です。画像の細部を滑らかにするぼかしフィルターとは異なり、鮮明フィルターは隣接する領域間のピクセル強度の違いを強調表示するため、エッジが強調され、特徴がより際立ちます。
鮮明化フィルターは、画像の高周波成分を強調することによって機能します。高周波成分は、エッジや細部の特徴であるピクセル値の急速な変化に対応します。
シャープ化フィルタは視覚的に魅力的な効果を生み出すことができますが、使用には注意が必要です。シャープにしすぎるとノイズが増幅され、アーティファクトが発生する可能性があります。多くの場合、すでに品質が高く、ノイズが最小限に抑えられている画像に鮮明化フィルターを適用することをお勧めします。
- ラプラシアンフィルター
- アンシャープマスク
4.1 ラプラシアンフィルター
ラプラシアンフィルターは、画像処理に用いられるエッジ検出フィルターです。これは二次微分フィルターであり、画像の強度の変化率を測定することを意味します。ラプラシアン フィルターは、画像を鮮明にし、エッジを検出するために一般的に使用されます。
laplacian = cv2.Laplacian(image, -1, ksize=5, scale=1,delta=0,borderType=cv2.BORDER_DEFAULT)
plt.figure(figsize=(10, 8))
plt.subplot(2, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 2, 2)
plt.imshow(laplacian)
plt.title('Laplacian Filter')
plt.axis('off')
ラプラシアンフィルター。画像は作者提供。
cv.Laplacian(src、 d Depth[、 dst[、 ksize[、scale[、 delta[、 borderType]]]]]) -> dst
ksize
はオプションで、ラプラシアン演算に使用するカーネル サイズです。、、、などの奇数に設定されます。指定しない場合、デフォルト値は 3x3 コアに対応します。1
3
5
1
scale
はオプションで、計算されたラプラシアン値に適用されるスケーリング係数です。このパラメータは、ラプラシアンの効果を強化または低減するのに役立ちます。delta
はオプションで、計算されたラプラシアン値に加算する値です。出力の全体的な明るさやコントラストを制御するために使用できます。
4.2 アンシャープマスク
これには、元の画像のぼかしたバージョンを (ローパス フィルターを使用して) 作成し、このぼやけたバージョンを元の画像から減算することが含まれます。その結果、エッジと詳細が強調表示された画像が得られます。「アンシャープ」という用語は、画像内のアンシャープなコンテンツを強調表示するマスクを作成することを指します。
シャープネスの量は、ぼかしの量とぼかした画像の重みによって制御されます。ぼかしは通常、ガウスぼかしですが、他のタイプのぼかしも使用できます。ぼやけた画像の重みは通常 0 から 1 の間です。重量が大きいほど、より研ぎやすくなります。
blurred = cv2.GaussianBlur(image, (25, 25), 3)
k = 3
unsharp_mask = cv2.addWeighted(image, k-1, blurred, -1.0, 0)
plt.figure(figsize=(10, 8))
plt.subplot(2, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 2, 2)
plt.imshow(cv2.cvtColor(unsharp_mask, cv2.COLOR_BGR2RGB))
plt.title('Unsharp Masking')
plt.axis('off')
アンシャープマスキング。画像は作者提供。
高ブースト フィルタリングは、アンシャープ マスキングの一般的な形式です。画像の詳細に適用される補正の量を制御できます。これは、元の画像と画像のぼかしたバージョンの重み付けされた組み合わせを追加することによって行われ、重みによって強調の度合いが決まります。
この関数は、重みの異なる 2 つの画像を結合するために使用されます。このコンテキストでは、高ブースト フィルタリング操作を実行するために使用されます。cv2.addWeighted
image
: これは元の画像です。k - 1
:元の画像の重みです。ここから 1 を減算すると、元の画像の寄与が強調係数に従って確実にスケーリングされます。Value では、細部の強化がより重視されます。k
k - 1
blurred
: ぼやけた画像です。-0.5
: ぼかした画像の重みです。負の値は画像からブラーを減算します。0
:オフセット値です。重み付け加算後、結果に加算されます。
5. エッジ強調フィルター
エッジ強調フィルターは、画像内のエッジを強調するために使用される画像フィルターです。エッジは画像内の異なる領域間の境界であり、画像内のオブジェクトの構造と形状に関する情報を提供するために重要です。
- ソーベルフィルター
- プリウェットフィルター
- ガウス フィルター処理されたラプラシアン
- スマートエッジ検出器
5.1 ソーベルフィルター
ソーベル フィルターは、各ピクセルでの画像強度の勾配を計算することによりエッジを検出するために使用されます。2 つの個別のコンボリューション カーネル (水平方向に 1 つと垂直方向に 1 つ) を使用して勾配を近似します。
ソーベルオペレーター。ソース
ソーベル フィルターは、実装が比較的簡単で、エッジの検出に非常に効果的であるため、一般的なエッジ検出フィルターです。ただし、ノイズの影響を受けやすいため、ソーベル フィルターを適用する前に画像のノイズを軽減するために、ガウスぼかしなどの他のフィルターと組み合わせて使用されることがよくあります。
image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
# Apply Sobel Filter
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=25)
sobel_y = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=25)
sobel_edges = np.sqrt(sobel_x**2 + sobel_y**2)
# plot
plt.figure(figsize=(12, 8))
plt.subplot(2, 3, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(sobel_edges, cmap='gray')
plt.title('Sobel Filter')
plt.axis('off')
ソーベルフィルター。画像は作者提供。
cv.Sobel(src、 d Depth、 dx、 dy[、 dst[、 ksize[、scale[、 delta[、 borderType]]]]]) -> dst
dx
および: それぞれ x 方向と y 方向の導関数の次数。これらの値は、勾配が計算される方向を決定します。たとえば、x 方向の勾配を設定して計算します。dy
dx=1
dy=0
ksize
(オプション): 計算に使用される Sobel カーネルのサイズ。通常は、、、などの奇数に設定されます。指定しない場合、デフォルト値は 3x3 コアに対応します。1
3
5
3
scale
(オプション): 計算されたソーベル値に適用するスケール係数。このパラメータは、Sobel オペレータの効果を増減するのに役立ちます。delta
(オプション): 計算されたソーベル値に追加する値。出力の全体的な明るさやコントラストを制御するために使用できます。
5.2 プリウェットフィルター
Sobel フィルターと同様に、Prewitt フィルターも画像の強度の勾配を計算してエッジを検出します。Sobel カーネルよりも単純なカーネルを使用しますが、エッジの強調表示には依然として効果的です。
- 画像がシャープになりすぎないように、フィルターの強度を慎重に調整する必要があります。
- 可能であれば、フィルタはノイズのないバージョンの画像に適用する必要があります。
- 画像の全体的な品質を向上させるには、フィルターを他の画像処理技術 (スムージングなど) と組み合わせて使用する必要があります。
プリウェットのオペレーター。ソース
image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
# Prewitt Filter
kernel_x = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
kernel_y = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]])
prewitt_x = cv2.filter2D(image, cv2.CV_64F, kernel_x)
prewitt_y = cv2.filter2D(image, cv2.CV_64F, kernel_y)
prewitt_edges = np.sqrt(prewitt_x**2 + prewitt_y**2)
# plot
plt.figure(figsize=(12, 8))
plt.subplot(2, 3, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(prewitt_edges, cmap='gray')
plt.title('Prewitt Filter')
plt.axis('off')
プリウェットフィルター。画像は作者提供。
5.3 ガウスフィルタリングのラプラシアン
LoG フィルターは、ぼかしとエッジ検出の効果を組み合わせます。最初にガウスぼかしを画像に適用し、次にぼかした画像のラプラシアン演算子を計算します。その結果、画像のエッジが強調され、ノイズが抑制されます。
ガウス フィルターのラプラシアン。ソース
LoG フィルターは分離可能なフィルターです。つまり、画像を単一のカーネル (つまり、3x3 行列) で畳み込むことによって計算できます。カーネルは、画像のエッジを強調するように設計された重みで構成されます。
- 画像がシャープになりすぎないように、フィルターの強度を慎重に調整する必要があります。
- 可能であれば、フィルタはノイズのないバージョンの画像に適用する必要があります。
- 画像の全体的な品質を向上させるには、フィルターを他の画像処理技術 (スムージングなど) と組み合わせて使用する必要があります。
image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
# Apply Laplacian of Gaussian (LoG) Filter
log_edges = cv2.Laplacian(image, cv2.CV_64F)
log_edges = cv2.convertScaleAbs(log_edges)
# plot
plt.figure(figsize=(12, 8))
plt.subplot(2, 3, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(log_edges, cmap='gray')
plt.title('LoG Filter')
plt.axis('off')
Logフィルター。画像は作者提供。
ラプラシアン演算は正と負の両方の値を生成する可能性があるため、視覚化には適していない可能性があります。関数は、ラプラシアン演算の出力を絶対値に変換し、画像表示により適したデータ型に変換するために使用されます ()。cv2.convertScaleAbs(log_edges)
uint8
5.4 スマートエッジ検出器
Canny エッジ検出器は、画像内のエッジを検出するために使用される一般的な画像処理技術です。
スマートエッジ検出器。ソース
Canny エッジ検出器は、画像内の強度が急速に変化する領域を識別することによって機能します。これらの領域は、多くの場合、オブジェクトの境界や重要な特徴に対応します。
Canny エッジ検出器の出力はバイナリ イメージで、エッジ ピクセルは白でマークされ、非エッジ ピクセルは黒でマークされます。この手法は汎用性が高く、ガウスぼかしの標準偏差やエッジ検出しきい値などのパラメーターを調整することで微調整できます。
canny_edges = cv2.Canny(image, 30, 60)
# plot
plt.figure(figsize=(12, 8))
plt.subplot(2, 3, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(canny_edges, cmap='gray')
plt.title('Canny Edge Filter')
plt.axis('off')
スマートエッジフィルター。画像は作者提供。
cv.Canny(Image, Threshold1, Threshold2[, Edges[, ApertureSize[, L2Gradient]]]) -> エッジ
cv.Canny(dx、dy、threshold1、threshold2[、edges[、L2gradient]]) -> エッジ
image
: Canny エッジ検出が適用される入力画像。通常はグレースケール画像です。threshold1
および: これらは、二重しきい値ステップで使用される下限しきい値と上限しきい値です。Canny アルゴリズムは、以上の勾配の大きさを持つピクセルを強いエッジとしてマークし、エッジ間のピクセルを弱いエッジとしてマークします。以下のピクセルは非エッジとみなされ、破棄されます。threshold2
threshold2
threshold1
threshold2
threshold1
apertureSize
(オプション): 勾配計算に使用される Sobel カーネルのサイズ。通常は 、 、 または に設定されます。指定しない場合は、デフォルト値が使用されます。3
5
7
3
L2gradient
(オプション): 勾配の大きさを計算するために L2 ノルムを使用する必要があるかどうかを示すフラグ。の場合は、ユークリッド距離を使用します。の場合、L1 ノルムが使用されます。デフォルト値は です。True
False
False
画像フィルタリングの核心は、ピクセル データから隠された洞察を抽出することです。畳み込みの数学的な力を通じて、エッジを強調し、ノイズを低減し、生の画像を魅力的なストーリーに変換します。このプロセスは目的とテクノロジーを組み合わせ、目に見えないものを明らかにし、視覚認識を強化する画像フィルタリングの強力な能力を強化します。オカン・ジャーニガン