画像処理を勉強中なのでその内容のアウトプットです。
対象の画像から 3原色の内、赤色(赤系統)のみを抽出した画像にする 処理です。
目次
OpenCVを使用した赤色のみ抽出
コメント多めなのは自分の勉強を兼ねているからです。
Code
import cv2 #OpenCVライブラリ
import matplotlib.pyplot as plt #グラフ化用ライブラリ
%matplotlib inline
IMG_PATH = './data/smarties.png'
#画像表示
def show_img(img, vmin=0, vmax=255, title=None):
if img.ndim == 3:
#カラー(ndim=次元数=3 -> RGBの3色)
#CV2のRGB3色に変換
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#変換後画像をplotへ設定
plt.imshow(rgb_img, vmin=vmin, vmax=vmax)
elif img.ndim == 2:
#グレースケール(ndim=次元数=2 -> 白黒の2色)
#変換後画像をplotへ設定
plt.imshow(img, cmap='gray', vmin=vmin, vmax=vmax)
#座標軸非表示
plt.axis('off')
#タイトル設定
plt.title(title)
#グラフ表示
plt.show()
#画像表示(比較)
def show_img_compare(src, dst, vmin=0, vmax=255):
# 元画像表示
plt.subplot(121)
show_img(src, vmin, vmax, title='Before')
# 返還後画像表示
plt.subplot(122)
show_img(dst, vmin, vmax, title='After')
bgr_img = cv2.imread(IMG_PATH)
show_img(bgr_img)
#3色に分離(チャンネルを分ける)
b, g, r = cv2.split(bgr_img)
#blueのみチャンネル
#show_img(b)
#greenのみチャンネル
show_img(g)
#redのみチャンネル
show_img(r)
#blueをマスク(黒にする)
_, mask_b_img = cv2.threshold(b, 200, 255, cv2.THRESH_BINARY_INV)
#show_img_compare(b, mask_b_img)
#元画像と合成して青を除外(白の座標のみ元画像を復元)
except_b_img = cv2.bitwise_and(bgr_img, bgr_img, mask=mask_b_img)
#show_img_compare(mask_b_img,except_b_img)
#redをマスクする(白にする)
_, mask_r_img = cv2.threshold(r, 150, 255, cv2.THRESH_BINARY)
#show_img_compare(r, mask_r_img)
#元画像と合成してredのみにする(白の座標のみ元画像を復元)
only_r_img = cv2.bitwise_and(except_b_img, except_b_img, mask= mask_r_img)
#show_img_compare(bgr_img, only_r_img)
#境界線が粗いのでフィルタをかける(境界を曖昧にする)
recure_img = cv2.medianBlur(only_r_img, 5)
#show_img(only_r_img)
show_img(recure_img)
RESULT
元画像

実行後画像

やってみて
対象物の境界線の粗さが目立つ
フィルターの方法がマズイんだと思います。フィルターについては厳密には画像にある境界線を暈しているだけなので元画像と比較すると正確さが損なわれていると思います。
ここで載せている画像を人の目がみても、その差はあまりわからないかもですね。ちなみにフィルター前は↓

パッと見ではわからないでしょ?これを数値化するとわかりやすいかもしれませんね。
チャンネル毎のマスク処理
blueのマスク処理で白色にする→元画像と合成→blueを除外
の流れですが、除外しなくても良い座標についても除外されている気がします。その結果が対象物の境界線の粗さに繋がっているのかも。。。
この辺りは閾値の設定次第かと思われます。ひたすら調べていくと丁度良い数値があるのでしょうが、今回はなしです。
提供されているライブラリにその辺りを調整してくれるモノがあるかもなので、もし見つけたらその機会に実行してみます。