【Python・OpenCV】色空間(cv2.cvtColor)

※当サイトではアフィリエイト広告を利用しています

Python プログラミング 画像処理

【Python・OpenCV】色空間(cv2.cvtColor)

2023-04-04

はじめに

PythonでOpenCVを使った色空間の扱いについて紹介します。
色の3原色というのを聞いたことがあるかもしれません。3つの色を割合を変えて混ぜ合わせることで様々な色を表現するものですが、3原色以外の概念で表現する方法もあります。
このように色の特性を複数の要素(成分)で表現する表現方法を色空間と呼びます。
OpenCVでは様々な色空間を扱うことができます。扱うことができる色空間とcv2.cvtColor関数を使った相互変換方法について解説します。

OpenCVで扱うことができる色空間

OpenCVで扱うことができる色空間の中からよく使うと思われるものについて説明します。

RGB

RGBは、赤(R)・緑(G)・青(B)の3原色を組み合わせる加法混合で色を表現する色空間です。RGBは、Red、Green、Blueの頭文字から名付けられました。
色を重ねるごとに明るくなり、3色を重ねると白になります。
コンピューターグラフィックス、デジタルカメラ、ビデオ、テレビなどで一般的に使用されています。

RGB色空間
画像引用元:Wikipedia RGB

HSV

HSV色空間は、色を明度(Value)、彩度(Saturation)、色相(Hue)の3つのパラメータで表現する色空間です。HSVは、「Hue(色相)」、「Saturation(彩度)」、「Value(明度)」の略称から取られています。

  • 色相(Hue):色相は、色の種類を表します。色相は、0~360度の間で表されます。赤、青、緑など、約6つの基本的な色相があります。
  • 彩度(Saturation):彩度は、色の鮮やかさや淡さを表します。彩度が高いほど、色はより鮮やかに見えます。彩度は、0~100%の間で表されます。
  • 明度(Value):明度は、色の明るさを表します。明度が高いほど、色はより明るく見えます。明度は、0~100%の間で表されます。

HSV色空間は、RGB色空間などの他の色空間と比較して、色相、彩度、明度を独立して操作することができるため、色相、明度、彩度の調整や、色の選択が容易になります。また、HSV色空間は、特に画像処理やグラフィックデザインにおいて、より自然な色の表現が可能です。

HSV色空間
画像引用元:Wikipedia HSL and HSV

HLS

HLS色空間は、色を表現するための一般的な方法の1つで、Hue(色相)、Lightness(明度)、Saturation(彩度)の3つの値で色を定義します。

Hueは、色の種類を示し、360度の円形スペクトルに基づいて0から360までの値を持ちます。赤、緑、青などの色は、それぞれ0、120、240のHue値に対応します。

Lightnessは、色の明るさを示し、0から100までの値を持ちます。0は完全に黒で、100は完全に白です。

Saturationは、色の強さを示し、0から100までの値を持ちます。0は完全にグレーで、100は最も鮮やかな色です。

HLS色空間は、RGB色空間と比較して、より直感的に色を調整できるという利点があります。たとえば、HLS色空間では、特定の色相を維持しながら彩度を低下させ、より自然な効果を生み出すことができます。また、色相を変更しながら明度を調整することによって、画像に深みを追加することができます。

HSL色空間
画像引用元:Wikipedia HSL and HSV

L*a*b*

L*a*b*色空間は、人間の目の知覚に基づいた、色の表現を行うための3次元色空間です。Lab色空間は、明度(L)、a軸(赤緑軸)、b軸(青黄軸)の3つの軸から構成されます。

L軸は、0から100までの範囲で明度を表現し、0が黒、100が白を表します。a軸とb軸は、-128から+127までの範囲で、赤緑と青黄の色を表現します。a軸は、負の値が緑色、正の値が赤色を表します。b軸は、負の値が青色、正の値が黄色を表します。

L*a*b*色空間は、RGB色空間やCMYK色空間と比較して、色の差異をより正確に表現できます。また、Lab色空間は、色覚の異なる人々が同じ色を見ることができるように、国際標準化機構(ISO)によって定められた色空間です。Lab*色空間は、色の測定や色の比較など、さまざまな用途で使用されます。

L*a*b*色空間
画像引用元:ResearchGate

L*u*v*

L*u*v*色空間は、人間の色覚に基づいて設計された色空間で、色の明度(L)、色の彩度(u)、および色相(v)を定義します。

L*は、色の明るさを示す値で、0が完全な黒を示し、100が完全な白を示します。

uおよびvは色相と彩度を表す値で正の値は赤寄りの色を、負の値は青寄りの色を表します。uは緑と赤の相対的な強さを示し、vは青と黄色の相対的な強さを示します。

L*u*v*色空間は、RGB色空間に比べて色の明るさや彩度についてより自然な感覚を与えることができます。また、様々な色を正確に表現することができ、色の変換や比較にも適しています。しかし、計算が複雑であるため、一般的には色の研究や調整などの特定の用途に限定されています。

XYZ

XYZ色空間は人間が知覚する光の3つの基本的な特性である色相、彩度、明度を表現するために使用される色空間の一つです。

XYZ色空間ではすべての色が3つの主要な軸、すなわちX軸、Y軸、Z軸によって表現されます。X軸は赤から緑までの色相を、Y軸は明るさまたは輝度を表します。Z軸は青から黄色までの色相を表します。

