質問するログイン新規登録

回答編集履歴

1

誤植の修正

2021/01/17 03:27

投稿

退会済みユーザー
answer CHANGED
@@ -1,11 +1,11 @@
1
1
  ![イメージ説明](5ba10c0a8e207cb2d4139935ca5fabc4.png)
2
2
 
3
3
  処理の要点だけ書きます。
4
- 0. 何とかして曲線部分だけ切り出しましょう。背景にいろいろな色があって分離困難な場合、HSV空間にもっていって、オレンジ色だけ切り出すと良いかもしれません。たくさん曲線があるようであれば、OpenCVのcontour毎に分離させる手法を取ってください。
5
- 1. 式で近似させるためになんとかして線ののっかる座標を拾いましょう。座標の割り出しにはskeletonが便利です。「オレは近似式なんぞ使わず、画素の並び具合から傾きを計算する!」というマッチョであれば以下無視してください。
6
- 2. 何らかの形でx,yから傾きを得るために、近似式を出す方法としてsplineを使いました。**式が定義できるのであればscipyで最小二乗法を**したらいいと思います(私にはムリでした)。**遺伝的アルゴリズムをコメントに書きましたが、計算が遅いのでお勧めできません**。splineが現実的かと思います。
7
- 3. 上記2において、**splineの場合あるxに対して1つのyしか存在が許されません**。あるx上に複数の解yが存在するのであれば、何らかの方法で曲線を分離してxに対して1つのyしか存在しないようにしてください。私の場合は重複チェックx,yの値を固有の値にしましました。これだと初めに出てきた対を機械的に生かすだけですので数pxくらいズレてしまいます。そんなザコい処理は許されないというのであれば、skeletonのskeletonを探したり、gaussianでぼかして濃いところだけ探す、cv2.erodeなりでもっとあたりを探ったら良いと思います。splineで曲線が相当最適化されると思いますので、上記の中心を割り出す処理をした上で、x,yの対の90%くらいを切り捨ててしまってから式を割り出すsplineをしてもいいかもしれません。
8
- 4. 傾きから直交する線を描くのはもっとスマートな方法があると思います。例えば[tiitoiさんの回答](https://teratail.com/questions/234974)みたいなもののほうがカッコいいですよね?
4
+ 1. 何とかして曲線部分だけ切り出しましょう。背景にいろいろな色があって分離困難な場合、HSV空間にもっていって、オレンジ色だけ切り出すと良いかもしれません。たくさん曲線があるようであれば、OpenCVのcontour毎に分離させる手法を取ってください。
5
+ 2. 式で近似させるためになんとかして線ののっかる座標を拾いましょう。座標の割り出しにはskeletonが便利です。「オレは近似式なんぞ使わず、画素の並び具合から傾きを計算する!」というマッチョであれば以下無視してください。
6
+ 3. 何らかの形でx,yから傾きを得るために、近似式を出す方法としてsplineを使いました。**式が定義できるのであればscipyで最小二乗法を**したらいいと思います(私にはムリでした)。**遺伝的アルゴリズムをコメントに書きましたが、計算が遅いのでお勧めできません**。splineが現実的かと思います。
7
+ 4. 上記3において、**splineの場合あるxに対して1つのyしか存在が許されません**。あるx上に複数の解yが存在するのであれば、何らかの方法で曲線を分離してxに対して1つのyしか存在しないようにしてください。私の場合は重複チェックをかませてx,yの値を固有の値にしましました。これだと初めに出てきた対を機械的に生かすだけですので少なくとも数pxくらいズレてしまいます。そんなザコい処理は許されないというのであれば、skeletonのskeletonを探したり、gaussianでぼかして濃いところだけ探す、cv2.erodeなりでもっとあたりを探ったら良いと思います。splineで曲線が相当最適化されると思いますので、上記の中心を割り出す処理をした上で、x,yの対の90%くらいを切り捨ててしまってから式を割り出すsplineをしてもいいかもしれません。
8
+ 5. 傾きから直交する線を描くのはもっとスマートな方法があると思います。例えば[tiitoiさんの回答](https://teratail.com/questions/234974)みたいなもののほうがカッコいいですよね?
9
9
 
10
10
  ```Python3
11
11
  import numpy as np
@@ -70,14 +70,12 @@
70
70
  # Calc slope on the point
71
71
  target_slope = calc_slope(spline_func,pos_x,target_x,shift_value_horizontal)
72
72
 
73
-
74
73
  # Left
75
74
  img = cv2.line(img,center,(int(target_x - shift_value_horizontal), int(target_y - (target_slope * shift_value_horizontal))),(128,255,192),3)
76
75
 
77
76
  # Right
78
77
  img = cv2.line(img,center,(int(target_x + shift_value_horizontal), int(target_y + (target_slope * shift_value_horizontal))),(128,192,255),3)
79
78
 
80
-
81
79
  #######################################
82
80
  # Calc orthogonal params
83
81
  orth_slope,orth_intercept = calc_orthogonal(target_slope,(target_x,target_y))
@@ -88,7 +86,6 @@
88
86
  # Bottom
89
87
  img = cv2.line(img,center,(int(target_x - shift_value_vertical), int(target_y - (orth_slope * shift_value_vertical) + orth_intercept)),(255,192,192),3)
90
88
 
91
-
92
89
  #######################################
93
90
  # Center
94
91
  img = cv2.circle(img,center, 3, (32,32,32), -1)
@@ -108,7 +105,6 @@
108
105
  # binary image to positional data
109
106
  pos_x, pos_y = images_to_pos(img_th)
110
107
 
111
-
112
108
  # Calc spline
113
109
  spline_func = interpolate.interp1d(pos_x, pos_y,kind="cubic")
114
110