📝

OpenCVを用いた画像の画素ごとの補色を用いた色変換【Python】

2023/09/01に公開

この記事はQiitaの記事の転載です!!

Qiitaの記事はこちら!!

https://qiita.com/blueman/items/27be76fd66f238f2e2e1


目次

はじめに
実行環境
画像の画素値へのアクセス方法
補色の計算方法
画像上に文字を出力する方法
複数の画像を横並びに表示する方法
ソースコード
結果
まとめ

はじめに

今回は、前回のTwitter(X)のアンケートでトップだった動画像処理についての記事です。
そのジャンルの中から、オリジナル画像画像の画素値ごとの補色を用いて変換した画像ネガポジ反転した画像並べて表示させ、ネガポジ反転と補色を用いた画像変換の画素値に関するヒストグラムを表示させるプログラムを作成したのでそれについて紹介したいと思います。


マイページについて

https://qiita.com/blueman

X(Twitter)について

https://twitter.com/0ca00118726208m

Qiitaについて

実行環境

実行環境は次の通りです。

実行環境
  • 環境

    • windows10
    • Python 3.10.5
  • ライブラリ

    • OpenCV 4.8.0
    • matplotlib 3.6.1

処理内容ライブラリの対応を分かりやすく表にすると次の通りです。

説明
処理内容 モジュール・ライブラリ
画像の読み込み画像のネガポジ反転画素値へのアクセス画像への文字列の出力画像の表示 OpenCV
ヒストグラムの表示 matplotlib

画像はこちらを使います。

使用した画像

Airplane.jpg
使用した画像

画像の引用元はこちらです

http://www.ess.ic.kanagawa-it.ac.jp/app_images_j.html

画像の画素値へのアクセス方法

前回の記事を参考にして画像の画素値へアクセスしました。

補色の計算方法

こちらのソース

https://appakumaturi.hatenablog.com/entry/20120121/1327143125

によると、

補色はRGB値の中での最大値と最小値を足し合わせその値をRGBのそれぞれの値から引くことで補色のRGB値が算出される

そうです。
この方法を用いて、補色を計算しました。

画像上に文字を出力する方法

こちらのソース

https://shikaku-mafia.com/opencv-puttext/

を見ると、

cv2.putTextを用いることで画像上に文字を出力できる

そうです。

この方法を使って画像上に文字を出力しました。

複数の画像を横並びに表示する方法

こちらのソース

https://note.nkmk.me/python-opencv-hconcat-vconcat-np-tile/

を見ると、

cv2.hconcatを用いることで複数の画像を横並びに表示できる

そうです。

この方法を使って複数の画像を横並びに表示させました。

ソースコード

下にソースコードを示します。おそらく実行環境で示した環境では動くはず。

ソースコード
color_trans(comp).py
import cv2                                               #OpenCVをインポート
import matplotlib.pyplot as plt                          #matplotlibをpltという名前でインポート

img_original = cv2.imread('Airplane.jpg')                #画像を読み込み(元の画像表示用)
img_trans = cv2.imread('Airplane.jpg')                   #画像を読み込み(画像変換用)
img_BitwiseNot = cv2.bitwise_not(img_original)           #画像をネガポジ反転

img_trans_blue_val = []                                  #変換後の青(blue)の画素値を格納するためのリストの宣言
img_trans_green_val = []                                 #変換後の緑(green)の画素値を格納するためのリストの宣言
img_trans_red_val = []                                   #変換後の赤(red)の画素値を格納するためのリストの宣言

img_BitwiseNot_blue_val = []                             #ネガポジ反転後の青(blue)の画素値を格納するためのリストの宣言
img_BitwiseNot_green_val = []                            #ネガポジ反転後の緑(green)の画素値を格納するためのリストの宣言
img_BitwiseNot_red_val = []                              #ネガポジ反転後の赤(red)の画素値を格納するためのリストの宣言

for i in range(img_BitwiseNot.shape[0]):                        #画像のy座標iを画像の高さの分img_BitwiseNotの配列の第1引数に入力
	for j in range(img_BitwiseNot.shape[1]):                    #画像のx座標jを画像の幅の分img_BitwiseNotの配列の第2引数に入力
		img_BitwiseNot_blue_val.append(img_BitwiseNot[i,j,0])   #ネガポジ反転後の青(blue)の画素値をimg_BitwiseNot_blue_valというリストに追加
		img_BitwiseNot_green_val.append(img_BitwiseNot[i,j,1])  #ネガポジ反転後の緑(green)の画素値をimg_BitwiseNot_green_valというリストに追加
		img_BitwiseNot_red_val.append(img_BitwiseNot[i,j,2])    #ネガポジ反転後の赤(red)の画素値をimg_BitwiseNot_red_valというリストに追加

