こちらのページで用意した環境を用いて、画像の基本的な扱い方を把握します。
RGB で処理するために Matplotlib を利用することにします。
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
img = mpimg.imread('./myimage.png')
画像サイズの確認
img.shape
(200, 200, 4)
指定したピクセルの R 値を取得および変更
img.item(0,0,0)
img.itemset((0,0,0), 1.0)
左上
part = img[0:100, 0:100]
plt.imshow(part)
plt.show()
右下にコピー
img[100:200, 100:200] = part
plt.imshow(img)
plt.show()
RGB を BGR に変換
import cv2 as cv
r,g,b,a = cv.split(img)
img = cv.merge((b,g,r,a))
plt.imshow(img)
plt.show()
同じサイズの二つの画像の RGB 値を比率を指定して足し合わせます。
myimg.png
myimg2.png
cv.addWeighted(img, 0.7, img2, 0.3, 0)
import cv2 as cv
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
img = mpimg.imread('./myimage.png')
img2 = mpimg.imread('./myimage2.png')
img.shape
img2.shape
plt.imshow(cv.addWeighted(img, 0.7, img2, 0.3, 0))
plt.show()
符号無し整数 [0, 255]
に範囲を変更したうえで、ビット演算してロゴ画像を別の画像に貼り付けます。
myimage.png
opencv-logo-small.png
import cv2 as cv
import matplotlib.image as mpimg
from matplotlib import pyplot as plt
import numpy as np
# RGBA の場合であっても RGB で読み込みます
# 今回はビット演算したいため、範囲を
# [0.0 ,1.0] (float32) から [0, 255] (uint8) に変更します
img_src1 = (mpimg.imread('./myimage.png')[:,:,:3] * 255).astype(np.uint8)
img_src2 = (mpimg.imread('./opencv-logo-small.png')[:,:,:3] * 255).astype(np.uint8)
#plt.imshow(img_src1); plt.show()
#plt.imshow(img_src2); plt.show()
# グレースケールに変換
img_src2_gray = cv.cvtColor(img_src2, cv.COLOR_RGB2GRAY)
#plt.imshow(img_src2_gray); plt.gray(); plt.show()
# 少しでも色がある箇所 (真っ黒 0 でない箇所) はすべて真っ黒 0 に変換します
# (逆に色がない黒い箇所 0 は真っ白 1 にします)
img_src2_maskg = cv.threshold(img_src2_gray, 10, 255, cv.THRESH_BINARY_INV)[1]
#plt.imshow(img_src2_maskg); plt.gray(); plt.show()
# RGB 画像のマスキング用に結合します
img_src2_mask = cv.merge((img_src2_maskg, img_src2_maskg, img_src2_maskg))
#plt.imshow(img_src2_mask); plt.show()
# 反転したマスキングも用意します
# bitwise への入力は符号なし整数であることが重要です。今回は uint8 です
# 0 = 00000000 => 11111111 = 255
# 255 = 11111111 => 00000000 = 0
img_src2_maskn = cv.bitwise_not(img_src2_mask)
#plt.imshow(img_src2_maskn); plt.show()
# threshold に満たなかった箇所をビット演算で 0 (真っ黒) にします
img_src2_masked = cv.bitwise_and(img_src2, img_src2_maskn)
#plt.imshow(img_src2_masked); plt.show()
# 別の画像 src1 から ROI を切り出して、src2 の色のある箇所をビット演算で真っ黒 0 にします
img_src1_masked = cv.bitwise_and(img_src1[:50,:54], img_src2_mask)
#plt.imshow(img_src1_masked); plt.show()
# ビット演算 OR でマスキングされた二つの画像を合わせます
img_src1_roi = cv.bitwise_or(img_src1_masked, img_src2_masked)
# img_src1_roi = img_src1_masked + img_src2_masked # としても同じ結果です
#plt.imshow(img_src1_roi); plt.show()
# src1 に結果を戻します
img_src1[:50, :54] = img_src1_roi
plt.imshow(img_src1)
plt.show()
img_src1
img_src2
img_src2_gray
img_src2_maskg
img_src2_mask
img_src2_maskn
img_src2_masked
img_src1_masked
img_src1_roi
img_src1