こしあん
2023-02-04

colorsysでライブラリ不要でRGB→HSV変換をする


3.3k{icon} {views}


PythonでRGB値から色相、彩度、明度への変換は画像処理ライブラリを使わないで行うことができます。ビルトインのcolorsysというモジュールを使います。

きっかけ

コード書くの面倒くさいなと、ChatGPTに聞いてみたら意外な結果を出してきました

colorsys

「えっそんなモジュールあるの?」と調べてみましたらありました。

colorsys — 色体系間の変換

しかもビルトイン。彩度色相の変換のためにいちいち画像処理ライブラリを読み込まなくていいそうです(Dockerで便利そうですね)

colorsys.rgb_to_yiq(r, g, b)
RGB から YIQ に変換します。

colorsys.yiq_to_rgb(y, i, q)
YIQ から RGB に変換します。

colorsys.rgb_to_hls(r, g, b)
RGB から HLS に変換します。

colorsys.hls_to_rgb(h, l, s)
HLS から RGB に変換します。

colorsys.rgb_to_hsv(r, g, b)
RGB から HSV に変換します。

colorsys.hsv_to_rgb(h, s, v)
HSV から RGB に変換します。

色相環を作ってみる

RGBとHSVの変換例として色相環の画像を作ってみます。作り方は単純で、xy座標を極座標変換して、それをHue(色相)とSatuation(彩度)に割り当てて、RGBに戻すというものです。

最後の画像の保存だけはどうしても画像処理ライブラリが必要なので、Pillowを使っています。

import numpy as np
import colorsys
from PIL import Image

def make_color_circle():
    # xy座標
    img_size = 512
    xy_coord = np.stack(
        np.meshgrid(
            np.arange(img_size), np.arange(img_size)), axis=-1)

    # 極座標変換
    polar_rho = np.linalg.norm(xy_coord-img_size//2, axis=-1)
    polar_phi = np.arctan2(
        xy_coord[:,:,1]-img_size//2, 
        xy_coord[:,:,0]-img_size//2)

    # HSV変換    
    hue = (polar_phi - polar_phi.min()) / (polar_phi.max() - polar_phi.min())
    satuation = polar_rho / (img_size // 2)
    value = np.ones_like(hue)
    value[satuation > 1] = 0
    satuation[satuation > 1] = 0

    # RGB変換
    # 要素ごとに関数適用できないのでnp.vectorizeする
    hsv_to_rgb = np.vectorize(colorsys.hsv_to_rgb)
    rgb = hsv_to_rgb(hue, satuation, value)
    out_img = (np.stack(rgb, axis=-1) * 255.0).astype(np.uint8)

    with Image.fromarray(out_img) as img:
        img.save("hsv_to_rgb_color_circle.png")


if __name__ == "__main__":
    make_color_circle()

ということでうまくいきました。小ネタとしては便利ですね。



Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内

技術書コーナー

北海道の駅巡りコーナー


Add a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です