Pythonで作りたいものを作る!No001、ローカルガンマ処理ツール。vol2 続き。大体作成完了

vol1の続きです。ここで大体完成させてしまいます。

ポイントは2か所

ステップ4特定の領域のサイズと重みづけ関数とする。ブラシで処理したようにする。
ステップ5マウスを置いた場所の周辺xx画素の範囲のみ行う

の2つを導入します。

<ステップ4>特定の領域のサイズと重みづけ関数とする。ブラシで処理したようにする。

これは、関数を重みづけするように式で書き込むだけですので、さほど難しくないです。

#ガンマnn2が円内一定の場合
nn2=nn

#ガンマnn2が円内で線形の重みづけをした場合。
nn2=(nn-1)*((rr**2)-((xx-x)**2+(yy-y)**2))/(rr**2)+1 

グラデーションを付けたことにより、自然と周囲となじむ処理になります。

左から、処理前、一様ガンマ、グラデーションガンマ(γ=0.6)です。

こんな感じでグラデーションを付けるとやんわり持ち上げられます。

少し価値が伝わってきたかと思います。

ステップ5マウスを置いた場所の周辺xx画素の範囲のみ行う。

一気に、ほぼ完成まで進めます。

つかったのは

cv2.setMouseCallback   マウスイベント情報を取得する関数。

event == cv2.EVENT_LBUTTONUP: #実際のイベント関数です。

の2つです。詳しい例はこちらに書いてあります。

これを入れて、出来上がったコードが以下になります。

import numpy as np
import cv2
import sys
import os, tkinter, tkinter.filedialog, tkinter.messagebox

####以下は画像ファイルを選ぶ場合
def f_opengui():
  root = tkinter.Tk()
  root.withdraw()
  fTyp = [("","*")]
  iDir = os.path.abspath(os.path.dirname(__file__))
  file = tkinter.filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir)
  return file

img=cv2.imread(f_opengui(),1)
img2=img
img0=img

ym=len(img)
xm=len(img[0])
zm=len(img[0,0])
print(xm,ym,zm)

def mouse_event(event, x, y, flags, param):
    #配列外参照回避
    #クリック地点を配列に格納
    if event == cv2.EVENT_LBUTTONUP:
        print(x,y)
        for xx in range(xm):
            for yy in range(ym):
                for zz in range(zm):
                    if rr**2>((xx-x)**2+(yy-y)**2):
                        #nn2=nn
                        nn2=(nn-1)*((rr**2)-((xx-x)**2+(yy-y)**2))/(rr**2)+1                       
                        dd=((img[yy,xx,zz]/(bb-aa)-aa/(bb-aa))**nn2)*255
                        if dd<0:
                            img2[yy,xx,zz]=0
                        elif dd>255:
                            img2[yy,xx,zz]=255
                        else:
                            img2[yy,xx,zz]=dd
                zz=0
            yy=0
img2=img #編集物入れ物

#元ファイルを表示
cv2.imshow('Base',img2)
cv2.waitKey(1)   

#加工の準備 パラメータ取得 (パラメータは仮固定20230821)
aa=0 #aa=int(input("黒引きaa= (何もしない場合0)   "))
bb=255 #bb=int(input("白とびbb= (何もしない場合255)   "))
nn=0.6 #nn=float(input("gamma nn= (何もしない場合1)   "))
print(aa,bb,nn)
rr=50 #rr=int(input("範囲 rr= "))

cv2.namedWindow("window_ans", cv2.WINDOW_AUTOSIZE) #
cv2.setMouseCallback("window_ans", mouse_event) #

#「q」が押されるまでループ
while True:
    #画像の表示
    cv2.imshow("window_ans", img2) #leftimg
    #キー入力
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
    if cv2.waitKey(1) & 0xFF == ord("b"):
        img2=img0
cv2.imwrite('c:/temp/gamma_img2.bmp',img2)
cv2.destroyAllWindows()
#-------------------------------------追加分修了

cv2.waitKey(0)
#cv2.destroyAllWindows()

これで、クリックしたとこが特定の円の範囲でガンマ処理を行われ、

ガンマの値が0~1以下の場合、クリックした分だけ、やんわり持ち上げられる処理が加わります。

上の写真は左のもとの写真の下のほうの道路の部分をクリックして持ち上げてみました。

結構、暗がりの中にも低階調で数値が残っていて、持ち上げると見えるようになるものですね。

終了は画像にカーソルがある状態で”q”で終了します。

また、ちょっと明るめにしたりするのにも使えます。

左は元のもの、右はガンマで少し明るくしたものです。年賀状用の写真の微修正なんかにも使えますね。

ガンマが1より大きいと引き締めたりする効果も与えられます。ガンマ以外にも黒引き値を設定しても局所的に引き締められます。テカリが抑えられます。

こんな感じで使えます。

これでほぼ完成ですが、次回、GUIでパブラシのパラメータを修正できるようにしたいと思います。

こちらの本をお勧めします。

コメント

タイトルとURLをコピーしました