質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

2549閲覧

PythonとOpenCVを使った色の反転のやり方がわかりません。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/14 02:18

編集2021/12/15 08:44

ガンマ補正に最適な値を設定する方法というサイトのプログラムを触っているのですが、

明るい画像の場合は、グレーまたは値の画像を反転し、暗い画像の場合と同様に処理してから、もう一度反転して、値の画像を使用している場合は再結合します。

とありました。
そのまんまなのですが、明るい画像の場合の値の画像を反転し、暗い画像の場合と同様に処理してから、もう一度反転して、値の画像を使用している場合は再結合する方法がわかりません。

今は再結合の方法がわかりません。

どなたか教えてください。お願い致します。

pyrhon

1import cv2 2import numpy as np 3import math 4 5# read image 6img = cv2.imread('lioncuddle1.jpg') 7 8 9# METHOD 2: HSV (or other color spaces) 10 11# convert img to HSV 12hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 13hue, sat, val = cv2.split(hsv) 14 15# compute gamma = log(mid*255)/log(mean) 16mid = 0.5 17mean = np.mean(val) 18gamma = math.log(mid*255)/math.log(mean) 19print(gamma) 20 21# do gamma correction on value channel 22val_gamma = np.power(val, gamma).clip(0,255).astype(np.uint8) 23 24# combine new value channel with original hue and sat channels 25hsv_gamma = cv2.merge([hue, sat, val_gamma]) 26img_gamma2 = cv2.cvtColor(hsv_gamma, cv2.COLOR_HSV2BGR) 27 28# show results 29cv2.imshow('input', img) 30cv2.imshow('result1', img_gamma1) 31cv2.imshow('result2', img_gamma2) 32cv2.waitKey(0) 33cv2.destroyAllWindows() 34 35# save results 36cv2.imwrite('lioncuddle1_gamma2.jpg', img_gamma2)

追記
プログラムを間違えており、サイトに載っているプログラムをそのまんま使用したらできたのですが、

暗い画像の場合と同様に処理してから、もう一度反転して、値の画像を使用している場合は再結合します。

とあるのですが、暗い画像と同様に処理した後、もう一度反転しました。
しかし、どこでどうやって再結合すればいいのかわかりません。

python

1 #色の反転 2 img = cv2.bitwise_not(img) 3 4 # imgをHSVに変換 5 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 6 hue, sat, val = cv2.split(hsv) 7 8 # gammaの計算 = log(mid*255)/log(mean) 9 mid = 0.5 10 mean = np.mean(val) 11 gamma = math.log(mid*255)/math.log(mean) 12 print(gamma) 13 14 #明度チャンネルにガンマ補正を行う 15 val_gamma = np.power(val, gamma).clip(0,255).astype(np.uint8) 16 17 18 #新しい明度チャンネルを元の色相と彩度チャンネルに合成します 19 hsv_gamma = cv2.merge([hue, sat, val_gamma]) 20 img_gamma2 = cv2.cvtColor(hsv_gamma, cv2.COLOR_HSV2BGR) 21 22 #色の反転 23 img_gamma2 = cv2.bitwise_not(img_gamma2) 24 25 26 #書き込み 27 cv2.imwrite(sys.argv[2],img_gamma2)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jbpb0

2021/12/14 04:00

> invert the gray or value image 値が0〜255の場合は、255を引いてから-1を掛ければいいのでは?
退会済みユーザー

退会済みユーザー

2021/12/14 04:10

value imageの方なのですが、大丈夫ですか? 大丈夫なら、どの様に入れればいいのでしょうか?
fana

2021/12/14 04:26

そろそろ自分が何やってるかを理解することを始めてみてはどうですか? 延々と意味もわからず他人のコードをいじくり回しては質問する無価値な営みを続けるのですか? ・「反転」が cv2.bitwise_not で達成できているならば,「反転」手段は解決している. ・value のchだけを処理して「再結合」する処理コードもある この状態で,何が問題として存在しているんですか?
fana

2021/12/14 04:40 編集

下側のコードでは gamma の計算式と,gamma を使う箇所がちぐはぐです. 少しでも処理の意味を把握してればこんなことにはならない. e.g. 画像がめちゃくちゃ暗くて mean の値が 32 の場合,この計算式だと gamma は約 1.4 になる. 1.0 を超えてるやん. 値域を 0.0~1.0 に正規化した世界で gamma乗 の計算をするならばこの時点で目的と反したgamma値になっていることがわかるハズ.
退会済みユーザー

退会済みユーザー

2021/12/14 04:41

> 「反転」手段は解決している. 2回目の元に戻す反転がうまくいかず、真っ黒になってしまいます > value のchだけを処理して「再結合」する処理コードもある これはまだ取り組んでいないためわからないです。 > 下側のコードでは gamma の計算式と,gamma を使う箇所がちぐはぐです. 少しでも処理の意味を把握してればこんなことにはならない 自分で組んでいるところではありませんが、そうは思いません。
退会済みユーザー

