回答編集履歴

10

コード内のコメントを修正

2020/11/27 23:34

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -50,7 +50,9 @@
50
50
 
51
51
  # 図形を立てた時の、中心軸に対する慣性モーメント
52
52
 
53
- # mass:縦軸ピクセル数 * radius:中心軸からの左右のピクセル距離を合計している
53
+ # mass:縦軸ピクセル数radius:中心軸からの左右のピクセル距離
54
+
55
+ # 慣性モーメント = Σ mass * radius^2
54
56
 
55
57
  def inertia(img):
56
58
 
@@ -62,7 +64,7 @@
62
64
 
63
65
  radius = radius[radius != 0] - 0.5 # 中心位置の補正
64
66
 
65
- return (mass * radius * radius).sum() # 慣性モーメント= Σ m*r^2
67
+ return (mass * radius * radius).sum()
66
68
 
67
69
 
68
70
 
@@ -74,7 +76,7 @@
74
76
 
75
77
 
76
78
 
77
- # 最小化関数の最小値を求めることで、-90〜90度の回転時の最小曲げモーメントを得る
79
+ # 最小化関数の最小値を求めることで、-90〜90度の回転時の最小慣性モーメントを得る
78
80
 
79
81
  res = optimize.minimize_scalar(
80
82
 

9

一部修正

2020/11/27 23:34

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
 
4
4
 
5
- - アイデアとしては、まずは歯の形を平面に置いた重心に中心を揃え、その後、歯の形を立てて中心を軸に自重で回転できるようにしたときにバランスが取れる回転位置を求める、というものです。
5
+ - アイデアとしては、まずは歯の形を平面に置いた重心に中心を揃え、その後、歯の形を立ててバランスが取れる回転位置を求める、というものです。
6
6
 
7
- - バランスが取れるかどうかは歯全体を重さ密度一定の剛体としてみた場合に、垂直に立てた状態で、中心軸に対する慣性モーメントが最小になる、という定義をしました。
7
+ - バランスが取れるかどうかは歯全体を重さ密度一定の剛体としてみた場合に、垂直に立てた状態で、中心軸に対する慣性モーメントが最小になる、という定義をしました。
8
8
 
9
9
  - 最初の重心、平行移動、回転は、全て`scipy.ndimage`を使い、モーメント演算だけは見当たらないので自作、そしてモーメント最小を求めるのに`scipy.optimize`を使いました。
10
10
 

8

一部修正

2020/11/27 12:49

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
 
15
- 以下がコードと実行結果の図です。-23.35度ほどの回転が最適である、と出ました。質問者様の結果と比較して、ほんの少しだけ右回転しており、とてもバランスが良いように見えます。
15
+ 以下がコードと実行結果の図です。-23.36度ほどの回転が最適である、と出ました。質問者様の結果と比較して、ほんの少しだけ右回転しており、とてもバランスが良いように見えます。
16
16
 
17
17
 
18
18
 
@@ -60,7 +60,7 @@
60
60
 
61
61
  if len(mass) != len(radius):
62
62
 
63
- radius = radius[radius != 0] # 中心位置の補正
63
+ radius = radius[radius != 0] - 0.5 # 中心位置の補正
64
64
 
65
65
  return (mass * radius * radius).sum() # 慣性モーメント= Σ m*r^2
66
66
 

7

一部修正

2020/11/27 12:45

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
 
15
- 以下がコードと実行結果の図です。-23.35度ほどの回転が最適である、と出ました。とてもバランスが良いように見えます。
15
+ 以下がコードと実行結果の図です。-23.35度ほどの回転が最適である、と出ました。質問者様の結果比較し、ほんの少しだけ右回転しており、とてもバランスが良いように見えます。
16
16
 
17
17
 
18
18
 

6

アルゴリズムを修正

2020/11/27 12:41

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
 
4
4
 
5
- - アイデアとしては、まずは歯の形を平面に置いた重心に中心を揃え、その後、歯の形を立てて中心を軸に自重で回転できるようにしたときにバランスが取れる回転位置を求める、というものです。バランスが取れるかどうかは歯全体を重さ密度一定の剛体としてみた場合の回転モーメントが最小になる、という定義をしました。
5
+ - アイデアとしては、まずは歯の形を平面に置いた重心に中心を揃え、その後、歯の形を立てて中心を軸に自重で回転できるようにしたときにバランスが取れる回転位置を求める、というものです。
6
+
7
+ - バランスが取れるかどうかは歯全体を重さ密度一定の剛体としてみた場合に、垂直に立てた状態で、中心軸に対する慣性モーメントが最小になる、という定義をしました。
6
8
 
7
9
  - 最初の重心、平行移動、回転は、全て`scipy.ndimage`を使い、モーメント演算だけは見当たらないので自作、そしてモーメント最小を求めるのに`scipy.optimize`を使いました。
8
10
 
@@ -10,11 +12,11 @@
10
12
 
11
13
 
12
14
 
13
- 以下がコードと実行結果の図です。-34.14度ほどの回転が最適である、と出ました。個人的には、重さ的バランスはいると思いますが、形的バランスだともう少し左に回転していたほうが良さそな気が・・・
15
+ 以下がコードと実行結果の図です。-23.35度ほどの回転が最適である、と出ました。とてバランスが良いよに見えます
14
16
 
15
17
 
16
18
 
17
- moment関数(絶対値)最小となる回転を求めるわけすの、moment関数を入替えことで「バラス良いは何か」つきつめて、り質問者様の求めるものに合う形にすることも可能です例えば図上側の「重さ密度」少し増やすこと的不安定さを打ち消ような丁度よいバランスが出るかと思います
19
+ ※ 当初は、左右で逆向き回転モーメントを使ってました、慣性モーメントを使った方が安定した形になるとわかりました。回転モートメントだと横に伸ばした形も左右対称ば安定すのに対して慣性モーメトだなるべく小さくするようが有利なります。フィギュアスケート選手が腕たたんで高速回転ことは同じです。
18
20
 
19
21
 
20
22
 
@@ -46,37 +48,37 @@
46
48
 
47
49
 
48
50
 
49
- # 中心からの左右のバラスを求める関数
51
+ # 図形を立てた時の、中心軸に対する慣性モーメ
50
52
 
51
- # arr:縦軸ピクセル数 * mul:中心軸からの左右のピクセル距離(左が+/右が-) を合計している
53
+ # mass:縦軸ピクセル数 * radius:中心軸からの左右のピクセル距離を合計している
52
54
 
53
- def moment(img):
55
+ def inertia(img):
54
56
 
55
- arr = img.sum(axis=0) # 現在は図の上も下も重さ密度は同じとして単純に縦軸ピクセル数を求める
57
+ mass = img.sum(axis=0)
56
58
 
57
- mul = np.arange(-len(arr)//2, len(arr)//2+1)
59
+ radius = np.abs(np.arange(-len(mass)//2, len(mass)//2+1))
58
60
 
59
- if len(arr) != len(mul):
61
+ if len(mass) != len(radius):
60
62
 
61
- mul = mul[mul != 0]
63
+ radius = radius[radius != 0] # 中心位置の補正
62
64
 
63
- return (arr * mul).sum()
65
+ return (mass * radius * radius).sum() # 慣性モーメント= Σ m*r^2
64
66
 
65
67
 
66
68
 
67
- # 回転させてmomentの絶対値を測定する=最小化関数
69
+ # 回転させて慣性モーメントを測定する=最小化関数
68
70
 
69
- def rotated_moment(degree, img):
71
+ def rotated_inertia(degree, img):
70
72
 
71
- return abs(moment(ndimage.rotate(img, degree, reshape=False)))
73
+ return inertia(ndimage.rotate(img, degree, reshape=False))
72
74
 
73
75
 
74
76
 
75
- # 最小化関数の最小値を求めることで、-90〜90度の回転時の最小モーメントを得る
77
+ # 最小化関数の最小値を求めることで、-90〜90度の回転時の最小曲げモーメントを得る
76
78
 
77
79
  res = optimize.minimize_scalar(
78
80
 
79
- rotated_moment, bounds=[-90,90], args=(img), method='Bounded')
81
+ rotated_inertia, bounds=[-90,90], args=(img), method='Bounded')
80
82
 
81
83
 
82
84
 
@@ -104,4 +106,4 @@
104
106
 
105
107
 
106
108
 
107
- ![回転結果](e23ed991fdf5f0fe1b45741a8a845309.png)
109
+ ![回転結果](73ac151c5e0f33fa43908bb84c97bd09.png)

5

一部修正

2020/11/27 12:39

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -52,7 +52,7 @@
52
52
 
53
53
  def moment(img):
54
54
 
55
- arr = img.sum(axis=0) # 現在は図の上も下も重さ密度は同じとして単純合計
55
+ arr = img.sum(axis=0) # 現在は図の上も下も重さ密度は同じとして単純に縦軸ピクセル数を求める
56
56
 
57
57
  mul = np.arange(-len(arr)//2, len(arr)//2+1)
58
58
 

4

一部修正

2020/11/26 22:30

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -10,7 +10,11 @@
10
10
 
11
11
 
12
12
 
13
- 以下がコードと実行結果の図です。-34.14度ほどの回転が最適である、と出ました。なかなか「バランスよく」回転しているかと思います。なお、moment関数(の絶対値)が最小となる回転を求めるわけですので、moment関数を入れ替えることで、「バランス良いとは何か」をつきつめて、より質問者様の求めるものに合う形にすることも可能です。個人的には、重さ的バランスはとれていると思いますが、形的バランスだともう少し左に回転していたほうが良さそうな気が・・・。
13
+ 以下がコードと実行結果の図です。-34.14度ほどの回転が最適である、と出ました。個人的には、重さ的バランスはとれていると思いますが、形的バランスだともう少し左に回転していたほうが良さそうな気が・・・。
14
+
15
+
16
+
17
+ moment関数(の絶対値)が最小となる回転を求めるわけですので、moment関数を入れ替えることで、「バランス良いとは何か」をつきつめて、より質問者様の求めるものに合う形にすることも可能です。例えば図の上側の「重さ密度」を少し増やすことで、心理的不安定さを打ち消すような丁度よいバランスが出るかと思います。
14
18
 
15
19
 
16
20
 
@@ -44,11 +48,11 @@
44
48
 
45
49
  # 中心からの左右のバランスを求める関数
46
50
 
47
- # 中心軸からの左右のピクセル距離(左が+/右が-)*縦軸ピクセル数積算
51
+ # arr:縦軸ピクセル数 * mul:中心軸からの左右のピクセル距離(左が+/右が-) 合計している
48
52
 
49
53
  def moment(img):
50
54
 
51
- arr = img.sum(axis=0)
55
+ arr = img.sum(axis=0) # 現在は図の上も下も重さ密度は同じとして単純合計
52
56
 
53
57
  mul = np.arange(-len(arr)//2, len(arr)//2+1)
54
58
 

3

一部修正

2020/11/26 22:28

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
 
13
- 以下がコードと実行結果の図です。-34.14度ほどの回転が最適である、と出ました。なかなか「バランスよく」回転しているかと思います。なお、moment関数が最小となる回転を求めるわけですので、moment関数を入れ替えることで、「バランス良いとは何か」をつきつめて、より質問者様の求めるものに合う形にすることも可能です。
13
+ 以下がコードと実行結果の図です。-34.14度ほどの回転が最適である、と出ました。なかなか「バランスよく」回転しているかと思います。なお、moment関数(の絶対値)が最小となる回転を求めるわけですので、moment関数を入れ替えることで、「バランス良いとは何か」をつきつめて、より質問者様の求めるものに合う形にすることも可能です。個人的には、重さ的バランスはとれていると思いますが、形的バランスだともう少し左に回転していたほうが良さそうな気が・・・。
14
14
 
15
15
 
16
16
 

2

moment算出が違っていたため修正

2020/11/26 22:22

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
 
13
- 以下がコードと実行結果の図です。-21.24度ほどの回転が最適である、と出ました。なかなか「バランスよく」回転しているかと思います。
13
+ 以下がコードと実行結果の図です。-34.14度ほどの回転が最適である、と出ました。なかなか「バランスよく」回転しているかと思います。なお、moment関数が最小となる回転を求めるわけですので、moment関数を入れ替えることで、「バランス良いとは何か」をつきつめて、より質問者様の求めるものに合う形にすることも可能です。
14
14
 
15
15
 
16
16
 
@@ -48,13 +48,15 @@
48
48
 
49
49
  def moment(img):
50
50
 
51
- arr = img.sum(axis=0)
51
+ arr = img.sum(axis=0)
52
52
 
53
- arr1, arr2 = np.array_split(arr, 2)
53
+ mul = np.arange(-len(arr)//2, len(arr)//2+1)
54
54
 
55
- arr3 = arr1[::-1] - arr2
55
+ if len(arr) != len(mul):
56
56
 
57
+ mul = mul[mul != 0]
58
+
57
- return (arr3 * np.arange(len(arr3))).sum()
59
+ return (arr * mul).sum()
58
60
 
59
61
 
60
62
 
@@ -62,7 +64,7 @@
62
64
 
63
65
  def rotated_moment(degree, img):
64
66
 
65
- return abs(moment(ndimage.rotate(img, degree, reshape=False)))
67
+ return abs(moment(ndimage.rotate(img, degree, reshape=False)))
66
68
 
67
69
 
68
70
 
@@ -98,4 +100,4 @@
98
100
 
99
101
 
100
102
 
101
- ![回転結果](ba79ab90332ddc899c3582df9266c224.png)
103
+ ![回転結果](e23ed991fdf5f0fe1b45741a8a845309.png)

1

一部修正

2020/11/26 22:19

投稿

toast-uz
toast-uz

スコア3266

test CHANGED
@@ -30,7 +30,7 @@
30
30
 
31
31
  img = cv2.imread('tooth.png', 0)
32
32
 
33
- _, img = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)
33
+ _, img = cv2.threshold(img, 100, 1, cv2.THRESH_BINARY)
34
34
 
35
35
 
36
36