Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

スタック検知について #1

Open
Mi-cchy opened this issue Jul 18, 2022 · 5 comments
Open

スタック検知について #1

Mi-cchy opened this issue Jul 18, 2022 · 5 comments

Comments

@Mi-cchy
Copy link
Collaborator

Mi-cchy commented Jul 18, 2022

スタック検知のもろもろを書き示したい所存

@Mi-cchy
Copy link
Collaborator Author

Mi-cchy commented Jul 18, 2022

7/18 コード作成

注意点

  • モーターが中に入ってしまっているので注意
  • モーターを外に出す場合は,トルネード時にその他の出力がかかるとモータードライバが焼けるので,全関数のモーターへの出力を変数でおいて,モーターに出力する指令はループで1度のみにまとめるべし.
  • モーター関数内でif self.stuckTime > 0:の場合はトルネード
  • 平らな室内で試したため走行時よりもスタック時のほうが加速度が大きいとして判定できたが,屋外だとおそらく同じ方法が使えないため注意
def stuck_detection(self):
        print("acceralation:",self.bno055.ax**2+self.bno055.ay**2+self.bno055.az**2," const:",ct.const.STUCK_ACC_THRE**2*1000)
        if self.stuckTime > 0:
            print("Stuck!!")
            if time.time() - self.stuckTime > ct.const.STUCK_MOTOR_TIME_THRE:#閾値以上の時間モータを回転させたら
                self.rightMotor.stop()
                self.leftMotor.stop()
                self.stuckTime = 0
                self.countstuckLoop = 0
            else:
                #トルネード実施
                self.rightMotor.go(ct.const.STUCK_MOTOR_VREF)
                self.leftMotor.back(ct.const.STUCK_MOTOR_VREF)
            
        elif (self.bno055.ax**2+self.bno055.ay**2+self.bno055.az**2) >= ct.const.STUCK_ACC_THRE**2*1000:
            print("stuck count +1")
            print("acceralation:",self.bno055.ax**2+self.bno055.ay**2+self.bno055.az**2)
            
            self.countstuckLoop+= 1
            
            if self.countstuckLoop > ct.const.STUCK_COUNT_THRE: #加速度が閾値以下になるケースがある程度続いたらスタックと判定
                print("stuck")
                self.stuckTime = time.time()#スタック検知最初の時間計測
                self.rightMotor.stop()
                self.leftMotor.stop()
            else:
                self.rightMotor.go(70)
                self.leftMotor.go(70)
        else:
            print("not stuck")
            self.rightMotor.go(70)
            self.leftMotor.go(70)

@masato1004
Copy link
Collaborator

masato1004 commented Aug 27, 2022

特徴画像再構成について


エッジ画像を用いた際の結果

  • 塀など地面以外が写ったwin1の再構成
    edge_part_2
  • 何もない地面(グラウンド)が写ったwin5の再構成
    edge_part_5

エッジ画像を用いた再構成について

再構成誤差が現れることが見込まれる理由

  1. 地面(グラウンド)の場合には砂利などがエッジ検出されることによりエッジ部分が広範にわたる
  2. 地面以外の砂利ではない部分(本番では轍?)が含まれる場合、エッジ部分が少ない
  • 上記2点により、砂利で学習された固有ベクトルを用いた再構成をした場合にはエッジが多いほうが再構成誤差が少ないはず
  • 現在差が出ていない理由として、再構成画像が全体的に薄く(白っぽく)ぼやけてしまっていることが挙げられる

解決策として下限値の補正などを行う…?

エッジ画像のパラメータ調整方法

今後試験する際にエッジの強度を変えたい場合の簡便な説明

フォルダ

wolvez2022/Testcode/EtoE/baaa_feature.py

変更箇所

Feature_img()クラスedge()メソッド

該当コード

def edge(self):
    #self.output_img_list = []
    self.org_img = cv2.imread(self.imp_p, 1)
    self.img_gray = cv2.cvtColor(self.org_img, cv2.COLOR_BGR2GRAY)
    self.gray=cv2.Canny(self.img_gray,100,200)
    # self.gray=cv2.Canny(self.img_gray,200,550)  # アーリスではこちらの値を用いた方が適切かも(エッジ検出感度)
    self.save_name = self.sav_d + f"/edge_{self.frame_num}.jpg"
    cv2.imwrite(self.save_name,self.gray)
    self.output_img_list.append(self.save_name)

上記におけるself.gray=cv2.Canny(self.img_gray,100,200)2,3番目の引数の値を変更する

  • 2番目の引数がエッジのつながりやすさ(小さいほどエッジ線がつながりやすい
  • 3番目の引数がエッジ検出の感度(小さいほどエッジ検出感度が高い

回避試験におけるエッジ検出の参考画像

  • 元画像
    firstimg0
  • エッジ画像
    edge_2022-08-27_14-28-33

@Mi-cchy
Copy link
Collaborator Author

Mi-cchy commented Aug 27, 2022

@Masato104
Cannyの0 or 255じゃなくて微分画像の方が画像再構成に適してる説はない?
http://opencv.jp/sample/gradient_edge_corner.html

@masato1004
Copy link
Collaborator

masato1004 commented Aug 27, 2022

@Masato104

Cannyの0 or 255じゃなくて微分画像の方が画像再構成に適してる説はない?

http://opencv.jp/sample/gradient_edge_corner.html

@Mi-cchy @
確かにその方が濃淡も含めて再現できていいかもですね、、
明日試してみます!

@masato1004
Copy link
Collaborator

masato1004 commented Aug 28, 2022

cv2.Canny, cv2.Laplacianと、edge(), enphasis()メソッド

=== 結論からいうと勾配によるエッジ検出は既に特徴画像の一つとして存在していた ===


エッジ検出手法

大きく分けて二種類

  • Canny法
  • Laplacian法

Laplacian法について

  • 原理としては、隣接ピクセルとの差(勾配)を強調することによってエッジを検出する
    • 以下のようなカーネル(3×3行列)をループで回してかけることにより算出する

$$ {kernel =} \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{bmatrix} $$


実装済みのenphasis()メソッドについて

  • 実装コードは以下
def enphasis(self):
    #self.output_img_list = []
    self.org_img = cv2.imread(self.imp_p, 1)
    self.org_img = cv2.cvtColor(self.org_img, cv2.COLOR_BGR2RGB)
    kernel = np.array([[0, 1, 0],
                        [1, -4, 1],
                       [0, 1, 0]], np.float32)
    self.output_img = cv2.filter2D(self.org_img, -1, kernel)
    self.save_name = self.sav_d + f"/enphasis_{self.frame_num}.jpg"
    cv2.imwrite(self.save_name, self.output_img)
    self.output_img_list.append(self.save_name)
  • 当初はRGB画像をそのままenphasis()に挿入していたため、エッジ部分がやや強調される画像となるために「エッジ強調」としてenphasis()としていた
  • 学習時に最終的に次元を落として扱うことになるため、特徴画像を二値画像(グレースケール)に変更するようになったことから、現在行われているenphasis()の処理はcv2.Laplacian()とまったくもって同義である

cv2.Laplacian()と現行のenphasis()の出力比較

  • 元画像
    11093013404 (1)
  • cv2.Laplacian()
    laplacian
  • enphasis()
    enphasis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants