画像に集中線をいれるコード
久しぶりにPythonのコーディングネタ。軽めですが。
モチベーション
このネタ。でも正直テストとかよくしらないです。ただ集中線を描くプログラムというワードにピンときて書いてみたくなりました。最近はOpenCVを使ったコーディングにめぞめぞしていたので丁度よい題材でした。
まずはコードを
みてくださいー。
import cv2 import math import random def setEffect(pic, center = (0.5, 0.5)): he, wi = pic.shape[:2] leng = math.sqrt(he ** 2 + wi ** 2) for rd in range(360): k = rd * math.pi/180 r = random.uniform(0.20,0.50) x = wi * center[0] + r * leng * math.cos(k) y = he * center[1] + r * leng * math.sin(k) dx = wi * center[0] + leng * math.cos(k) dy = he * center[1] + leng * math.sin(k) cv2.line(pic, (int(x), int(y)), (int(dx), int(dy)), (0, 0, 0), 2) cv2.imshow('test', pic) cv2.waitKey(0) cv2.destryAllWindows() img = cv2.imread("test.jpg") setEffect(img)
例として拾い物のPUBGというネットワークゲームのスクショをいれてみますね。ちょうどよいのこれしかなかった。 これを入れると、以下の画像が出てきます。
うひょーい、できましたー!
解説
画像データを引数にとっております。あと、集中線の中心となる場所を指定できます。Defaultでど真ん中にしております。 あと、画像の縦横の長さを取得して起きます。そのデータから集中線の長さのもととなる値を計算しています。十分な長さを確保するため、画像の対角線の長さにしてあります。
def setEffect(pic, center = (0.5, 0.5)): he, wi = pic.shape[:2] leng = math.sqrt(he ** 2 + wi ** 2)
中心から360ぐるっと回る繰り返しで1度ずつ線を引くようにします。kは度数から三角関数の引数となる値の計算をします。2 pi が360度なので、1度は pi/180ですね。 あと、集中線の長さをランダムに指定します。r は0.2 ~ 0.5 までのFloatの乱数を出します。
for rd in range(360): k = rd * math.pi/180 r = random.uniform(0.20,0.50)
線引きの描写です。 各度数ごとに(x, y) から (dx, dy)の線をひくのですが、中心は先ほど指定したように画像のど真ん中です。先ほど求めた対角線の長さ leng を放射状に直線を引きますが、線の引き始めはランダム値の割合 (0.2-0.5)からになります。終わりはleng の終わりまで。対角線の長さにしたのはどの中心地からも必ず画像の外側に行くからです。。 角度はcos(k), sin(k)で指定します。
x = wi * center[0] + r * leng * math.cos(k) y = he * center[1] + r * leng * math.sin(k) dx = wi * center[0] + leng * math.cos(k) dy = he * center[1] + leng * math.sin(k) cv2.line(pic, (int(x), int(y)), (int(dx), int(dy)), (0, 0, 0), 2)
imshowで表示。そのままだと画像が一瞬で消えてしまいますので、waitKey(0)で待たせておきます。 destryAllWindows()できちんとお掃除をしておきます。
cv2.imshow('test', pic) cv2.waitKey(0) cv2.destryAllWindows()
感想
行数自体は長くないのですが、数学でならった円(楕円)や三角関数の公式を思い出すのにちょっとだけ時間がかかりました。 プログラムをよく書くようになって数学的センスって大事。今更、勉強をさぼった過去を悔いてもしょうがないのでこうやって書きながら思い出しながらいけたらよいかと思ってます。