退会済みユーザー

2021/12/14 04:53

ガンマは 0.9724143545505973 で、超えていません。 また、暗い画像でも 1.0183983588700147 で1.0を超えていますが、問題はありません
fana

2021/12/14 05:25 編集

("e.g." とは「例えば」という意味だ.他の値の場合にOKということではない.) > ガンマは > 0.9724143545505973 であれば,meanは 0.5*255 を超えているハズ.つまり「明るいか暗いか」と訊かれたら「明るい」. 「反転」した結果の輝度平均が「明るい」ならば,元々は「暗い」画像だったハズ. > 明るい画像の場合は、グレーまたは値の画像を反転し… という話と既に食い違っているね. 仮にそこのところは無視するとしてもだ, 輝度平均が「明るい」ときに 1.0 に満たないガンマを用いて変換したならば,その結果は「もっと明るい」ものになると思うのだが.それでいいのか?って話をしている. 面倒だから全部書くが, 【値域を 0.0~1.0 に正規化した世界で gamma乗 の計算をするならば,gammaの値の算出もその世界で行うべきではないのか?】 という話だ.検証されたい.
fana

2021/12/14 05:22 編集

さて,別の話として > 2回目の元に戻す反転がうまくいかず、真っ黒になってしまいます ということは,2回目の反転の直前は「真っ白」なわけだ. いつ「真っ白」になってしまったのか? を突き止めればよいのではないか? まぁ画像をいじくってる処理は実質一か所しかないから,確認するまでもなく > image3 = cv2.LUT(image2, y) が犯人であろうと想像は付くのだが,実際に確認すべき. で,ここで「真っ白」になるならば,原因は「 y が悪い」に決まっている. そういうくらいのことは自身で追うべき. もしも y の値を一通り確認しても妥当な値なのであれば,これは「おそらく」だが,yの型が悪い.8bitデータになっていないのではないか? ※俺はpythonを知らんから > (x / 255) ** gamma * 255 なる演算の型がどうなるのかわからんから,原因がどちらにあるのか判断付かん.
jbpb0

2021/12/14 05:46

> value imageの方なのですが、大丈夫ですか? cv2.cvtColor(img, cv2.COLOR_BGR2HSV)で変換したHSVの「V」は0〜255みたいなので、変換前のRGB(BGR)画像がガンマ1.0(線形)ならば大丈夫だと思いますよ 質問者さんがやろうとしてる「適切なガンマ値を設定する」が大丈夫という意味ではなく、明るさを反転(黒→白を白→黒に)が大丈夫、という意味ですが
退会済みユーザー

退会済みユーザー

2021/12/14 07:09

jbpb0さんの 値が0〜255の場合は、255を引いてから-1を掛けるのをやりたいのですが、 どうすればいいのか、教えていただけませんか?
fana

2021/12/14 07:13

255を引いてから-1倍するくらいなら,最初から「255 から引く」だけで良いのではあるまいか.
fana

2021/12/14 07:19 編集

というか,cv2.bitwise_not でちゃんと反転してるんでしょ? だったらそれでよくね? (って,最初から言ってるんだが… そこに何の問題があるの?????) 万が一,「ちゃんと反転してるかどうかすら把握してない」とかいうことであれば, 何かテキトーな画像を cv2.bitwise_not に食わせてみて色が反転してるかを実際にチェックしてみればいいよね. 何ならさらにそいつを cv2.bitwise_not に食わせたら元に戻るかも見てみればいいよね.
退会済みユーザー

退会済みユーザー

2021/12/14 07:32 編集

> cv2.bitwise_not でちゃんと反転してるんでしょ? 反転できているのですが、yの値をみても何が原因かわからず > yの型が悪い.8bitデータになっていないのではないか? というところで、どうすればいいのか調べています。 そこで、この方法で出来るならそれでやってみたいので聞いています。 print(y)をしたところ [ 0. 0.90307456 1.82933003 2.76454149 3.70561689                  ・                   ・ 249.90893263 250.92699743 251.94513685 252.96335062 253.98163843 255. ] となりました。 暗い画像の時とそんなに変わらないので、苦戦しています。
fana

2021/12/14 07:40 編集

小数点以下が出てる時点でもうフォーマットが違う感. まぁ,それが本当に問題を起こしているか否かは 「cv2.LUT(image2, y) が image2 と y のフォーマットが違う場合をサポートしてるかどうか?」次第だ. 手元にあった OpenCV のバージョン 3.2.0 (古い!) を C++ で使って y を float として試してみた限りでは,結果はいかれてしまうようだが, このあたりは OpenCVのバージョンにも依存するかもしれない. ↓修正 ちがう.正当な動作結果として型が変わるのだな. LUTの型が結果画像の型を支配するという仕様だ.
退会済みユーザー

退会済みユーザー

2021/12/14 07:32

