PythonのOpenCVで画像生成する際の高速化についての質問です。
以下のような2重ループがある方法で円形グラデーションを生成すると、画素を網羅するため非常に遅いです。
python
1import cv2 2import numpy as np 3 4PIXSIZE=4096 5 6# 真っ白の画像を作成 7img = np.zeros((PIXSIZE, PIXSIZE, 3), np.uint8) 8img += 255 9 10cx, cy = PIXSIZE/2, PIXSIZE/2 # 円の中心 11r = PIXSIZE/2 # 円の半径 12x0, y0 = 1089, 2411 # 点 (任意のグラデーション中心点) 13 14def inside_circle(x, y): 15 '''円の内部かどうか 16 ''' 17 return np.sqrt((x - cx) ** 2 + (y - cy) ** 2) <= r 18 19 20def get_intersections(x1, y1): 21 '''直線と円の交点を求める。 22 ''' 23 a = (x1 - x0) ** 2 + (y1 - y0) ** 2 24 if a == 0: # (x0, y0) の場合、t = 0 25 return 0 26 27 b = 2 * (x1 - x0) * (x0 - cx) + 2 * (y1 - y0) * (y0 - cy) 28 c = (x0 - cx) ** 2 + (y0 - cy) ** 2 - r ** 2 29 30 D = b ** 2 - 4 * a * c 31 t1 = (-b + np.sqrt(D)) / (2 * a) 32 t2 = (-b - np.sqrt(D)) / (2 * a) 33 t = max(t1, t2) # t > 0 の点が求める交点 34 35 return t 36 37def get_intersections2(x2, y2): 38 '''直線と円の交点を求める。 39 ''' 40 a = (x2 - cx) ** 2 + (y2 - cy) ** 2 41 if a == 0: # (x0, y0) の場合、t = 0 42 return 0 43 44 b = 2 * (x2 - cx) * (cx - cx) + 2 * (y2 - cy) * (cy - cy) 45 c = (cx - cx) ** 2 + (cy - cy) ** 2 - r ** 2 46 47 D = b ** 2 - 4 * a * c 48 t1 = (-b + np.sqrt(D)) / (2 * a) 49 t2 = (-b - np.sqrt(D)) / (2 * a) 50 t = max(t1, t2) # t > 0 の点が求める交点 51 52 return t 53 54innerColorB = 206 55innerColorG = 183 56innerColorR = 145 57outerColorB = 166 58outerColorG = 93 59outerColorR = 4 60 61night_innerColorB = 80 62night_innerColorG = 35 63night_innerColorR = 25 64night_outerColorB = 166 65night_outerColorG = 93 66night_outerColorR = 4 67 68# 任意の点の円の内外判定 69if inside_circle(x0, y0): 70 for y in range(img.shape[0]): 71 for x in range(img.shape[1]): 72 if inside_circle(x, y): 73 # 円の内部の場合、t を計算する。 74 t = get_intersections(x, y) 75 # t に基づき、輝度値を決める。 76 valB = int((1 - 1 / t) * innerColorB + (1 / t) * outerColorB) if t > 0 else 255 77 valG = int((1 - 1 / t) * innerColorG + (1 / t) * outerColorG) if t > 0 else 255 78 valR = int((1 - 1 / t) * innerColorR + (1 / t) * outerColorR) if t > 0 else 255 79 80 img[y, x, 0] = valB 81 img[y, x, 1] = valG 82 img[y, x, 2] = valR 83 cv2.imwrite('back.png', img) 84else: 85 for y in range(img.shape[0]): 86 for x in range(img.shape[1]): 87 if inside_circle(x, y): 88 # 円の内部の場合、t を計算する。 89 t = get_intersections2(x, y) 90 # t に基づき、輝度値を決める。 91 valB = int((1 - 1 / t) * night_innerColorB + (1 / t) * night_outerColorB) if t > 0 else 255 92 valG = int((1 - 1 / t) * night_innerColorG + (1 / t) * night_outerColorG) if t > 0 else 255 93 valR = int((1 - 1 / t) * night_innerColorR + (1 / t) * night_outerColorR) if t > 0 else 255 94 95 img[y, x, 0] = valB 96 img[y, x, 1] = valG 97 img[y, x, 2] = valR 98 cv2.imwrite('back.png', img)
既存画像のカラー置き換えの高速化は
https://teratail.com/questions/265066
見つけましたが、画像生成時の高速化が分かりません。
#任意の点の円の内外判定
以降のif~else内の2重ループがボトルネックなのは分かるのですが、この部分の高速化はできないのでしょうか?
よろしくお願いします。
回答2件
あなたの回答
tips
プレビュー