【Python/OpenCV】画像の読み書き、表示、色変換、部分処理

Python+OpenCVを用いて画像ファイルの読み書き、表示、色変換、部分処理をする方法をソースコード付きで解説します。

画像の読み込み(cv2.imread)

Python版のOpenCVでは、cv2.imreadメソッドで画像を読み込むことができます。

書式

img = cv2.imread(filename[,flag])
パラメータ 説明
filename 読み込む画像のファイルパス
flag cv2.IMREAD_COLOR : RGBカラー画像として読み込む(画像の透明度は無視)。デフォルト値。単に1と指定しても同じ。
cv2.IMREAD_GRAYSCALE : グレースケール画像として読み込む。単に0と指定しても同じ。
cv2.IMREAD_UNCHANGED :透明度(アルファチャンネル)も含めたRGBA画像として読み込む。単に-1と指定しても同じ。
img NumPy配列(読み込んだ画像の画素値を格納)

読み込みに対応している画像ファイル形式は、「jpg」「png」「bmp」「pgm」「pbm」「ppn」「dib」「jp2」「tiff」「tf」「ras」「sr」です。
読み込んだ画像の画素値はNumPy配列に格納されます。
そのため、通常のNumPy配列と同様に、print関数で中身を確認できます。

ソースコード

サンプルプログラムのソースコードです。


■入力画像(3×3)

rgbとrgbaは3次元配列、grayは2次元配列になります。
それぞれの各要素は各画素の画素値を表しています。

種類 説明
rgb 最初の要素[ 36 28 237]は、座標(0,0)の画素値です。Windowsの場合、36はBlue、28はGreen、237はRedの濃度です。[ 76 177 34]は、座標(1, 0)の画素値です。
gray 最初の要素91は座標(0,0)の画素値です。122は、座標(1, 0)の画素値です。
rgba 最初の要素[36 28 237 255]は座標(0,0)の画素値です。Windowsの場合、36はBlue、28はGreen、237はRedの濃度、255は透明度です。[ 76 177 34 255]は、座標(1, 0)の画素値です。
【Python/OpenCV】ブロブ解析+カラートラッキングで物体追跡
Python+OpenCVのブロブ解析+カラートラッキングで物体追跡する方法をソースコード付きで解説します。

画像の書き込み(cv2.imwrite)

Python版OpenCVでは、「cv2.imwrite」で画像を出力(書き込み)できます。

cv2.imwrite(filename, img)
パラメータ 説明
filename 書き込み画像のファイル名
img 画像オブジェクト(NumPy配列)

ソースコード

サンプルプログラムのソースコードです。

#-*- coding:utf-8 -*-
import cv2
import numpy as np


# 画像の読み込み(RGB)
img = cv2.imread("/Users/github/sample/python/opencv/basic/input.png")

# 画像の読み込み(グレースケール)
gray = cv2.imread("/Users/github/sample/python/opencv/basic/input.png", 0)

# 画像の読み込み(RGBA)
rgba = cv2.imread("/Users/github/sample/python/opencv/basic/input.png", -1)

# 画素値の表示
print("rgb=", img)
print("\n------------------------\n")
print("gray=", gray)
print("\n------------------------\n")
print("rgba=", rgba)

'''
rgb= [[[ 36  28 237] [ 76 177  34] [204  72  63]]
    [[  0   0   0] [255 255 255] [195 195 195]]
    [[164  73 163] [ 36  28 237] [  0   0   0]]]

------------------------

gray= [[138 142  98]
         [  0 255 195]
         [120 138   0]]

------------------------

rgba= [[[ 36  28 237 255] [ 76 177  34 255] [204  72  63 255]]
         [[  0   0   0 255] [255 255 255 255] [195 195 195 255]]
         [[164  73 163 255] [ 36  28 237 255] [  0   0   0 255]]]
'''
【Python/OpenCV】cv2.imwriteで画像ファイルを出力(書き込み・保存)
Python版OpenCVのcv2.imwriteで画像ファイルへ出力(書き込み)する方法をソースコード付きで解説します。