XYZ色空間は、多くの他の色空間と比較して視覚的な色の違いを正確に表現することができるため、色の測定や比較に広く使用されています。また、他の色空間に変換することもできるため、多くのデジタルカメラやグラフィックスソフトウェアでも使用されています。しかし、XYZ色空間自体は人間の知覚に基づいているため、そのままの形式で使用することは少なく他の色空間に変換する必要があります。

YUV

YUV色空間はテレビやビデオなどの映像伝送によく使われます。この色空間は明るさ(輝度)と色度を別々に扱い、コンピューターなどで画像処理を行う場合にも広く利用されています。

YUV色空間では画像の各ピクセルは3つの値で表されます。Yは輝度を表します。UとVは色度を表します。Uは青紫色から黄色に、Vは緑から赤にかけての色を表します。

YUV色空間
画像引用元:Wikipedia

色空間の変換(cv2.cvtColor)

色空間の変換は計算することが出来ます。
下記リンクには様々な色空間について相互の変換式が紹介されています。

OpenCVではこのリンクの変換式を用いた色空間の変換関数としてcv2.cvtColor関数が実装されています。

cv2.cvtColor(入力画像, code[, dst[, dstCn]])

引数

名称説明
入力画像(必須)入力画像
code(必須)ColorConversionCodesとして定義されている色空間変換コード
dst(オプション)出力画像。指定された場合、結果がこの変数に格納されます。指定されない場合は、新しい配列が作成されて結果が格納され戻り値として取得できます。
dstCn(オプション)出力画像のチャンネル数

引数のColorConversionCodesにはとても多くのコードが列挙されているので、下に代表的なものを抜粋します。

コード名説明
cv2.COLOR_BGR2RGBBGRからRGBへチャンネルの並びを変換します。
cv2.COLOR_BGR2GRAYBGRからグレースケールに変換します。
cv2.COLOR_BGR2XYZBGRからXYZに色空間を変換します。
cv2.COLOR_BGR2HSVBGRからXYZに色空間を変換します。Hueのレンジは8bit画像の場合、0〜180です。
cv2.COLOR_BGR2LabBGRからLab*に色空間を変換します。
cv2.COLOR_BGR2LuvBGRからLuv*に色空間を変換します。
cv2.COLOR_BGR2HLSBGRからHLSに色空間を変換します。Hueのレンジは8bit画像の場合、0〜180です。
cv2.COLOR_HSV2BGRHSVからBGRに色空間を変換します。Hueのレンジは8bit画像の場合、0〜180です。
cv2.COLOR_HLS2BGRHLSからBGRに色空間を変換します。Hueのレンジは8bit画像の場合、0〜180です。
cv2.COLOR_BGR2YUVBGRからYUVに色空間を変換します。
ColorConversionCodes

ポイント

OpenCVではRGB色空間の画像のチャンネルの並びはBGRとなっています。
このため、ColorConversionCodesではコード名の表記がBGRとなっています。

戻り値

色空間変換後の画像データです。

使い方

入力画像として、この画像を使用しました。

【Python・OpenCV】色空間(cv2.cvtColor)の入力画像

引用元
https://unsplash.com/ja/%E5%86%99%E7%9C%9F/gO87zun6lF4

例として下のコードではRGBの画像をHSVに変換します。
cv2.cvtColor関数の引数は必須のものだけを使っています。

import cv2

# 画像を読み込む
image = cv2.imread('image.jpg')

# BGRからHSVに変換
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# HSVの画像をそれぞれのチャンネルに分割
hue, saturation, value = cv2.split(hsv)

# 画像を保存する
cv2.imwrite('result.jpg', hsv) # 3チャンネル画像
cv2.imwrite('hue.jpg', hue) # 色相画像
cv2.imwrite('saturation.jpg', saturation) # 彩度画像
cv2.imwrite('value.jpg', value) # 明度画像

変換の結果が下の画像です。

変換結果の画像は元の画像とは全く異なる色になりました。
それぞれのチャンネルを個別の画像に分割して表示します。

ポイント

8bitの入力画像でcv2.cvtColor関数で作成された画像はHSV色空間の場合、色相(Hue)は0〜179、彩度(Saturation)は0〜255、明度(Value)は0〜255の範囲の値となります。
HLS色空間についても同様です。

色相画像の色が暗いのは値の範囲が0〜179となっているためです。0〜360の範囲で処理したい場合は2倍する必要があります。

上のコードの中で使用しているcv2.split関数については下記の記事解説しています。よろしければ参考してみください。

おわりに

OpenCVのcv2.cvtColor関数は、画像処理の前処理やカメラからの入力映像の色空間変換などで使われることが多いと思います。
色空間の種類によって値の範囲が異なる場合があるので要注意ですね。

最後までご覧いただきありがとうございました。

■(広告)OpenCVの参考書としてどうぞ!■

参考リンク

(広告)あなたに合ったプログラミング スクールが見つかるかも

プログラミングの学習が、新しい世界を開きます。副業からキャリアの転換まで、目標に向かって一歩を踏み出しましょう。

これらのプログラミング スクールは、あなたの目的に合わせて選択できるさまざまなプログラムを提供しています。どのスクールを選ぶにせよ、プログラミングは未来への扉を開き、新しい機会を切り開く手段として素晴らしい選択です。あなたの夢や目標を実現する第一歩を踏み出す準備はできていますか?

-Python, プログラミング, 画像処理
-