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)
Red(赤)、Green(緑)、Blue(青)はRGBカラー画像の画素値です。
Grayはグレースケール画像の画素値です。
例えばRed(0, 0)=255, Green(0, 0)=12, Blue(0, 0)=35のとき、Gray(0, 0)の画素値ha
(2)
となります。
– | 関連記事 |
---|---|
1 | ■【画像処理】RGBからグレースケールへの変換 |
2 | ■デジタル画像の構造(2次元配列・行列・画素値) |
3 | ■【画像処理入門】アルゴリズム&プログラミング |
4 | ■PythonでOpenCV入門 サンプル集 |
5 | ■【画像処理入門】アルゴリズム&プログラミング |
コメント
方法1のソースコードについて
OpenCVのimreadを使うと、得られる配列はB,G,Rの順になりませんか?
だとすると、rgb_to_gray()内のBとRの扱いは、逆になりませんか?
※匿名様
コメントありがとうございます。
ご指摘いただいた通りですので修正致しました。