はじめに、
第 1 部では画像処理の基礎知識を紹介し、第 2 部では画像コンピューティングと画像強調を紹介し、第 3 部では画像セグメンテーションと画像処理の古典的な事例を詳しく説明します。この部分は高度な画像処理に属し、知識を得ることでさらに理解と実践力が深まります。画像セグメンテーションは、画像を固有の特性を持つ複数の領域に分割し、対象のオブジェクトを抽出する技術およびプロセスであり、画像処理および画像分析における重要なステップです。それは主に、閾値ベースのセグメンテーション方法、領域ベースのセグメンテーション方法、エッジベースのセグメンテーション方法、および特定の理論ベースのセグメンテーション方法に分けられます。この記事では、色ベースの画像分割方法について詳しく説明します。
1. カラーベースの画像セグメンテーション
カラー セグメンテーションは画像処理における重要なテクノロジであり、ターゲット検出や画像認識などのアプリケーション シナリオで画像内の異なる色を分離できます。
カラーセグメンテーションのアルゴリズム原理は比較的単純で、通常は色空間の変換に基づいて実現されます。一般的に使用される色空間には、RGB、HSV、LAB などが含まれますが、その中でも HSV 色空間はカラー セグメンテーション タスクにより適しています。HSV 色空間は、色を色相、彩度、明度の 3 つのチャネルに分割します。
- 色相: 赤、青、緑など、色の種類を示します。
- 彩度: 色の純度を示します。色の彩度が高いほど鮮やかであり、その逆も同様です。
- 明るさ: 色の明暗を指します。カラーでは、明度が高いほど色は明るくなり、明度が低いほど色は暗くなります。
カラーセグメンテーションの基本的な考え方は、しきい値処理によって異なる色のピクセルをセグメント化することです。具体的には、画像を RGB 色空間から HSV 色空間に変換し、適切なしきい値 (通常は色相、彩度、明度の最大値と最小値) を選択して画像を白と黒の部分に分割します。 。
opencv hsv色空間で
-
色相(Hue)の最大値は179度、最小値は0度で、カラーホイール上の色の位置を表します。
-
彩度の最大値は 255、最小値は 0 で、色の純度とグレースケールを表します。
-
Brightness の最大値は 255、最小値は 0 で、色の明暗を表します。
実装手順
上記のアルゴリズム原理に基づいて、次の手順を実行してカラー セグメンテーションを実現できます。
- 画像を RGB カラー空間から HSV カラー空間に変換します。
- 色相、彩度、明度の最大値と最小値をそれぞれ計算します
- 画像を白黒部分に分割するしきい値を設定します。
- 形態学的操作を使用してノイズを除去し、最終的なセグメンテーション結果を取得します。
この論文では、OpenCV の cv2.inRange() 関数を使用して、画像内のターゲットの色ベースのセグメンテーションを実行します。
マスク = cv2.inRange(src, lowerb, upperb[, dst])
— src パラメーターは入力イメージ (シングル チャネルまたはマルチ チャネルの場合があります)、データ型は np.uint8 です。
— マスクは出力イメージ (シングル チャネル イメージ (バイナリ イメージ)) であり、データtype は入力イメージと同じです
。 lowerb は、Scalar 型の指定された下限です。単一の値、タプル、または複数の値のリストにすることができます。upperb は、
Scalar 型の指定された上限です。単一の値、タプル、または複数の値のリスト
注:
マスクは、指定された色範囲に一致するピクセルの位置情報を表します。つまり、2 値画像内の指定された色範囲内のピクセルの対応するピクセル値は 255 で、指定された色範囲にないピクセルは 255 になります。バイナリ イメージ の対応するピクセル値は 0 です。したがって、このマスクを使用すると、画像を選択的に操作し、他のピクセルに影響を与えることなく、指定された色の範囲内のピクセルのみを処理できます。
以下は、上記のアルゴリズム原理に基づいた単純なカラー セグメンテーション コードです (マスク自体が特定の範囲を与えます)。
import cv2
import numpy as np
# 读入图片
img = cv2.imread( "C:/Users/Administrator/Desktop/flower.png")
# 转换颜色空间
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 定义绿色范围
lower_green = np.array([40, 50, 50])
upper_green = np.array([90, 255, 255])
# 定义黄色范围
lower_yellow = np.array([15, 50, 50])
upper_yellow = np.array([40, 255, 255])
# 根据颜色范围创建掩码
mask_green = cv2.inRange(hsv, lower_green, upper_green)
mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)
# 合并掩码
mask = cv2.bitwise_or(mask_green, mask_yellow)
# 应用掩码
result = cv2.bitwise_and(img, img, mask=mask)
# 显示结果
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
実行結果を図 1-1 に示します。図ではヒマワリが適切にセグメント化されていますが、草もセグメント化されています。
いくつかの一般的な色の HSV 範囲は次のとおりです。
赤: (0, 70, 50) - (10, 255, 255) または (170, 70, 50) - (179, 255, 255)
オレンジ: (10、70、50) - (25、255、255)
黄色: (25, 70, 50) - (35, 255, 255)
緑: (35、70、50) - (85、255、255)
シアン: (85, 70, 50) - (100, 255, 255)
青: (100, 70, 50) - (130, 255, 255)
紫: (130, 70, 50) - (170, 255, 255)
白: (0, 0, 221) - (180, 30, 255)
黒: (0, 0, 0) - (180, 255, 30)
2. ヒストグラムを観察して色の値の範囲を決定します。
セグメント化されるカラー ターゲットが画像内で大きな干渉を持たない場合、カラー ターゲットの値の範囲は、セグメント化の境界基準として色相 (Hue) コンポーネントのヒストグラムを観察することによって決定できます。
コード例は次のとおりです。
import cv2
import numpy as np
from matplotlib import pyplot as plt
#通过OpenCV读取图片信息
img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")
# BGR图转为HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 提取hsv中H通道数据
h = hsv[:, :, 0].ravel()
# 直方图显示
plt.hist(h, 180, [0, 180])
plt.show()
図 2-1 に示すヒストグラムを取得します。
異議申し立てで言及されている一般的な色の HSV 範囲によると、ヒストグラムの 30 ~ 70 の部分に大量のデータが表示されるため、上位と緑色の H 成分の下限は 30 ~ 70 である。SV の上限は、控訴で提案された HSV の範囲に応じて大まかに設定でき、マスクを抽出するときに調整して決定できる
マスクマスクは、HSV の緑色の境界を通して下に生成されます。コードは以下のように表示されます:
import cv2
import numpy as np
from matplotlib import pyplot as plt
#通过OpenCV读取图片信息
img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# HSV 的下界限
lower_red = np.array([35,70,50])
# HSV 的上界限
upper_red = np.array([70,255,255])
# 通过上下限提取范围内的掩模mask
mask = cv2.inRange(hsv, lower_red, upper_red)
img = cv2.resize(img,(500,500))
mask = cv2.resize(mask,(500,500))
cv2.imshow("img", img)
cv2.imshow("mask", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
実行結果を図 2-2 に示します。
草の大まかな輪郭は抽出されているのがわかりますが、フィールド上に黒点が多く存在しますが、これは黒点のほとんどが暗所にあるためであり、下限値を小さくすることで除去できます。ここで、V 値の下限値は、元の 50 を 15 に調整します。
その効果は次のとおりです。
現時点では、V 調整では除去できない黒点もありますが、膨張、腐食などの手段を使用して、独立した白点または黒点を除去できます。
黒点を除去するコードは次のとおりです。
import cv2
import numpy as np
from matplotlib import pyplot as plt
#通过OpenCV读取图片信息
img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# HSV 的下界限
lower_green = np.array([35,70,15])
# HSV 的上界限
upper_green = np.array([70,255,255])
# 通过上下限提取范围内的掩模mask
mask = cv2.inRange(hsv, lower_green, upper_green)
# 定义结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 35))
# 图像闭运算
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=2)
img = cv2.resize(img,(500,500))
mask = cv2.resize(mask,(500,500))
cv2.imshow("img", img)
cv2.imshow("mask", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
効果は図 2-3 に示されています。
黒い点が削除され、cv2.bitwise_and() を使用してビットごとに元の画像とマスクを使用して草の画像を抽出していることがわかります。
色の置き換え
上記の操作により、指定した色をすでに正確にセグメント化することができ、その後、その色を黄色に変更するなど、2 番目のベースで色を変更できます。これも HSV 色空間で操作する必要がありますが、今回はマスクを閉じる操作を行う必要はありません。
ここで createTrackbar 関数を使用して hsv を調整します
cv2.createTrackbar(トラックバー名, ウィンドウ名, 値, カウント, onChange)
- trackbarName: ドラッグ可能なバーの名前、文字列タイプ。
- windowName: ドラッグ可能なバーが配置されているウィンドウの名前 (文字列タイプ)。
- value: ドラッグ可能なバーのデフォルト値、整数。
- count: ドラッグ可能なバーの最大値、整数。
- onChange: ドラッグ可能なバーの値が変更されたときに呼び出されるコールバック関数、関数タイプ。
コードは以下のように表示されます:
import cv2
import numpy as np
def nothing(x):
pass
#通过OpenCV读取图片信息
img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")
img = cv2.resize(img,(500,500))
cv2.namedWindow('img',cv2.WINDOW_NORMAL)
cv2.imshow("img", img)
# HSV 的下界限
lower_green = np.array([35,70,15])
# HSV 的上界限
upper_green = np.array([70,255,255])
cv2.namedWindow('img2',cv2.WINDOW_NORMAL)
cv2.createTrackbar('H','img2',140,180,nothing)
cv2.createTrackbar('S','img2',100,180,nothing)
cv2.createTrackbar('V','img2',117,180,nothing)
rows,cols,channels = img.shape
while(1):
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower_green, upper_green)
#将制定像素点的数据设置为0, 要注意的是这三个参数对应的值是Blue, Green, Red。
h = cv2.getTrackbarPos('H', 'img2')
s = cv2.getTrackbarPos('S', 'img2')
v = cv2.getTrackbarPos('V', 'img2')
for r in range(rows):
for c in range(cols):
if mask[r, c] == 255:
hsv.itemset((r, c, 0), hsv.item(r, c, 0) -h)
hsv.itemset((r, c, 1), hsv.item(r, c, 1) +90-s)
hsv.itemset((r, c, 2), hsv.item(r, c, 2) +90-v)
img2 = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
#将图像进行输出,使用show()也是可以显示的。
img = cv2.resize(img, (500, 500))
cv2.imshow("img2", img2)
k = cv2.waitKey(1)&0xFF
if k == 27: #esc exit
break
#cv2.waitKey(0)
cv2.destroyAllWindows()
3. まとめ
このブログでは、HSV 色空間としきい値セグメンテーション アルゴリズムを使用するカラー セグメンテーションに Python と OpenCV を使用する方法を紹介します。カラー セグメンテーションを実現する手順には、画像ファイルの読み取り、色空間の変換、しきい値の計算、画像のセグメント化、ノイズの除去などが含まれます。サンプルのコードを通じて、カラー セグメンテーションの実装プロセスをより深く理解できます。