画像の表示(cv2.imshow)

Python版OpenCVでは「cv2.imshow」で読み込んだ画像ファイルをウィンドウに表示できます。

# -*- coding: utf-8 -*-
import cv2

# 入力画像のロード
img = cv2.imread('input.png')

cv2.imshow("input", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
【Python/OpenCV】cv2.imshowで画像をウィンドウに表示
Python版OpenCVで読み込んだ画像ファイルをウィンドウに表示する方法をソースコード付きでまとめました。

画像の高さ・幅・チャンネル数・画素数を取得

Python版OpenCVでは、「cv2.imread」を用いて読み込んだ画像データはNumPy配列に変換されます。
そのため、NumPy配列のshape属性を利用することで画像の高さ・幅・チャンネル数・画素数を調べることができます。

動画版説明

ソースコード

サンプルプログラムのソースコードです。

#-*- coding:utf-8 -*-
import cv2
import numpy as np

# 画像の読み込み(RGB)
img = cv2.imread("a.jpg")

height, width, ch = img.shape

# 画素数 = 幅 * 高さ
size = width * height

# 情報表示
print("幅:", width)
print("高さ:", height)
print("チャンネル数:", ch)
print("画素数:", size)
print("データ型:", img.dtype)

# 1chずつ表示
print("Bの画素値:\n", img[:,:,0])
print("Gの画素値:\n", img[:,:,1])
print("Rの画素値:\n", img[:,:,2])

サンプルプログラムの実行結果です。

■入力画像(3×3)

■標準出力

幅: 3
高さ: 3
チャンネル数: 3
画素数: 9
データ型: uint8

Bの画素値:
 [[ 35  43 221]
 [  0 255 209]
 [200   0   0]]
Gの画素値:
 [[ 12 198  43]
 [  0 255 225]
 [ 87   0   0]]
Rの画素値:
 [[255   0  50]
 [  0 255 226]
 [174 255   0]]

エラーが出た場合

以下のようなエラーが表示された場合、指定した画像ファイルが見つからなかったため空の配列を処理しようとしてエラーを出しています。
この場合、「cv2.imread(“C:/Users/Downloads/input.jpg”)」という風に絶対パスで画像ファイルのパスを指定してみてください。

cv2.error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-sn_xpupm\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'
【Python/OpenCV】画像の高さ・幅・チャンネル数・画素数を調べる方法
Python版OpenCVで画像の高さ・幅・チャンネル数・画素数を調べる方法をソースコード付きで解説します。

グレースケール変換(cv2.cvtColor)

グレースケール変換とは、次のようにカラー画像をモノクロ調のグレースケール画像に変換する処理です。
OpenCVでは、cv2.cvtColorメソッドでRGBの画像をグレースケール変換できます。

動画解説

ソースコード

#-*- coding:utf-8 -*-
import cv2

# 入力画像の読み込み
img = cv2.imread("C:\prog\python\input.png")

# グレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# グレースケール画像の書き込み
cv2.imwrite("C:\prog\python\gray.png", gray)


# BGR, B, G, R, Grayの2次元配列を確認
print("BGR=", img)
print("-------------")

print("Blue=", img[:,:,0])
print("-------------")

print("Green=", img[:,:,1])
print("-------------")

print("Red=", img[:,:,2])
print("-------------")
print("gray=", gray)
【Python/OpenCV】グレースケール変換(cv2.cvtColor)
PythonとOpenCVを用いて画像をグレースケール変換する方法をソースコード付きで解説します。

HSV色空間に変換(cv2.cvtColor)

HSV色空間とは、「色相(Hue)」「彩度(Saturation)」「明度(Value)」の3つの組み合わせで色を表現する手法です。
HSV色空間は人間が色を知覚する方法と類似しているため、RGB色空間よりも人がイメージした通りの色を作りやすいという特徴があります。
この特徴から、画像処理でも色検出をおこなう場合などにHSV色空間が利用されています。

動画解説

本ページの内容は動画でも解説しています。

【画像処理】RGBからHSVへの変換
この記事では、画像処理におけるRGBからHSVへの色空間変換の原理や特徴、計算式についてまとめました。

OpenCVライブラリでは、cv2.cvtColorメソッドでRGBからHSVに変換できます。

ソースコード

#-*- coding:utf-8 -*-
import cv2
import numpy as np


# 入力画像の読み込み
img = cv2.imread("C:\prog\python\\test\input.jpg")

# 方法2(OpenCVで実装)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 結果を出力
cv2.imwrite("C:\prog\python\\test\hsv.jpg", hsv)

実行結果

■左から入力画像(input.jpg)、出力画像(hsv2.jpg)

お借りした画像:プロ生ちゃん(暮井 慧)

【Python/OpenCV】RGBからHSVに変換(cv2.cvtColor)
PythonとOpenCVを用いて画像をRGBからHSVに変換する方法をソースコード付きで解説します。

赤、緑、青色の物体を検出

HSV色空間における、赤色、緑色、青色のHue値のおおよその範囲は以下のとおりです。

値の範囲 値の範囲(OpenCVの場合)
赤色のHue 0~60, 300~360[度] 0~30, 150~179
緑色のHue 60~189[度] 30~90
青色のHue 180~300[度] 90~150

SとVは対象に応じて適宜調整しますが、今回は以下の値域で赤、緑、青を検出します、

値の範囲 値の範囲(OpenCVの場合)
S 25~100[%] 64~255
V 00~100[%] 0~255

Sは彩度(色の鮮やかさ)を示す値・・・下限をさげるほど薄い色も検出します。
Sは明るさを示す値

OpenCVのcv2.inRangeメソッドを使うことで、指定したH、S、V値の範囲でマスクを取ることができます。

#-*- coding:utf-8 -*-
import cv2
import numpy as np

# 赤色の検出
def detect_red_color(img):
    # HSV色空間に変換
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    # 赤色のHSVの値域1
    hsv_min = np.array([0,64,0])
    hsv_max = np.array([30,255,255])
    mask1 = cv2.inRange(hsv, hsv_min, hsv_max)

    # 赤色のHSVの値域2
    hsv_min = np.array([150,64,0])
    hsv_max = np.array([179,255,255])
    mask2 = cv2.inRange(hsv, hsv_min, hsv_max)

    # 赤色領域のマスク(255:赤色、0:赤色以外)
    mask = mask1 + mask2

    # マスキング処理
    masked_img = cv2.bitwise_and(img, img, mask=mask)

    return mask, masked_img

# 緑色の検出
def detect_green_color(img):
    # HSV色空間に変換
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    # 緑色のHSVの値域1
    hsv_min = np.array([30, 64, 0])
    hsv_max = np.array([90,255,255])

    # 緑色領域のマスク(255:赤色、0:赤色以外)
    mask = cv2.inRange(hsv, hsv_min, hsv_max)

    # マスキング処理
    masked_img = cv2.bitwise_and(img, img, mask=mask)

    return mask, masked_img

# 青色の検出
def detect_blue_color(img):
    # HSV色空間に変換
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    # 青色のHSVの値域1
    hsv_min = np.array([90, 64, 0])
    hsv_max = np.array([150,255,255])

    # 青色領域のマスク(255:赤色、0:赤色以外)
    mask = cv2.inRange(hsv, hsv_min, hsv_max)

    # マスキング処理
    masked_img = cv2.bitwise_and(img, img, mask=mask)

    return mask, masked_img


# 入力画像の読み込み
img = cv2.imread("C:\prog\python\\test\input.png")

# 色検出(赤、緑、青)
red_mask, red_masked_img = detect_red_color(img)
green_mask, green_masked_img = detect_green_color(img)
blue_mask, blue_masked_img = detect_blue_color(img)

# 結果を出力
cv2.imwrite("C:\prog\python\\test\\red_mask.png", red_mask)
cv2.imwrite("C:\prog\python\\test\\red_masked_img.png", red_masked_img)
cv2.imwrite("C:\prog\python\\test\green_mask.png", green_mask)
cv2.imwrite("C:\prog\python\\test\green_masked_img.png", green_masked_img)
cv2.imwrite("C:\prog\python\\test\\blue_mask.png", blue_mask)
cv2.imwrite("C:\prog\python\\test\\blue_masked_img.png", blue_masked_img)

実行結果

サンプルプログラムの実行結果です。

■入力画像(input.png)

■赤色の検出結果
左がマスク画像(red_mask.png)、右がマスキング処理した画像(red_masked_img.png)

■緑色の検出結果
左がマスク画像(green_mask.png)、右がマスキング処理した画像(green_masked_img.png)

■青色の検出結果
左がマスク画像(blue_mask.png)、右がマスキング処理した画像(blue_masked_img.png)

【Python/OpenCV】赤・緑・青色の検出(HSV色空間)
PythonとOpenCVを用いて画像をHSV色空間に変換し、赤・緑・青色の領域を色検出する方法をソースコード付きで解説します。

【OpenCV】窓画像の作成(切り取り)

ROI(Region of Interest)とは、画像データのうち、操作の対象として選ぶ領域のことです。
「対象領域」「注目領域」「関心領域」「窓画像」などといいます。
Pythonでは、NumPyのスライスを使うことで、OpenCVで読み込んだ画像の一部分を切り取って窓画像を作成できます。

実行例

■入力画像(左)、出力画像(右)

動画解説

ソースコード

#-*- coding:utf-8 -*-
import cv2
import numpy as np

# 入力画像とテンプレート画像をで取得
img = cv2.imread("C:\prog\python\input.png")

# 窓画像の左上座標
x, y = 50, 100

# 窓画像の幅・高さ
w, h = 40, 40

# 入力画像から窓画像を切り取り
roi = img[y:y+h, x:x+w]

# 窓画像の保存
cv2.imwrite("C:\prog\python\output.png", roi)
【Python/OpenCV】窓画像の作成(切り取り)
Python版OpenCVで画像の一部分を切り取り、窓画像を作る方法をソースコード付きで解説します。

【OpenCV】部分処理

Pythonでは、NumPyのスライスを使うことで、OpenCVで読み込んだ画像の一部分だけに処理を施します。

実行例

■入力画像(左)、出力画像(右)
※画像の一部分を黒塗り

ソースコード

#-*- coding:utf-8 -*-
import cv2
import numpy as np

# 入力画像とテンプレート画像をで取得
img = cv2.imread("C:\prog\python\input.png")

# 窓画像の左上座標
x, y = 50, 100

# 窓画像の幅・高さ
w, h = 40, 40

# 窓画像を黒塗り(画素値を0に)
img[y:y+h, x:x+w] = 0

# 画像の書き込み
cv2.imwrite("C:\prog\python\output.png", img)
【Python/OpenCV】部分処理
Python版OpenCVで画像の一部分だけに処理を施す方法をソースコード付きで解説します。

【OpenCV】画像の圧縮(encode、decode)

Python版OpenCVの「cv2.imencode」で画像の圧縮(エンコード)ができます。
復元(デコード)は、「cv2.imdecode」です。

# -*- coding: utf-8 -*-
import cv2
import numpy as np

# 入力画像の読み込み
img = cv2.imread("input.jpg")

# 画像の圧縮(画質は80%)
result, encimg = cv2.imencode("img2.jpg", img, [int(cv2.IMWRITE_JPEG_QUALITY), 80])

# 圧縮画像の保存
cv2.imwrite("output.jpg", img)
【Python/OpenCV】画像の圧縮(encode、decode)
Python版OpenCVでフレーム間差分法を実装し、移動物体を検出する方法をソースコード付きで解説します。
【Python版OpenCV超入門】使い方とサンプルコードを解説
Python版OpenCVで画像処理プログラミングを行う方法を入門者向けにソースコード付きで解説するページです。

コメント