目的:上画像の黄色部分の歯をAffine変換による回転により下画像のように縦向きに変換。
-90度から90度まで回転させ最適な角度を出力。
自分で考えたものとしては、2パターンあり、
- 矩形で歯を囲みその中の歯以外のピクセルを合計し最小のものを最適とする。
- 列ごとに歯部分のピクセルを数え最多のものを最適とする。
この2つだと実際に見てみると最適でないように感じました。
縦向きになったとどのように人が認知しているのか知りたいです。最適な角度を算出するアイデアをご教授願います。
添付フォルダ(tooth_array.zip内に3つnpyファイル、ipynbファイル)
Python
1#coding:utf-8 2import numpy as np 3import matplotlib.pyplot as plt 4 5# アフィン変換で画像配列の回転 6def rotate_affine(src, theta): 7 # 元画像のサイズを取得 8 h, w = src.shape[0], src.shape[1] 9 10 # 出力画像用の配列生成(要素は全て0) 11 dst = np.zeros((h,w)) 12 13 # degreeかrradianに変換 14 rd = np.radians(theta) 15 16 # アフィン変換 17 for y in range(0, h): 18 for x in range(0, w): 19 xi = int((x - int(w/2))*np.cos(rd) - (y - int(h/2))*np.sin(rd) + int(w/2)) 20 yi = int((x - int(w/2))*np.sin(rd) + (y - int(h/2))*np.cos(rd) + int(h/2)) 21 22 # 変換後の座標が範囲外でなければ出力画像配列に画素値を代入 23 if yi < h - 1 and xi < w - 1 and yi > 0 and xi > 0: 24 dst[y][x] = src[yi][xi] 25 26 return dst 27 28def pattern1(src): 29 sum_cnt = 1000000 30 best_theta = 0 31 for theta in range(-90,90+1): 32 dst = rotate_affine(src,theta) 33 vertical_info = np.count_nonzero(dst ==255, axis=0) 34 side_info = np.count_nonzero(dst ==255, axis=1) 35 min_flag = False 36 for i,num in enumerate(vertical_info): 37 if num != 0 and min_flag == False: 38 min_flag = True 39 min_x = i 40 if num == 0 and min_flag == True: 41 max_x = i-1 42 min_flag = False 43 44 for i,num in enumerate(side_info): 45 if num != 0 and min_flag == False: 46 min_flag = True 47 min_y = i 48 if num == 0 and min_flag == True: 49 max_y = i-1 50 min_flag = False 51 tooth_co_info = [min_y,min_x,max_y,max_x] 52 ex_dst = dst[tooth_co_info[0]:tooth_co_info[2]+1,tooth_co_info[1]:tooth_co_info[3]+1] 53 print("theta,sum:{},{}".format(theta,np.count_nonzero(ex_dst ==0, axis=0).sum())) 54 if np.count_nonzero(ex_dst ==0, axis=0).sum() < sum_cnt: 55 sum_cnt = np.count_nonzero(ex_dst ==0, axis=0).sum() 56 best_theta = theta 57 print("best") 58 print(best_theta,sum_cnt) 59 60 61def pattern2(src): 62 max_cnt = 0 63 best_theta = 0 64 for theta in range(-90,90+1): 65 dst = rotate_affine(src,theta) 66 print("theta,count:{},{}".format(theta,np.count_nonzero(dst ==255, axis=0).max())) 67 if np.count_nonzero(dst ==255, axis=0).max() > max_cnt: 68 max_cnt = np.count_nonzero(dst ==255, axis=0).max() 69 best_theta = theta 70 print("best") 71 print("theta,count:{},{}".format(theta,max_cnt)) 72 73if __name__ == '__main__': 74 mask = np.load('mask.npy') 75 bi_mask = np.where(mask==True,255,0) 76 h, w = bi_mask.shape[0], bi_mask.shape[1] 77 src = np.zeros((int((w**2 + h**2)**(1/2)), int((w**2 + h**2)**(1/2)))) 78 dx,dy = int((w**2 + h**2)**(1/2)/2) - int(w/2), int((w**2 + h**2)**(1/2)/2) - int(h/2) 79 80 for y in range(0, h):#平行移動 81 for x in range(0, w): 82 src[y+dy][x+dx] = bi_mask[y][x] 83 84 theta = 0 85 dst = rotate_affine(src,theta) 86 plt.imshow(dst) 87 plt.show() 88 89 pattern1(src) #切り替え必要 90# pattern2(src)
回答1件
あなたの回答
tips
プレビュー