for i in range(img_trans.shape[0]):                      #画像のy座標iを画像の高さの分img_transの配列の第1引数に入力
	for j in range(img_trans.shape[1]):                  #画像のx座標jを画像の幅の分img_transの配列の第2引数に入力
		Max = int(max(img_trans[i,j]))                   #BGRのリストの最大値の取得(型変換をしないと255まで行くと0になってしまう)
		Min = int(min(img_trans[i,j]))                   #BGRのリストの最小値の取得(型変換をしないと255まで行くと0になってしまう)
		total = Max+Min                                  #BGR値のリストの最大値とBGR値の最小値の和の計算
		img_trans[i,j,0] = total-img_trans[i,j,0]        #和から青(B)の値を引いてその値を新しい青(B)の値にする
		img_trans[i,j,1] = total-img_trans[i,j,1]        #和から緑(G)の値を引いてその値を新しい緑(G)の値にする
		img_trans[i,j,2] = total-img_trans[i,j,2]        #和から赤(R)の値を引いてその値を新しい赤(R)の値にする
		
		img_trans_blue_val.append(img_trans[i,j,0])      #新しい青(B)の値をimg_trans_blue_valというリストに追加
		img_trans_green_val.append(img_trans[i,j,1])     #新しい緑(G)の値をimg_trans_green_valというリストに追加
		img_trans_red_val.append(img_trans[i,j,2])       #新しい赤(R)の値をimg_trans_red_valというリストに追加

#img_originalの画像に「Original」という文字を描画
img_original = cv2.putText(img_original,text='Original',org=(0,25),fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=1.0,color=(0,0,0),thickness=2,lineType=cv2.LINE_AA)
#img_transの画像に「Trans」という文字を描画
img_trans = cv2.putText(img_trans,text='Trans',org=(0,25),fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=1.0,color=(0,0,0),thickness=2,lineType=cv2.LINE_AA)
#img_BitwiseNotの画像に「Bitwise Not」という文字を描画
img_BitwiseNot = cv2.putText(img_BitwiseNot,text='Bitwise Not',org=(0,25),fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=1.0,color=(255,255,255),thickness=2,lineType=cv2.LINE_AA)

img_result = cv2.hconcat([img_original,img_trans,img_BitwiseNot])       #元の画像と変換後の画像を横に並べる
cv2.imshow("result",img_result)                                         #横に並べた画像を表示
cv2.waitKey()                                                           #window closeボタンが押されるまで待機

plt.hist(img_trans_blue_val,ec='black',label="Trans")                        #変換後の画素値に関するヒストグラムの設定(青(blue)について)
plt.hist(img_BitwiseNot_blue_val,ec='black',alpha=0.5,label="Bitwise Not")   #ネガポジ反転の画素値に関するヒストグラムの設定(青(blue)について)
plt.title('Blue')                                                            #タイトルの表示
plt.legend(loc='center',bbox_to_anchor=(0.8,1.08))                           #凡例の表示(グラフ外)
plt.show()                                                                   #ヒストグラムの表示

plt.hist(img_trans_green_val,ec='black',label="Trans")                       #変換後の画素値に関するヒストグラムの設定(緑(green)について)
plt.hist(img_BitwiseNot_green_val,ec='black',alpha=0.5,label="Bitwise Not")  #ネガポジ反転の画素値に関するヒストグラムの設定(緑(green)について)
plt.title('Green')                                                           #タイトルの表示
plt.legend(loc='center',bbox_to_anchor=(0.8,1.08))                           #凡例の表示(グラフ外)
plt.show()                                                                   #ヒストグラムの表示

plt.hist(img_trans_red_val,ec='black',label="Trans")                         #変換後の画素値に関するヒストグラムの設定(赤(red)について)
plt.hist(img_BitwiseNot_red_val,ec='black',alpha=0.5,label="Bitwise Not")    #ネガポジ反転の画素値に関するヒストグラムの設定(赤(red)について)
plt.title('Red')                                                             #タイトルの表示
plt.legend(loc='center',bbox_to_anchor=(0.8,1.08))                           #凡例の表示(グラフ外)
plt.show()                                                                   #ヒストグラムを表示

結果

まず、出力画像を示します。

出力画像

result.jpg

次に、ヒストグラムを示します。

青(B)のヒストグラム

comp_hist_blue.png

緑(G)のヒストグラム

comp_hist_green.png

赤(R)のヒストグラム

comp_hist_red.png

特徴

特徴はこんな感じです。

画像について

画像を見ると、

  • オリジナル画像で赤系統の色だと補色による色変換とネガポジ反転での色変換で同系色

になるみたいです。

ヒストグラムについて

ヒストグラムを見ると、

  • 赤(R)のヒストグラムでは Transの最頻値の頻度 の方が Bitwise Notの最頻値の頻度 よりも多くなっている
  • すべてのヒストグラムTransの最頻値 の方が Bitwise Notの最頻値 よりも大きくなっている

ことが分かります。

まとめ

今回は、前回のTwitter(X)のアンケートでトップだった動画像処理から画像の画素ごとの補色で色変換を行い、その結果とネガポジ反転から得られた結果とオリジナル画像を並べて表示させ補色による色変換とネガポジ反転の画素値によるヒストグラムを表示させるプログラムを作成しました。
この記事が実際に役に立つかどうかは分かりませんが、誰かの役に立ってくれると嬉しいです。
記事を執筆する余力があれば、次回も記事を投稿する予定です。
次回の予定としては、今回のTwitter(X)のアンケートでトップだった動画像処理からwebカメラから得られた映像にγ変換をかけて明るくしたリアルタイムの動画をTkinterを用いて表示させγの値をTkintertkinter.Scaleで調整させるプログラムを作成できたのでそれに関する記事を投稿予定です!!

Discussion