0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2023-09-01

目次

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

はじめに

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


マイページについて

主にPythonについての記事を投稿してます!!

マイページはこちら

X(Twitter)について

Qiitaの新着記事の通知おススメの理工学書の紹介をツイートしてます!!

X(Twitter)はこちら

Zennについて

主に自分の書いたQiitaの記事の転載Pythonを使っていて遭遇したエラーの対処法のような記事を投稿していく予定です!!

Zennはこちら

実行環境

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

実行環境
  • 環境

    • windows10
    • Python 3.10.5
  • ライブラリ

    • OpenCV 4.8.0
    • matplotlib 3.6.1

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

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

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

使用した画像

使用した画像

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

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

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

補色の計算方法

こちらのソース

によると、

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

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

この方法だと OpenCVのRGB値の範囲0~255であり整数型(int)に型変換しないと和が255以上の値だと255を超えると0に初期化されてしまいます。
この問題を解決するために、最大値と最小値を整数型(int)に型変換して和を出しました。

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

こちらのソース

を見ると、

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

そうです。

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

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

こちらのソース

を見ると、

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

Bitwise Notの文字は文字を見えやすくするために白色にしました。

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

青(B)のヒストグラム

comp_hist_blue.png

緑(G)のヒストグラム

comp_hist_green.png

赤(R)のヒストグラム

comp_hist_red.png

  • Trans補色による色変換のヒストグラム
  • Bitwise Notネガポジ反転のヒストグラム

です。

特徴

特徴はこんな感じです。

画像について

画像を見ると、

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

になるみたいです。

ヒストグラムについて

ヒストグラムを見ると、

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

ことが分かります。

まとめ

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

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?