こしあん
2021-01-17

Pillow(Python)でRGB→CMYKのプロファイル変換

Pocket
LINEで送る
Delicious にシェア

398{icon} {views}



RGBからCMYKへの変換は印刷をする際に必要になりますが、通常はPhotoshopなどの有料の画像編集ソフトを使います。実はこれはPythonで無料でできます。Pillowを使ったやり方を紹介します。バッチ処理にも便利です。

プロファイル変換によるCMYK変換

前回の投稿では、「CMYK画像をPillowでどう扱うか」について簡単な解説をしました。今回は任意のRGB画像をCMYKにいい感じに変換するための処理をPythonで見ていきます。

CMYK画像は印刷所への入稿をする際に必要になりますが、RGB→CMYKは表現できる色が異なるのでくすみが発生します。同人誌の印刷では結構これが問題になります。これを抑える方法はあって、例えばPhotoshopでは「プロファイル変換」をするとその影響を抑えて変換することが可能です。

Photoshop CC2020の場合、次の方法でプロファイル変換ができます。「編集→プロファイル変換」をクリックし、

ソースカラースペース、変換後のカラースペースともに変換前・後の色空間を表します。このケースではRGB→CMYKですね。CMYKでもプロファイルがいろいろありますが、「CMYK – Japan Color 2001 Coated」をCMYKのプロファイルとして使うことがほとんどです。これはコート紙への印刷を目的とした日本における規格です。

マッチング方法は4種類ありますが、「相対的な色域を維持」を選ぶことが多いです。ほかも選べますがこの方法が出力結果が安定しています。

ICCプロファイルのダウンロード

本題はこれをPythonでどのように再現するかということです。Pillowを使うとこれができます。ただしICCプロファイルのダウンロードが必要です。

Adobe ICC Profiles download for Windows
https://www.adobe.com/support/downloads/iccprofiles/iccprofiles_win.html

「for Windows」と書いてありますがLinux環境のPythonでも動きました。これから「ICC profile download for End Users」をダウンロードします。規約を読んでAcceptをクリック、そこからいくつか画面を飛ぶと、「AdobeICCProfilesCS4Win_end-user.zip」というファイルがダウンロードされます。

このZipにはいろいろなICCプロファイルがあるのですが、「AdobeICCProfilesCS4Win_end-user/Adobe ICC Profiles (end-user)/CMYK/JapanColor2001Coated.icc」というファイルを使います。これをカレントディレクトリにコピーします。

ここでは2001Coatedを使いましたが、印刷する用紙がコート紙以外なら、Uncoatedを使ってもいいと思います。いろいろ試してみると楽しいでしょう。

Pillowでのプロファイル変換

Pillowというライブラリが必要です。Python3環境です。インストールが面倒だったらGoogle Colaboratoryを使いましょう。

pip install --upgrade Pillow

サンプル画像は、自分が書いた本の表紙をベースとします。これを「rgb.jpg」とします。

これをCMYKに変換するコードは次のとおりです。

from PIL import ImageCms, Image

def convert_to_cmyk():
    with Image.open("rgb.jpg") as img:
        # sRGBのプロファイル取得
        srgb = ImageCms.createProfile("sRGB")
        # sRGB -> Japan Color 2001 Coated(CMYK)
        img = ImageCms.profileToProfile(
            img, srgb, "JapanColor2001Coated.icc",
            renderingIntent=ImageCms.INTENT_RELATIVE_COLORIMETRIC,
            outputMode="CMYK")
        # ICCプロファイルを埋め込んで保存
        with open("JapanColor2001Coated.icc", "rb") as fp:
            profile = fp.read()
        img.save("cmyk.jpg", icc_profile=profile)

if __name__ == "__main__":
    convert_to_cmyk()

結果は次のようになります。

右上の「くるまなしで」の部分が若干くすんでいますが、これはCMYK変換へのくすみなので仕方ないです。同じ変換をPhotoshopで行った結果が次のとおりです。

PythonとPhotoshopが同じ結果になりました。右上の文字はPhotoshopでもくすむので、局所的にトーンカーブいじって対応でしょうね。

renderingIntentについて

