回答編集履歴
10
コード内のコメントを修正
test
CHANGED
@@ -50,7 +50,9 @@
|
|
50
50
|
|
51
51
|
# 図形を立てた時の、中心軸に対する慣性モーメント
|
52
52
|
|
53
|
-
# mass:縦軸ピクセル数
|
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()
|
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
一部修正
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
一部修正
test
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
|
14
14
|
|
15
|
-
以下がコードと実行結果の図です。-23.3
|
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
一部修正
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
アルゴリズムを修正
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
|
-
以下がコードと実行結果の図です。-3
|
15
|
+
以下がコードと実行結果の図です。-23.35度ほどの回転が最適である、と出ました。とてもバランスが良いように見えます。
|
14
16
|
|
15
17
|
|
16
18
|
|
17
|
-
|
19
|
+
※ 当初は、左右で逆向きの回転モーメントを使ってましたが、慣性モーメントを使った方が安定した形になるとわかりました。回転モートメントだと横に伸ばした形でも左右対称であれば安定するのに対して、慣性モーメントだと横をなるべく小さくするような形が有利になります。フィギュアスケートの選手が腕をたたんで高速回転することと、原理は同じです。
|
18
20
|
|
19
21
|
|
20
22
|
|
@@ -46,37 +48,37 @@
|
|
46
48
|
|
47
49
|
|
48
50
|
|
49
|
-
# 中心
|
51
|
+
# 図形を立てた時の、中心軸に対する慣性モーメント
|
50
52
|
|
51
|
-
# a
|
53
|
+
# mass:縦軸ピクセル数 * radius:中心軸からの左右のピクセル距離を合計している
|
52
54
|
|
53
|
-
def
|
55
|
+
def inertia(img):
|
54
56
|
|
55
|
-
a
|
57
|
+
mass = img.sum(axis=0)
|
56
58
|
|
57
|
-
|
59
|
+
radius = np.abs(np.arange(-len(mass)//2, len(mass)//2+1))
|
58
60
|
|
59
|
-
if len(a
|
61
|
+
if len(mass) != len(radius):
|
60
62
|
|
61
|
-
|
63
|
+
radius = radius[radius != 0] # 中心位置の補正
|
62
64
|
|
63
|
-
return (ar
|
65
|
+
return (mass * radius * radius).sum() # 慣性モーメント= Σ m*r^2
|
64
66
|
|
65
67
|
|
66
68
|
|
67
|
-
# 回転させて
|
69
|
+
# 回転させて慣性モーメントを測定する=最小化関数
|
68
70
|
|
69
|
-
def rotated_
|
71
|
+
def rotated_inertia(degree, img):
|
70
72
|
|
71
|
-
return
|
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
|
-
|
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
|
-
![回転結果](
|
109
|
+
![回転結果](73ac151c5e0f33fa43908bb84c97bd09.png)
|
5
一部修正
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
一部修正
test
CHANGED
@@ -10,7 +10,11 @@
|
|
10
10
|
|
11
11
|
|
12
12
|
|
13
|
-
以下がコードと実行結果の図です。-34.14度ほどの回転が最適である、と出ました。
|
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
一部修正
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算出が違っていたため修正
test
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
|
11
11
|
|
12
12
|
|
13
|
-
以下がコードと実行結果の図です。-
|
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
|
-
|
51
|
+
arr = img.sum(axis=0)
|
52
52
|
|
53
|
-
|
53
|
+
mul = np.arange(-len(arr)//2, len(arr)//2+1)
|
54
54
|
|
55
|
-
|
55
|
+
if len(arr) != len(mul):
|
56
56
|
|
57
|
+
mul = mul[mul != 0]
|
58
|
+
|
57
|
-
|
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
|
-
|
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
|
-
![回転結果](
|
103
|
+
![回転結果](e23ed991fdf5f0fe1b45741a8a845309.png)
|
1
一部修正
test
CHANGED
@@ -30,7 +30,7 @@
|
|
30
30
|
|
31
31
|
img = cv2.imread('tooth.png', 0)
|
32
32
|
|
33
|
-
_, img = cv2.threshold(img, 100,
|
33
|
+
_, img = cv2.threshold(img, 100, 1, cv2.THRESH_BINARY)
|
34
34
|
|
35
35
|
|
36
36
|
|