#色の反転 image2 = cv2.bitwise_not(img) cv2.imwrite('test/test1.jpg',image2) #画像を保存 # imgをHSVに変換 hsv = cv2.cvtColor(image2, cv2.COLOR_BGR2HSV) hue, sat, val = cv2.split(hsv) # gammaの計算 = log(mid*255)/log(mean) mid = 0.5 mean = np.mean(val) print(mean) gamma = math.log(mid*255)/math.log(mean) print(gamma) x = np.arange(256) y = (x / 255) ** gamma * 255 # 変換する。 image3 = cv2.LUT(image2, y) cv2.imwrite('test/test2.jpg',image3) #画像を保存 #色の反転 dst1 = cv2.bitwise_not(image3) cv2.imwrite('test/test3.jpg',dst1) #画像を保存 #書き込み cv2.imwrite(sys.argv[2],dst1) 今はこの様にして画像を作成しているのですが、ガンマ補正が終わったところまでの画像 今回はtest2.jpgは問題ないのですが、次の色の反転のところで、黒くなってしまうので、jbpb0さんの方法が使えないかと考えています。
fana

2021/12/15 08:38

追記に対して: > …(略)…なので、あっていると思います 「あっている」と考える理由がきちんと存在しているのであれば,自信を持って「あっている」という前提の下で検証すればよいのでは.(結果が全てなのだから結果を見て判断されると良い.)
退会済みユーザー

退会済みユーザー

2021/12/15 08:42

あっていると考えるのは、合成の後で色の反転を行なった結果もとの画像の様になったため、できていると考えました。 しかし、再結合がなんなのか、どうやるのかがわからないのに、プログラムの製作者は説明で書いているため、やり方をわかる人やにお聞きして検証したいので質問しました。 文章は直します。
fana

2021/12/15 08:44

細かい話をすれば, > 明るい画像の場合は、グレーまたは値の画像を反転し… という話に素直に従うのであれば, 最初の反転対象は「グレーまたは値の画像」つまりここでは value のchであるのだから,その処理手順は 元画像をHSVに変換 → H,S,V に分離 → Vを反転 → V' = Vをガンマ補正したもの → V' を反転 → H,S と V' を合成してHSV画像を作る (←これを「再結合」と呼んでいるのであろう) → BGR色空間に戻す という感じとなろう.
fana

2021/12/15 08:48

あなたのコードでは 元画像を最初に反転する (R,G,B 全てを反転) → HSVに変換 → H,S,V に分離 → V' = Vをガンマ補正したもの → H,S と V' を合成してHSV画像を作る (←「再結合」) → BGR色空間に戻す → 最後に反転 という形になっているが,結果が同じであれば(←これを検証すればよい)問題ないでしょう.
退会済みユーザー

退会済みユーザー

2021/12/15 08:48

自分も 「プログラムでは合成、しかし、変化させた時は再結合」 といっているのではないかと考えました。 しかし、どこまでが暗い画像と同じ処理に含まれるのかがわからないので、もやもやしています。 暗い画像と同じ処理に含まれないのであれば、そのプログラムは自作する必要があるのではないか?色の反転はプログラムに記入されていないのだし。 などと考えてしまい。詳しい人の意見をお聞きしたいのです。
退会済みユーザー

退会済みユーザー

2021/12/15 08:50

Vを反転が違うのですか! ありがとうございます。 cv2.bitwise_not でVが反転できるのか試してみます。
fana

2021/12/15 08:54

> Vを反転が違うのですか! 繰り返しになるが,あくまでも 【大元の話の手順とは違う】 というだけの話であって 処理としては等価ならOK.(まず等価であろうと思う)
fana

2021/12/15 08:57

> どこまでが暗い画像と同じ処理に含まれるのかがわからない 反転しないときの処理を ↑ の私の記述みたく書いてみればよい. それが「暗い画像」の処理. 明るい場合には 反転 「暗い画像」の処理と同じ処理 反転 ということをするだけ.
退会済みユーザー

退会済みユーザー

2021/12/15 09:05 編集

やっぱり、Vを反転させるとおかしくなりました。 間違えました。 最初のVの反転忘れてました。
guest

回答1

0

起きているだろうことをまとめておく.

  • 最初の反転 image2 = cv2.bitwise_not(img) は,img の画素値が8bit整数であろうから(3ch全部反転するという処理としては)正当である.
  • image3 = cv2.LUT(image2, y) この結果の image3 の画素値の型は8bit整数ではない別のものになっている.(おそらく浮動小数点数)

これは LUT の処理結果データの型が y の要素の型に依存しているため.

  • 故に,dst1 = cv2.bitwise_not(image3) は最初とは異なり「反転」とはならない.

LUT に与える変換テーブル y の型を 8bit とするか,あるいは,LUT変換結果データ image3 を先に 8bit のデータに戻してから反転すればよかろう.


#ガンマ変換の処理が間違っていると見えるが,本件の主題ではなさそうなので回答には含めずにおく.

投稿2021/12/14 07:47

fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/12/14 07:49

そのコードを実行していない者の戯言かもしれないので 間違っている場合には完全論破のコメントを付しての低評価をよろしく.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問