プロファイル変換のに部分に「renderingIntent」というオプションがありますが、これはPhotoshopの「マッチング方法」と対応するようです。次の4種類があります。

  • ImageCms.INTENT_PERCEPTUAL = 0 (DEFAULT)
  • ImageCms.INTENT_RELATIVE_COLORIMETRIC = 1
  • ImageCms.INTENT_SATURATION = 2
  • ImageCms.INTENT_ABSOLUTE_COLORIMETRIC = 3

Photoshopの表記では上から順に次のように対応します。英語と訳語が綺麗に対応しますね。

  1. 知覚的
  2. 相対的な色域を維持
  3. 彩度
  4. 絶対的な色域を維持

プロファイルを埋め込んで保存について

これは変換後のファイルが「どのICCプロファイルか」を示すために明示的に埋め込んでおいたほうが良さそうです。Photoshopでの保存画面でも、

このように「ICCプロファイルを埋め込むかどうか」のオプションがあるので、印刷のように色管理が重要になると埋め込んでおいたほうが無難と言えるでしょう。

sRGBのICCプロファイルについて

先程「JapanColor2001Coated.icc」というファイルを用意しましたが、例えばCMYK→RGBに変換するときに「sRGBのICCプロファイルはいるのか」という疑問は湧きます。結論からいうといりません。なぜなら、Pillowの中にsRGBのICCは組み込まれており、

srgb = ImageCms.createProfile("sRGB")

このコードで取得できるからです。

renderingIntentを変えてプロット

「ImageCms.INTENT_RELATIVE_COLORIMETRICでいいよ」と言いましたが、これを変えてプロットしてみます。

from PIL import ImageCms, Image, ImageDraw
import numpy as np

