OpenCV による基本的な画像の扱い (Python)
[History] [Last Modified] (2018/09/25 15:47:01)
ここは
趣味のプログラミングを楽しむための情報共有サービス。記事の一部は有料設定にして公開できます。 詳しくはこちらをクリック📝
Recent posts
Popular pages

概要

こちらのページで用意した環境を用いて、画像の基本的な扱い方を把握します。

切り出し Region of Interest (ROI)

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()

Uploaded Image

右下にコピー

img[100:200, 100:200] = part
plt.imshow(img)
plt.show()

Uploaded Image

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()

Uploaded Image

ブレンド

同じサイズの二つの画像の RGB 値を比率を指定して足し合わせます。

myimg.png

Uploaded Image

myimg2.png

Uploaded Image

cv.addWeighted(img, 0.7, img2, 0.3, 0)

Uploaded Image

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

Uploaded Image

opencv-logo-small.png

Uploaded Image

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

Uploaded Image

img_src2

Uploaded Image

img_src2_gray

Uploaded Image

img_src2_maskg

Uploaded Image

img_src2_mask

Uploaded Image

img_src2_maskn

Uploaded Image

img_src2_masked

Uploaded Image

img_src1_masked

Uploaded Image

img_src1_roi

Uploaded Image

img_src1

Uploaded Image

Related pages
    概要 NumPy から扱えるデータをファイルに保存するためのフォーマットとして HDF5 (Hierarchical Data Format) が利用されます。これを Python から扱うためには h5py を利用します。 pip install h5py サンプルコード NumPy データの保存 import h5py import numpy as np with h5py.File
    概要 ポイントクラウド (点群) は空間内の点 (x,y,z) の集合です。例えば LiDAR (Light Detection and Ranging、レーザースキャナ、3D スキャナ) を利用して取得できます。メッシュで物体を表現している場合と区別します。 画像には通常の RGB カラー画像だけでなく、距離情報を濃淡として保存した距離画像があります。両方を取得できるカメラを RGB-D カ
    概要 Python から扱う方法ではなく C++ で OpenCV を扱うためのサンプルコードを記載します。ビルドには cmake を用います。 Debian の場合は以下のコマンドで必要なライブラリがインストールされます。 sudo apt install libopencv-dev 画像を開いてウィンドウに表示