【Python/OpenCV】グレースケール変換(cv2.cvtColor)

PythonとOpenCVを用いて画像をグレースケール変換する方法をソースコード付きで解説します。

【OpenCV】グレースケール変換

グレースケール変換とは、次のようにカラー画像をモノクロ調のグレースケール画像に変換する処理です。


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

OpenCVでは、cv2.cvtColorメソッドでRGBの画像をグレースケール変換できます。

書式

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
パラメータ名 説明
img 入力画像(RGB)
gray 出力画像(グレースケール)

今回は、「変換アルゴリズムを自前で実装する方法」と「cvtColorメソッドを利用する方法」を両方試してみました。

動画解説

ソースコード(Python3)

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

方法①

#-*- 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)

方法②

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

def rgb_to_gray(src):
     # チャンネル分解
     b, g, r = src[:,:,0], src[:,:,1], src[:,:,2]

     # R, G, Bの値からGrayの値に変換(float型 → 符号なし8bit整数型に変換)
     return np.array(0.2989 * r + 0.5870 * g + 0.1140 * b, dtype='uint8')

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

# グレースケール変換
gray = rgb_to_gray(img)

# グレースケール画像の書き込み
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)

※動作には、OpenCVライブラリのインストールが必要です。

【変換式】グレースケール

RGB画像をグレースケール画像に変換する場合は以下の式を利用します。

(1)   \begin{eqnarray*} Gray = Red\times 0.3 + Green\times 0.59 + Blue\times 0.11 \end{eqnarray*}

Red(赤)、Green(緑)、Blue(青)はRGBカラー画像の画素値です。
Grayはグレースケール画像の画素値です。

例えばRed(0, 0)=255, Green(0, 0)=12, Blue(0, 0)=35のとき、Gray(0, 0)の画素値ha

(2)   \begin{eqnarray*} Gray(0, 0)&=&Red(0, 0)\times 0.3 + Green(0, 0)\times 0.59 + Blue(0, 0)\times 0.11\\ &=&(255 \cdot 0.3) + (12 \cdot 0.59) + (35 \cdot 0.11)=87.43\simeq 87 \end{eqnarray*}

となります。

関連記事
1 【画像処理】RGBからグレースケールへの変換
2 デジタル画像の構造(2次元配列・行列・画素値)
3 【画像処理入門】アルゴリズム&プログラミング
4 PythonでOpenCV入門 サンプル集
5 【画像処理入門】アルゴリズム&プログラミング

コメント

  1. 匿名 より:

    方法1のソースコードについて
    OpenCVのimreadを使うと、得られる配列はB,G,Rの順になりませんか?
    だとすると、rgb_to_gray()内のBとRの扱いは、逆になりませんか?

    • 管理人 より:

      ※匿名様
      コメントありがとうございます。
      ご指摘いただいた通りですので修正致しました。