def compare_rendering_intent():
    icc_names = ["PERCEPTUAL", "RELATIVE_COLORIMETRIC", "SATURATION", "ABSOLUTE_COLORIMETRIC"]
    results = []
    with Image.open("rgb.jpg") as img:
        srgb = ImageCms.createProfile("sRGB")
        # 半分にリサイズ
        img = img.resize((img.width//2, img.height//2), Image.LANCZOS)
        # sRGB -> Japan Color 2001 Coated(CMYK)
        for i in range(4):
            out = ImageCms.profileToProfile(
                img, srgb, "JapanColor2001Coated.icc",
                renderingIntent=i,
                outputMode="CMYK")
            # ICC名を表示
            draw = ImageDraw.Draw(out)
            draw.text((5, 5), icc_names[i], fill=(0, 0, 0, 255)) # 色はCMYK
            results.append(np.array(out))
        # タイル
        results = np.stack(results, axis=0)
        results = results.reshape(2, 2, *results.shape[1:])
        results = results.transpose([0, 2, 1, 3, 4])
        results = results.reshape(img.height * 2, img.width * 2, 4)
        with Image.fromarray(results, "CMYK") as result:
            with open("JapanColor2001Coated.icc", "rb") as fp:
                profile = fp.read()
            result.save("cmyk_tile.jpg", icc_profile=profile)

if __name__ == "__main__":
    compare_rendering_intent()

「絶対的な色域を維持」は白飛びしているようで、「知覚的」は若干色が抜けたような感じがあります。「相対的な色域を維持」と「彩度」は悪くないように思えます。ただし元の画像次第では「彩度」も白飛びしているように見えることがあるので、いろいろ試してみるのをおすすめします。

事前に彩度補正を入れて、「相対的な色域を維持」でプロファイル変換するのがベターかなと今の所思っています。

まとめ

Photoshopでのプロファイル変換を用いたCMYK変換は、実はPillow(Python)でもできる。ただしICCプロファイルのダウンロードや埋め込みを忘れずに。ということでした。

この記事は、2020年12月の新刊・インフィニティNumPyの第4章のQ88-89で紹介した内容を掘り下げたものです。



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

技術書コーナー

【新刊】インフィニティNumPy――配列の初期化から、ゲームの戦闘、静止画や動画作成までの221問

「本当の実装力を身につける」ための221本ノック――
機械学習(ML)で避けて通れない数値計算ライブラリ・NumPyを、自在に活用できるようになろう。「できる」ための体系的な理解を目指します。基礎から丁寧に解説し、ディープラーニング(DL)の難しいモデルで遭遇する、NumPyの黒魔術もカバー。初心者から経験者・上級者まで楽しめる一冊です。問題を解き終わったとき、MLやDLなどの発展分野にスムーズに入っていけるでしょう。

本書の大きな特徴として、Pythonの本でありがちな「NumPyとML・DLの結合を外した」点があります。NumPyを理解するのに、MLまで理解するのは負担が大きいです。本書ではあえてこれらの内容を書いていません。行列やテンソルの理解に役立つ「従来の画像処理」をNumPyベースで深く解説・実装していきます。

しかし、問題の多くは、DLの実装で頻出の関数・処理を重点的に取り上げています。経験者なら思わず「あー」となるでしょう。関数丸暗記では自分で実装できません。「覚える関数は最小限、できる内容は無限大」の世界をぜひ体験してみてください。画像編集ソフトの処理をNumPyベースで実装する楽しさがわかるでしょう。※紙の本は電子版の特典つき

モザイク除去から学ぶ 最先端のディープラーニング

「誰もが夢見るモザイク除去」を起点として、機械学習・ディープラーニングの基本をはじめ、GAN(敵対的生成ネットワーク)の基本や発展型、ICCV, CVPR, ECCVといった国際学会の最新論文をカバーしていく本です。
ディープラーニングの研究は発展が目覚ましく、特にGANの発展型は市販の本でほとんどカバーされていない内容です。英語の原著論文を著者がコードに落とし込み、実装を踏まえながら丁寧に解説していきます。
また、本コードは全てTensorFlow2.0(Keras)に対応し、Googleの開発した新しい機械学習向け計算デバイス・TPU(Tensor Processing Unit)をフル活用しています。Google Colaboratoryを用いた環境構築不要の演習問題もあるため、読者自ら手を動かしながら理解を深めていくことができます。

AI、機械学習、ディープラーニングの最新事情、奥深いGANの世界を知りたい方にとってぜひ手にとっていただきたい一冊となっています。持ち運びに便利な電子書籍のDLコードが付属しています。

「おもしろ同人誌バザールオンライン」で紹介されました!(14:03~) https://youtu.be/gaXkTj7T79Y?t=843

まとめURL:https://github.com/koshian2/MosaicDeeplearningBook
A4 全195ページ、カラー12ページ / 2020年3月発行

Shikoan's ML Blog -Vol.1/2-

累計100万PV超の人気ブログが待望の電子化! このブログが電子書籍になって読みやすくなりました!

・1章完結のオムニバス形式
・機械学習の基本からマニアックなネタまで
・どこから読んでもOK
・何巻から読んでもOK

・短いものは2ページ、長いものは20ページ超のものも…
・通勤・通学の短い時間でもすぐ読める!
・読むのに便利な「しおり」機能つき

・全巻はA5サイズでたっぷりの「200ページオーバー」
・1冊にたっぷり30本収録。1本あたり18.3円の圧倒的コストパフォーマンス!
・文庫本感覚でお楽しみください

Vol.1 電子550円
Vol.2 電子550円

北海道の駅巡りコーナー

日高本線 車なし全駅巡り

ローカル線や秘境駅、マニアックな駅に興味のある方におすすめ! 2021年に大半区間が廃線になる、北海道の日高本線の全区間・全29駅(苫小牧~様似)を記録した本です。マイカーを使わずに、公共交通機関(バス)と徒歩のみで全駅訪問を行いました。日高本線が延伸する計画のあった、襟裳岬まで様似から足を伸ばしています。代行バスと路線バスの織り成す極限の時刻表ゲームと、絶海の太平洋と馬に囲まれた日高路、日高の隠れたグルメを是非たっぷり堪能してください。A4・フルカラー・192ページのたっぷりのボリュームで、あなたも旅行気分を漫喫できること待ったなし!

見どころ:日高本線被災区間(大狩部、慶能舞川橋梁、清畠~豊郷) / 牧場に囲まれた絵笛駅 / 窓口のあっただるま駅・荻伏駅 / 汐見の戦争遺跡のトーチカ / 新冠温泉、三石温泉 / 襟裳岬

A4 全192ページフルカラー / 2020年11月発行


Pocket
LINEで送る
Delicious にシェア

Add a Comment

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