pythonで3リンクの逆運動学を解いて表示する
pythonで3リンク逆運動学を計算して2次元で表示します。
プログラム
・3リンク問題を逆運動学で算出してmatplotlibで表示しています
・Px,Pyが手先目標座標なので、使用するときは変更してください
・L1,L2,L3のリンクの長さは直接指定しているので、使用するときは変更してください
・tht3は直接指定しているので、使用するときは変更してください
・エラー系は実装していません
# -*- coding: utf-8 -*- import math import numpy import matplotlib.pyplot as plt fig = plt.figure() #アーム手先座標 Px = 15 Py = 20 #Linkの長さ L1 = 10 L2 = 10 L3 = 10 #逆運動学計算↓ #手先座標に対し # x =L1cos(tht1)+L2cos(tht1+th2)+L3cos(tht1+tht2+tht3) # y =L1sin(tht1)+L2sin(tht1+th2)+L3sin(tht1+tht2+tht3) # tht = tht1+tht2+tht3 #が成り立つ # L3の角度指定。(x軸とのなす角) tht = math.radians(90) #tht1の算出 A = Py - (L3*math.sin(tht)) B = Px - (L3*math.cos(tht)) C = (pow((Py - (L3*math.sin(tht))),2) + pow((Px - (L3*math.cos(tht))),2) + pow(L1,2) - pow(L2,2)) / (2*L1) tht1= math.atan2(A,B) - math.atan2(math.sqrt((pow(A,2)+pow(B,2)-pow(C,2))),C) #tht2の算出 D = (pow((Py - L3*math.sin(tht)),2) + pow((Px - L3*math.cos(tht)),2) - pow(L1,2) + pow(L2,2)) / (2*L2) tht2 = math.atan2(math.sqrt((pow(A,2)+pow(B,2)-pow(C,2))),C) - math.atan2(math.sqrt((pow(A,2)+pow(B,2)-pow(D,2)))*-1,D) #tht3の算出 tht3 = tht-tht2-tht1 #表示のために順運動学計算する #リンク1の座標算出 #数式↓ #x =L1cos(tht1) #y =L2sin(tht1) #プログラム↓ x1 = L1 * numpy.cos(tht1) y1 = L1 * numpy.sin(tht1) #リンク2の座標算出 #数式↓ #x2 =L1cos(tht1)+L2cos(tht1+th2) #y2 =L1sin(tht1)+L2sin(tht1+th2) #プログラム↓ x2 = x1 + (L2 * numpy.cos((tht1+tht2))) y2 = y1 + (L2 * numpy.sin((tht1+tht2))) #リンク3の座標算出 #数式↓ #x3 =L1cos(tht1)+L2cos(tht1+th2)+L3cos(tht1+tht2+tht3) #y3 =L1sin(tht1)+L2sin(tht1+th2)+L3sin(tht1+tht2+tht3) #プログラム↓ x3 = x2 + (L3 * numpy.cos((tht1+tht2+tht3))) y3 = y2 + (L3 * numpy.sin((tht1+tht2+tht3))) #算出結果を格納 #リンクは[x,y]=[0,0]から表示するため最初の要素に0を代入 x = [0, x1, x2, x3] y = [0, y1, y2, y3] #表示 #リンクの座標表示↓ plt.text(x1, y1, x1, verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x1, y1-0.8, y1,verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x2, y2, x2,verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x2, y2-0.8, y2, verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x3, y3, x3,verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x3, y3-0.8, y3, verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) #線分表示↓ plt.plot(x,y,"r-") #表示実行 plt.show()
pythonで2リンクの逆運動学を解いて表示する
pythonで2リンク逆運動学を計算して2次元で表示します。
プログラム
・2リンク問題を逆運動学で算出してmatplotlibで表示しています
・Px,Pyが手先目標座標なので、使用するときは変更してください
・L1,L2のリンクの長さは直接指定しているので、使用するときは変更してください
・計算結果はprint文とグラフ上に表示されます
・エラー系は実装していません
import math import numpy import matplotlib.pyplot as plt fig = plt.figure() #アーム手先座標 Px = 6 Py = 7.5 #Linkの長さ L1 = 10 L2 = 10 #逆運動学計算↓ L3 = math.sqrt((Px*Px) + (Py*Py)) fai2 = math.acos(((L1*L1) + (L2*L2) - ( L3 * L3)) / (2*L1*L2)) tht2 = math.pi - fai2 fai1 = math.acos(((L1*L1) + (L3 * L3) - (L2*L2)) / (2*L1*L3)) fai0 = math.atan(Py / Px) tht1 = math.atan2(Py , Px) - fai1 #角度計算↓ #deg1 = math.degrees(tht1) #deg2 = math.degrees(tht2) #表示のために順運動学計算する #リンク1の座標算出 #数式↓ #x =L1cos(tht1) #y =L2sin(tht1) #プログラム↓ x1 = L1 * numpy.cos(tht1) y1 = L1 * numpy.sin(tht1) #リンク1の座標算出 #数式↓ #x2 =L1cos(tht1)+L2cos(tht1+th2) #y2 =L1sin(tht1)+L2sin(tht1+th2) #プログラム↓ x2 = x1 + L2 * numpy.cos((tht1+tht2)) y2 = y1 + L2 * numpy.sin((tht1+tht2)) #計算結果表示↓ print(x1) print(x2) print(y1) print(y2) #算出結果を格納 #リンクは[x,y]=[0,0]から表示するため最初の要素に0を代入 x = [0, x1, x2] y = [0, y1, y2] #表示 #リンクの座標表示↓ plt.text(x1, y1, x1, verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x1, y1-0.8, y1,verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x2, y2, x2,verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x2, y2-0.8, y2, verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) #線分表示↓ plt.plot(x,y,"r-") #表示実行 plt.show()
pythonで2リンク順運動学を解いて表示する
pythonで2リンク順運動学を計算して2次元で表示します。
プログラム
・2リンク問題を順運動学で算出してmatplotlibで表示しています。
・L1,L2のリンクの長さは直接指定しているので使用するときは変更してください
・deg1,deg2はリンクの角度なので使用するときは変更してください
・計算結果はprint文とグラフ上に表示されます
・エラー系は実装していません
import math import numpy import matplotlib.pyplot as plt fig = plt.figure() #Linkの長さ L1 = 10 L2 = 10 #各リンクの角度指定 deg1 = 30 deg2 = 50 #リンク1の座標算出 #数式↓ #x =L1cos(tht1) #y =L2sin(tht1) #プログラム↓ x1 = L1 * numpy.cos(math.radians(deg1)) y1 = L1 * numpy.sin(math.radians(deg1)) #リンク1の座標算出 #数式↓ #x2 =L1cos(tht1)+L2cos(tht1+th2) #y2 =L1sin(tht1)+L2sin(tht1+th2) #プログラム↓ x2 = x1 + L2 * numpy.cos(math.radians(deg1+deg2)) y2 = y1 + L2 * numpy.sin(math.radians(deg1+deg2)) #計算結果表示↓ print(x1) print(x2) print(y1) print(y2) #算出結果を格納 #リンクは[x,y]=[0,0]から表示するため最初の要素に0を代入 x = [0, x1, x2] y = [0, y1, y2] #表示 #リンクの座標表示↓ plt.text(x1, y1, x1, verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x1, y1-0.8, y1,verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x2, y2, x2,verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) plt.text(x2, y2-0.8, y2, verticalalignment='bottom', horizontalalignment='right',color='green', fontsize=8) #線分表示↓ plt.plot(x,y,"r-") #表示実行 plt.show()
websocketでRaspberryPiからwindowsPCに画像を送る(Python)
Raspberypi3から webscketで画像をあげて、PC側で取得・表示までやります。
概要図↓
実行画面↓
開発環境
- win10 64bit
python3.5.2
openCV3.1.0
- Raspberrypi3
Raspbian Debian Stretch - Version:September 2017
python3.5.2
RaspberryPi側開発
構成
Raspberry Piのカメラモジュールで撮った映像をWebSocketでブラウザに送る!! - ami_GS's diary
ラズパイの方は、ほぼ上記参考HPのまま使っています。
今回は自分の環境でエラーが出たところを修正しました。
また、IP固定はあらかじめしておいてください。
ーーここ引用ーー
camera.py
RPi側でブラウザからのアクセスを受け付けるwebサーバ、及びカメラから映像を撮り、ブラウザへ送る。
index.html
WebSocketでブラウザに送られてきた画像を表示する。
ーーーーーーーー
インストール
pip3 install websocket pip3 install tornado
camera.py
import time import picamera import io import tornado import tornado.httpserver import tornado.websocket import tornado.ioloop import tornado.web import socket from threading import Thread WIDTH = 480 HEIGHT = 360 FPS = 30 class HttpHandler(tornado.web.RequestHandler): def initialize(self): pass def get(self): self.render("./index.html") #最初のHTTPアクセスを受け付け、WebSocket接続を確立させるスクリプトが入ったindex.htmlを返す class WSHandler(tornado.websocket.WebSocketHandler): def initialize(self, camera): self.camera = camera self.state = True def open(self): print(self.request.remote_ip, ": connection opened") t = Thread(target=self.loop) #撮影&送信スレッドの作成 t.setDaemon(True) t.start() def loop(self): stream = io.BytesIO() for foo in self.camera.capture_continuous(stream, "jpeg"): stream.seek(0) self.write_message(stream.read(), binary=True) stream.seek(0) stream.truncate() if not self.state: break def on_close(self): self.state = False #映像送信のループを終了させる self.close() #WebSocketセッションを閉じる print(self.request.remote_ip, ": connection closed") def piCamera(): camera = picamera.PiCamera() camera.resolution = (WIDTH, HEIGHT) camera.framerate = FPS camera.start_preview() time.sleep(2) #カメラ初期化 return camera def main(): camera = piCamera() print("complete initialization") app = tornado.web.Application([ (r"/", HttpHandler), #最初のアクセスを受け付けるHTTPハンドラ (r"/camera", WSHandler, dict(camera=camera)), #WebSocket接続を待ち受けるハンドラ ]) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(8080) tornado.ioloop.IOLoop.instance().start() if __name__ == "__main__": main()
index.html
<html> <head> <title>livecamera</title> <img id="liveImg" src="" width="480" height="360"> <script type="text/javascript"> var img = document.getElementById("liveImg"); var arrayBuffer; //WebSocketでサーバに接続 var ws = new WebSocket("ws://192.168.1.201:8080/camera"); ws.binaryType = 'arraybuffer'; //受診するデータがバイナリであるので設定 ws.onopen = function(){console.log("connection was established");}; //接続が確立した時に呼ばれる ws.onmessage = function(evt){ arrayBuffer = evt.data; //受信したデータを復号しbase64でエンコード img.src = "data:image/jpeg;base64," + encode(new Uint8Array(arrayBuffer)); }; window.onbeforeunload = function(){ //ウィンドウ(タブ)を閉じたらサーバにセッションの終了を知らせる ws.close(1000); }; function encode (input) { var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; while (i < input.length) { chr1 = input[i++]; chr2 = i < input.length ? input[i++] : Number.NaN; // Not sure if the index chr3 = i < input.length ? input[i++] : Number.NaN; // checks are needed here enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output += keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); } return output; } </script> </head> </html>
*WebSocketでサーバに接続する部分のIPアドレスを自分のラズパイのIPに書き換えてください
起動
上の2つのプログラムを同じフォルダに置いて実行します。
python camera.py
ブラウザでwindowsPCからラズパイIPにアクセスするとリアルタイム画像が表示されます。
Windows側開発
構成
client.py
websocketのクライアント文とOpenCVでの画像表示になります。
インストール
pip3 install websocket-client
client.py
#-*- coding:utf-8 -*- from websocket import create_connection import sys import base64 from io import BytesIO import cv2 import numpy as np ws = create_connection("ws://192.168.1.201:8080/camera") # decode while True: arr = np.asarray(bytearray(ws.recv()), dtype=np.uint8) img = cv2.imdecode(arr, -1) # 'load it as it is' cv2.imshow('image', img) cv2.waitKey(10) cv2.destroyAllWindows() ws.close()
*create_connectionのアドレスをラズパイのアドレスに書き換えてください
起動
こっちを起動する前にラズパイの方を起動させておいてください。
ラズパイ起動確認後、以下で実行
python client.py
ウインドウが表示され、ラズパイが取得している画像が表示されます
初めてwebsocketやりました。
おわり
[参考]
Raspberry Piのカメラモジュールで撮った映像をWebSocketでブラウザに送る!! - ami_GS's diary
【技術】pythonでwebsocketを試してみた - エンジニアリングとお金の話
PicameraによるRaspberry Pi 3カメラモジュールのカメラ設定 | TomoSoft
Pythonの画像読み込み: PIL, OpenCV, scikit-image - Qiita
YoLo/darknet初期学習データで判別できる種類一覧
github等でYOLO、YOLOv2、darknetでよく用意されている学習データをそのまま適用したときに
判別できる種類の一覧は、以下の全80種類になります。
人 自転車 車 バイク 飛行機 バス 列車 トラック ボート 信号機 消火栓 一時停止標識 パーキングメーター ベンチ 鳥 ネコ 犬 馬 羊 牛 ゾウ くま シマウマ キリン バックパック 傘 ハンドバッグ ネクタイ スーツケース フリスビー スキー スノーボード スポーツボール 凧 野球用バット 野球グローブ スケートボード サーフボード テニスラケット ボトル ワイングラス カップ フォーク ナイフ スプーン ボウル バナナ 林檎 サンドイッチ オレンジ ブロッコリ にんじん ホットドッグ ピザ ドーナツ ケーキ 椅子 ソファー 鉢植え ベッド ダイニングテーブル トイレ テレビモニター ノートPC マウス リモコン キーボード 携帯電話 電子レンジ オーブン トースター シンク 冷蔵庫 本 時計 花瓶 はさみ テディベア ヘアドライヤー 歯ブラシ
元の英語では
person bicycle car motorbike aeroplane bus train truck boat traffic light fire hydrant stop sign parking meter bench bird cat dog horse sheep cow elephant bear zebra giraffe backpack umbrella handbag tie suitcase frisbee skis snowboard sports ball kite baseball bat baseball glove skateboard surfboard tennis racket bottle wine glass cup fork knife spoon bowl banana apple sandwich orange broccoli carrot hot dog pizza donut cake chair sofa pottedplant bed diningtable toilet tvmonitor laptop mouse remote keyboard cell phone microwave oven toaster sink refrigerator book clock vase scissors teddy bear hair drier toothbrush
BBoX-Label-ToolをPython3で使用する
BBoX-Label-Toolはpyhotn2.7で作成されているので3系では起動しません。
そこで今回はpython3系で起動できるようにします。
[環境]
win7 64bit
python3.5
[ソースダウンロード]
以下から本体をダウンロードします
github.com
[python3系に編集]
DL後、解凍。
main.pyを開きます。
10 from Tkinter import * 11 import tkMessageBox
の部分を削除して
try: import tkinter import tkinter.messagebox except: import Tkinter as tkinter import tkMessageBox from tkinter import *
に書き換え
あとはpython3用にprint文にカッコを追記して
python main.py
私の環境ではpythonで3系が起動します。
これで起動できたと思います。
ちなみに画像フォルダはimages/002とか作ってそこにいれても画像が読み込めない?事態がおきますので、
その場合は001に入っている初期画像を消して、自分の学習させたい画像を001に移動させます。
そしてBBoxを起動させてフォルダパスのところに"1"と数字のみ入れてloadすると読み込めるはずです。
おわり
Darknetをwindows10にインストールして物体認識・物体判別をする
今までChainerやTensorflowなどで記述された物体認識・物体判別をしてきましたが
今回はYoloV2の制作者がC言語製作したdarknetをwindowsPCにインストールして試してみました。
[環境]
windows7 64bit
python3.5.2
VisualStudio2015
OpenCV3.2
[OpenCVインストール]
OpenCV3.2をダウンロードします
*製作者はOpenCV3.0でやっていますがファイル関係のエラーでできなかったため3.2でやっています
OpenCV 3.2 - OpenCV library
ここの一番下の”Windows self-extracting archive:”からexeをダウンロードします
exeを実行し、C:\直下に定してインストール
環境設定に
[DarkerNetビルド]
https://github.com/AlexeyAB/darknet
ここにアクセスしてzipをダウンロード
ダウンロードしたファイルを解凍し、
次に”darknet.sln”を実行(VisualStudio2015)
VisualStudioが起動したら、
プラットフォームを”x64”に構成を”Release”に変更
ビルド→darknetのリビルドを実行
以下エラー除去
・include失敗、見つからない
プロジェクト→プロパティ→VC++ディレクトリ→インクルードディレクトリ右の▼→編集→C:\opencv\build\includeを追加
・opencv_world320.libが見つからない、参照できない
プロジェクト→プロパティ→VC++ディレクトリ→ライブラリディレクトリ右の▼→編集→C:\opencv\build\x64\vc14\libを追加
*1.CUDA8.0ではなくて他のバージョンをお持ちの場合は、メモ帳を使用してbuild\darknet\darknet.vcxprojを開き、
”CUDA 8.0”で2か所探して自分のCUDAバージョンに変更して、リビルドを実行してください。
*2.GPUがない人はbuild\darknet\darknet_no_gpu.slnで実行してください
*3.OpenCV2.4.13の人はパスを変更してください
・(right click on project) -> properties -> C/C++ -> General -> Additional Include Directories:
C:\opencv_2.4.13\opencv\build\include
・(right click on project) -> properties -> Linker -> General -> Additional Library Directories:
C:\opencv_2.4.13\opencv\build\x64\vc14\lib
*4.OpenCV2.4.**の人はさらにパス変更が必要なようです
\src\detector.c等を開き、”#pragma comment(lib, "opencv_core2413.lib"”などを変更
無事ビルドが終了したら”darknet-master\darknet-master\build\darknet\x64”にexeができています。
[DarkerNet実行]
コマンドプロンプトを起動して以下に移動
”darknet_voc.cmd”
以下エラー除去
・opencv_world320.libが見つからない、参照できない
C:\opencv\build\x64\vc14\bin\opencv_world320.dllをdarknet_voc.cmdを生成したexeと同じフォルダにコピー
・opencv_ffmpeg320_64.dllが見つからない、参照できない
C:\opencv\build\x64\vc14\bin\opencv_ffmpeg320_64.dllをdarknet_voc.cmdを生成したexeと同じフォルダにコピー
以下実行結果
\darknet-master\darknet-master\build\darknet\x64>darknet.exe detector test data/voc.data yolo-voc.cfg yolo-voc.weights -i 0 -thresh 0.2 layer filters size input output 0 conv 32 3 x 3 / 1 416 x 416 x 3 -> 416 x 416 x 32 1 max 2 x 2 / 2 416 x 416 x 32 -> 208 x 208 x 32 2 conv 64 3 x 3 / 1 208 x 208 x 32 -> 208 x 208 x 64 3 max 2 x 2 / 2 208 x 208 x 64 -> 104 x 104 x 64 4 conv 128 3 x 3 / 1 104 x 104 x 64 -> 104 x 104 x 128 5 conv 64 1 x 1 / 1 104 x 104 x 128 -> 104 x 104 x 64 6 conv 128 3 x 3 / 1 104 x 104 x 64 -> 104 x 104 x 128 7 max 2 x 2 / 2 104 x 104 x 128 -> 52 x 52 x 128 8 conv 256 3 x 3 / 1 52 x 52 x 128 -> 52 x 52 x 256 9 conv 128 1 x 1 / 1 52 x 52 x 256 -> 52 x 52 x 128 10 conv 256 3 x 3 / 1 52 x 52 x 128 -> 52 x 52 x 256 11 max 2 x 2 / 2 52 x 52 x 256 -> 26 x 26 x 256 12 conv 512 3 x 3 / 1 26 x 26 x 256 -> 26 x 26 x 512 13 conv 256 1 x 1 / 1 26 x 26 x 512 -> 26 x 26 x 256 14 conv 512 3 x 3 / 1 26 x 26 x 256 -> 26 x 26 x 512 15 conv 256 1 x 1 / 1 26 x 26 x 512 -> 26 x 26 x 256 16 conv 512 3 x 3 / 1 26 x 26 x 256 -> 26 x 26 x 512 17 max 2 x 2 / 2 26 x 26 x 512 -> 13 x 13 x 512 18 conv 1024 3 x 3 / 1 13 x 13 x 512 -> 13 x 13 x1024 19 conv 512 1 x 1 / 1 13 x 13 x1024 -> 13 x 13 x 512 20 conv 1024 3 x 3 / 1 13 x 13 x 512 -> 13 x 13 x1024 21 conv 512 1 x 1 / 1 13 x 13 x1024 -> 13 x 13 x 512 22 conv 1024 3 x 3 / 1 13 x 13 x 512 -> 13 x 13 x1024 23 conv 1024 3 x 3 / 1 13 x 13 x1024 -> 13 x 13 x1024 24 conv 1024 3 x 3 / 1 13 x 13 x1024 -> 13 x 13 x1024 25 route 16 26 conv 64 1 x 1 / 1 26 x 26 x 512 -> 26 x 26 x 64 27 reorg / 2 26 x 26 x 64 -> 13 x 13 x 256 28 route 27 24 29 conv 1024 3 x 3 / 1 13 x 13 x1280 -> 13 x 13 x1024 30 conv 125 1 x 1 / 1 13 x 13 x1024 -> 13 x 13 x 125 31 detection Loading weights from yolo-voc.weights...Done! Enter Image Path:
使用する画像を尋ねられるからサンプルに付属している画像のパスを入れる
Enter Image Path: ***\darknet-master\darknet-master\data\dog.jpg ***\darknet-master\darknet-master\data\dog.jpg: Predicted in 0.038000 seconds. car: 75% bicycle: 77% dog: 91% ^Cバッチ ジョブを終了しますか (Y/N)? y
Ctrl+Cを打ってyで終了する
実行結果↓
[参考HP]
「darknet」C言語で機械学習!とりあえずインストールとmake、エラーの対処をしてみた - lisz-works
DarknetをWindowsにインストールする - TadaoYamaokaの日記
YOLOv2を使って自前のデータを学習させて認識させるまで。 - 可変ブログ
OpenCV3.2インストール方法(ビルドなし) - Qiita