文献紹介:気圧センサとゴムで作るロボット用格安触覚センサ
個人的にグッとくる文献を見つけたので、特に脈絡もなくご紹介。
タイトルの通り、
ロボットの指先に装備する触覚センサを気圧センサとゴムで格安で作った
というお話。
論文ではArduinoで実装されていますが、使っている気圧センサ(MPL115A2)自体はラズパイでも使えるようです(コチラ参照)。
参考文献・Webページ
最初の論文と思しきもの。
Inexpensive and Easily Customized Tactile Array Sensors using MEMS Barometers Chips
それを引用して発展(?)させたらしき論文。
ゴムをあらかじめつけてあるセンサが、こちらのページで販売されています。
www.labs.righthandrobotics.com
センサのみで$149、スターターキットは$299。
個人でも買えなくはない価格。
論文の内容(ざっくり)
ロボットの指先の感覚器官として触覚センサを使いたいけれど、
- カスタム開発だったり
- お高かったり
- 壊れやすかったり
といった問題があって使いにくい。。。
それらを解決するための方法を考案したぜ!
というもの。安いし、丈夫で簡単なのがウリ。
ただし、実際に使うとなるとコツがいりそうです。
ゴムの厚さや気温の影響があるとのことで、
使う前にちゃんと較正する必要がありそうですね。
感想
最先端のすごい技術を駆使した研究もかっこよくて良いですが、
個人的にはこういうDIY的なのも大好きです(^ ^)ノ
さすがにすごく高精度に測れる、というふうにはいかないようですが
時間とお金に余裕ができたら試してみたいですね。
scikit-imageのお勉強 番外編 〜台形補正にチャレンジ!~
先日から行なっているscikit-imageの機能を網羅していくシリーズ。
transformモジュールについては以前も取り上げました。
plant-raspberrypi3.hatenablog.com
今回は、このとき取り上げることができなかった台形補正にチャレンジしてみました。
Scikit-imageでの台形補正のやり方については、以下のページを参考にしました。
Computer vision in geoscience: recover seismic data from images – part 2mycarta.wordpress.com
環境
Jupyter lab上で操作。
準備
台形補正の効果がわかりやすいように、以下のサンプル画像を使用します。
%matplotlib inline import matplotlib.pyplot as plt from skimage import data,transform import numpy as np f = 'brick.png' loaded_img = data.load(f) plt.imshow(loaded_img) plt.show()
サンプル画像の呼び出し方は以前の記事をご参照ください。
plant-raspberrypi3.hatenablog.com
次に、台形の四隅の座標を調べます。調べる順番は「左上->左下->右下->右上」の反時計回り。
座標はImageJで手作業で調べました。
四隅の座標は以下のようなNumPyアレイとして、cornerCoords
に代入しておきます。
#[縦, 横]の順番 cornerCoords = np.array([[83,79],[446,31],[443,482],[76,450]]) plt.imshow(loaded_img) plt.scatter(cornerCoords[:,1],cornerCoords[:,0], s=60, color=['magenta', 'cyan', 'yellow', 'red']) plt.show()
手順その1
変換に使うための長方形の枠(?)を四隅の座標を元にして準備します。
w1 = np.sqrt(((cornerCoords[0, 1]-cornerCoords[3, 1])**2) +((cornerCoords[0, 0]-cornerCoords[3, 0])**2)) w2 = np.sqrt(((cornerCoords[1, 1]-cornerCoords[2, 1])**2) +((cornerCoords[1, 0]-cornerCoords[2, 0])**2)) h1 = np.sqrt(((cornerCoords[0, 1]-cornerCoords[1, 1])**2) +((cornerCoords[0, 0]-cornerCoords[1, 0])**2)) h2 = np.sqrt(((cornerCoords[3, 1]-cornerCoords[2, 1])**2) +((cornerCoords[3, 0]-cornerCoords[2, 0])**2)) w = max(int(w1), int(w2)) h = max(int(h1), int(h2)) dst = np.array([ [0, 0], [h-1, 0], [h-1, w-1], [0, w-1]], dtype = 'float32')
手順その2
その1で求めたdstの値と四隅の座標のX,Yをひっくり返しておきます。(必要らしい)
dst[:,[0,1]] = dst[:,[1,0]] cornerCoords[:,[0,1]] = cornerCoords[:,[1,0]]
手順その3
1. transform.ProjectiveTransformクラスのインスタンス化
tform = transform.ProjectiveTransform()
2. 手順その2で準備したdstと四隅の座標をestimate
関数に適用
tform.estimate(dst,cornerCoords)
3. アフィン変換でも使用したtransform.warp
関数で台数補正を画像に適用
warped =transform.warp(loaded_img, tform, output_shape=(h-1,w-1)) plt.imshow(warped) plt.show()
できました!
以上です。
scikit-imageのお勉強 第6回 filtersモジュール・前編 ~平滑化、エッジファインダ~
かなりご無沙汰していたscikit-imageの便利機能の備忘録シリーズの続き。
今回は第6回です。filters
モジュールの前編です。平滑化・エッジファインダについてメモしていきます。
平滑化
filters.gaussian
Gaussianフィルタ
エッジファインダ
filters.sobel
Sobelフィルタfilters.scharr
Scharrフィルタfilters.prewitt
Prewittフィルタfilters.roberts
Robertsフィルタfilters.laplace
Laplacianフィルタ
準備
前回までと同じようにサンプル画像のロケットを使用します。 カラー画像とグレースケール画像の両方を準備。
詳細を読む
%matplotlib inline
import matplotlib.pyplot as plt
from skimage import filters, color, data
def image_show(img,title,record=False):
plt.imshow(img)
plt.xticks([])
plt.yticks([])
plt.title(title)
# record=Trueの時タイトルと同名の画像ファイルを保存
if record:
plt.savefig(f"scimage_filters/{title}.png",dpi=150)
plt.show()
rocket = data.rocket()
image_show(rocket,"Raw",record=True)
gray_rocket = color.rgb2gray(rocket)
image_show(gray_rocket,"Gray",record=True)
平滑化
Gaussianフィルタは平滑化フィルタです。いわゆる「ぼかし」処理。
原理についてはこちらのページが詳しいです。 ガウシアンフィルタは、画像の平滑化に使われるフィルタの1つです。考え方は簡単で、「注目画素からの距離に応じて近傍の画素値に重みをかける」ということをガウス分布を利用して行います。それにより、自然な平滑化をおこなうことができます。詳細を読む
Gaussianフィルタを使ってみる
グレースケール画像の場合はデフォルトでOKですが、カラー画像に適用したい場合は
詳細を読む
multichannel=True
を設定します。sigma
の値が大きいほど、ぼかし具合が強くなります。image_show(rocket[300:400,250:400],"Raw_magnified",record=True)
sigmas = range(0,5,2)
for s in sigmas:
gaussian = filters.gaussian(rocket,sigma=s,multichannel=True)
image_show(gaussian[300:400,250:400],f"sigma={s}",record=True)
エッジファインダ
Sobel、Scharr、Prewitt、Roberts、Laplacianフィルタはエッジをみつけるためのフィルタ群です。
エッジについては以下のページの説明がわかりやすいです。 画像のエッジ(edge)とは、画素値が急峻に変化する点です。画素値の変化の大きさを「勾配(Gradient)」や「エッジの強さ」と言います。エッジは物体の輪郭を示す場合が多く、物体認識において重要な要素と言えます。 各フィルタの原理については以下のページを参照。 Sobelフィルタ、Prewittフィルタ、Laplacianフィルタ Sobelフィルタ、Scharrフィルタ、Laplacianフィルタ Sobelフィルタ、Prewittフィルタ、Robertsフィルタ、Laplacianフィルタ詳細を読む
qiita.com
画像の勾配 — OpenCV-Python Tutorials 1 documentation
エッジ検出
Sobel, Scharr, Prewitt, Robertsフィルタを使ってみる
グレースケール画像を使用します。
Sobel、Scharr、Prewittフィルタはほとんど同じように見えますが、Robertsフィルタだけ結果が若干違います。 Robertsフィルタは他の3つと原理が異なるので(コチラ参照)、当然の結果と言えそうです。詳細を読む
filter_names = ("filters.sobel","filters.scharr","filters.prewitt",
"filters.roberts")
filter_tuple = (filters.sobel,filters.scharr,filters.prewitt,
filters.roberts)
image_show(gray_rocket[300:400,250:400],"Raw_gray_magnified",record=True)
for f,name in zip(filter_tuple,filter_names):
filtered_image = f(gray_rocket)
image_show(filtered_image[300:400,250:400],f"{name}_magnified",record=True)
Laplacianフィルタを使ってみる
こちらもグレースケール画像を使用。
Laplacianフィルタは2次微分に相当します。 Laplacianフィルタでエッジ抽出する - [物理のかぎしっぽ] Laplacianフィルタの場合、ほとんどの画素値が0付近になり、特に変化の大きいところだけがプラス、マイナスの大きい値として現れます。 画素値のヒストグラムを描くと以下のようになります。
詳細を読む
image_show(gray_rocket[300:400,250:400],"Raw_gray_magnified",record=True)
laplace_img = filters.laplace(gray_rocket)
image_show(laplace_img[300:400,250:400],f"laplace_magnified",record=True)
plt.hist(laplace_img.flatten())
plt.savefig("scimage_filters/laplace_hist.png",dpi=150)
plt.show()
以上です。
MacOS High SierraでPython環境構築(再)
High Sierraの入った新しいMacBook ProでPython環境を構築し直したので、まとめました。
同じようなネタでだいぶ前にも記事にしましたが(コチラ)、拙いところが多かったので、こちらの方がベターです。
また、下記サイトも参考にさせていただきました。感謝!
手順
- homebrewをインストール
- pyenvをインストール
- Anacondaをインストール
- Jupyter labをインストール
1. homebrewをインストール
2. pyenvをインストール
次に、 その後、パスを通すために まず、nanoエディタで 下記の三行を追加します。 下記コマンドで設定を有効にします。 lsコマンドなどで、パスが壊れていないか確認しておくと安心。詳細を展開
brew
コマンドでpyenvをインストールします。$ brew install pyenv
~/.bash_profile
を設定します。~/.bash_profile
を開きます。$ nano ~/.bash_profile
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
Control
+o
で保存し、Control
+x
で終了します。$ source ~/.bash_profile
3. Anacondaをインストール
anacondaの最新バージョンを確認します。 Anacondaをインストールします。ここもちょっと時間がかかるかも(10分くらい)。 pyenvをリフレッシュ。 新しいAnacondaをローカルで動かすために、新しいディレクトリを作成して移動し、そちらでアクチベートします。 これで ちゃんと適用されているかは、Pythonを起動することで確かめることができます。 または、 こうなっていればOKです。詳細を展開
$ pyenv install -l | grep anaconda3
anaconda3-2.0.0
anaconda3-2.0.1
anaconda3-2.1.0
anaconda3-2.2.0
anaconda3-2.3.0
anaconda3-2.4.0
anaconda3-2.4.1
anaconda3-2.5.0
anaconda3-4.0.0
anaconda3-4.1.0
anaconda3-4.1.1
anaconda3-4.2.0
anaconda3-4.3.0
anaconda3-4.3.1
anaconda3-4.4.0
anaconda3-5.0.0
anaconda3-5.0.1
anaconda3-5.1.0
anaconda3-5.2.0
$ pyenv install anaconda3-5.2.0
$ pyenv rehash
$ mkdir python3_env
$ cd python3_env
$ pyenv local anaconda3-5.2.0
python3_env
ディレクトリにいるときにはanaconda3-5.2.9が使えるはずです。
$ python
Python 2.7.10 (default, Oct 6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
python3_env
ディレクトリで起動した場合$ python
Python 3.6.5 |Anaconda, Inc.| (default, Apr 26 2018, 08:42:37)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
python3_env
ディレクトリでconda
コマンドを試してみることでも確認できます。$ conda -V
conda 4.5.4
4. Jupyter labをインストール
jupyterlabをインストールする際に、msgpackが必要と言われるためインストールしておきます。 その後、pipをupgradeし、jupyterlabをインストールします。 Jupyter Labを開いてみます。
以上です!詳細を展開
$ brew install msgpack
$ pip install msgpack
$ pip install --upgrade pip
$ pip install jupyterlab
$ jupyter lab
おまけ
scikit-imageのお勉強 第5回 exposureモジュール ~露出補正~
scikit-imageの便利機能の備忘録シリーズ。
これまでの回はコチラ。
第1回 dataモジュールとioモジュール ~画像の入出力~
第4回 transformモジュール ~拡大縮小・回転・アフィン変換~
今回は第5回です。exposure
モジュールについてメモしていきます。
exposureモジュール
露出補正についての機能を含むモジュールです。
公式ページ:Module: exposure — skimage v0.14.0 docs
以下の関数とその効果をざっと紹介します。
exposure.equalize_hist
exposure.equalize_adapthist
exposure.rescale_intensity
exposure.adjust_gamma
exposure.adjust_sigmoid
exposure.adjust_log
まずは準備。
%matplotlib inline import matplotlib.pyplot as plt import numpy as np from skimage import exposure, data, color def image_show(img): try: h,w,c = img.shape plt.figure(figsize=[float(w/100),float(h/100)]) plt.title(f'w={w}, h={h}') plt.imshow(img) except ValueError: h,w = img.shape plt.figure(figsize=[float(w/100),float(h/100)]) plt.title(f'w={w}, h={h}') plt.imshow(img,cmap='gray') plt.xticks([]) plt.yticks([]) plt.show() rocket = data.rocket() image_show(rocket) rocket_g = color.rgb2gray(rocket) image_show(rocket_g)
・元画像
・元画像(グレー)
はじめの3つを実行
exposure.equalize_hist
とexposure.equalize_adapthist
はカラー画像で実行するとエラーがでました。
・code
image_show(rocket_g) hist_img = exposure.equalize_hist(rocket_g) image_show(hist_img) hist_img = exposure.equalize_adapthist(rocket_g,kernel_size=50) image_show(hist_img) hist_img = exposure.rescale_intensity(rocket_g, in_range=(0, 0.5)) image_show(hist_img) hist_img = exposure.rescale_intensity(rocket_g, out_range=(0, 0.5)) image_show(hist_img) image_show(rocket) hist_img = exposure.rescale_intensity(rocket, in_range=(0, 127)) image_show(hist_img) hist_img = exposure.rescale_intensity(rocket, out_range=(0, 127)) image_show(hist_img)
・元画像(グレー)
・exposure.equalize_hist
・exposure.equalize_adapthist
・exposure.rescale_intensity(in_range=(0, 0.5))
・exposure.rescale_intensity(out_range=(0, 0.5))
・元画像
・exposure.rescale_intensity(in_range=(0, 0.5))
・exposure.rescale_intensity(out_range=(0, 0.5))
exposure.adjust_gamma
gammaの値を色々変えて効果の違いを見てみます。
・code
image_show(rocket) for i in np.arange(1.2,1.7,0.2): print(f'gamma={i:.1f}') hist_img = exposure.adjust_gamma(rocket,gamma=i) image_show(hist_img)
・元画像
・gamma = 1.2
・gamma = 1.4
・gamma = 1.6
exposure.adjust_sigmoid
cutoffとgainをいじります。
・code
image_show(rocket) for i in np.arange(2,9,4): print(f'cutoff=0,gain={i:.1f}') hist_img = exposure.adjust_sigmoid(rocket,cutoff=0,gain=i) image_show(hist_img) print(f'cutoff=0.5,gain={i:.1f}') hist_img = exposure.adjust_sigmoid(rocket,cutoff=0.5,gain=i) image_show(hist_img) print(f'cutoff=1.5,gain={i:.1f}') hist_img = exposure.adjust_sigmoid(rocket,cutoff=1.0,gain=i) image_show(hist_img)
・元画像
・cutoff=0,gain=2.0
・cutoff=0.5,gain=2.0
・cutoff=1.5,gain=2.0
・cutoff=0,gain=6.0
・cutoff=0.5,gain=6.0
・cutoff=1.5,gain=6.0
exposure.adjust_log
gainを調整してみます。
image_show(rocket) for i in np.arange(0.2,2,0.4): print(f'gain={i:.1f}') hist_img = exposure.adjust_log(rocket,gain=i) image_show(hist_img)
・元画像
・gain=0.2
・gain=0.6
・gain=1.0
・gain=1.4
・gain=1.8
各々の関数の雰囲気を探ってみました。
解説なしでスミマセン。
Twythonでつぶやいてみた [Twitter Bot]
scikit-imageのメモシリーズ途中ですが、息抜きで、PythonでTwitterのbotを作ってみました、というお話し。
QiitaのRSSがめちゃ簡単に取得できることを知り、「ラズパイ」タグのRSSをつぶやかせることにしました。
RSSの取得
feedparserを使います。
インストールは普通にpipでOK。
ついでにtwythonもインストール。
$ pip install feedparser twython
早速、やってみます。
このあたりのウェブページを参考にさせていただきます。
import feedparser import time RSS_URL = "https://qiita.com/tags/%E3%83%A9%E3%82%BA%E3%83%91%E3%82%A4/feed" #%E3%83%A9%E3%82%BA%E3%83%91%E3%82%A4=ラズパイ qiita_raspi_rss = feedparser.parse(RSS_URL) for entry in qiita_raspi_rss.entries[:10]: title = entry.title link = entry.link print(f'{title}: {link}\n') #出力結果 ラズパイ to VNCviewer: https://qiita.com/third_it_1027/items/ce1cf6fff981c25316cc Aoide DAC II 備忘録: https://qiita.com/zkusaka/items/90141267b39d2e5eeb18 初心者がRaspberry Pi 3 Model B+を買ってSSH、RDP接続するまでを雑にメモ: https://qiita.com/flecott/items/20e4f1ef0ff1bdbc867a 【Raspberry Pi 3B/3B+】ラズパイをオーバークロック(OC)しよう: https://qiita.com/BearcubThaw/items/4aa0a7d373b597dfea21 【Raspberry Pi 3B/3B+】よく使うLinuxコマンド: https://qiita.com/BearcubThaw/items/b6041e57fee4e530b408 【Raspberry Pi 3B/3B+】ラズパイケースを改造して小型ファンを設置しよう: https://qiita.com/BearcubThaw/items/81b70017e5f7d5662ec5 周辺機器不要でラズパイ のセットアップ: https://qiita.com/yukoh/items/94788a5da05f626cf6f5 ラズパイでKubernetesを動かして見たら、驚いた!: https://qiita.com/MahoTakara/items/2b39e06f077927bafa2c Raspberry Pi3を5インチのディスプレイで使いたい: https://qiita.com/uichi/items/655cb431cba260315250 Raspberry Pi3を使ってネットワークカメラを構築してみる: https://qiita.com/uichi/items/6094eb9fa633192e71e0
できました!
TwythonでTwitter Bot
完全にこちらを参考にさせていただきました。
- ツイッターのアカウント作成
- ツイッターディベロッパーに登録(電話番号認証)
- Applicationを作成
- customer key, customer secret, access token, access token secretの4つを取得
- twythonでつぶやく
理由や使い方などを英語で延々と書かされるのがちょっと大変でした。
では、登録できたところで早速つぶやいてみます。
from twython import Twython twitter = Twython( consumer_key, consumer_secret, access_token, access_token_secret ) message = "こんにちは。これはテストです。" twitter.update_status(status=message)
RSSをつぶやかせるには、messageのところに、rssで取得した情報を代入します。
for entry in qiita_raspi_rss.entries: title = entry.title link = entry.link message = f'Qiita ラズパイRSS 「{title}」: {link}' twitter.update_status(status=message) time.sleep(30)
ツイッターに負荷をかけないように、30秒間スリープいれてみました。
新しく作ったツイッターページはこちら。
なかなか良い感じ。
今後は実際にRaspberry pi3など駆使して、定期的につぶやくようにしてみたいです。
scikit-imageのお勉強 第4回 transformモジュール ~拡大縮小・回転・アフィン変換~
scikit-imageの便利機能の備忘録シリーズ。
これまでの回はコチラ。
第1回 dataモジュールとioモジュール ~画像の入出力~
今回は第4回です。transform
モジュールについてメモしていきます。
transformモジュール
回転などの変換に関するモジュールです。
公式ページ:Module: transform — skimage v0.14.0 docs
よく使いそうな機能は以下の4種類。
リサイズ・リスケール
transform.resize
transform.rescale
回転
transform.rotate
スワール(渦巻き化)
transform.swirl
アフィン変換
transform.AffineTransform
+transform.warp
他に画像ピラミッド、Hough変換(特徴抽出の一種)やradon変換(断層画像の変換)なども利用できます。 この中で、今回は画像ピラミッドのみ取り上げます。
画像ピラミッド
transform.pyramid_reduce
transform.pyramid_expand
transform.pyramid_gaussian
いつも通り、テスト画像をdata
モジュールで読み込んでおきます。
今回、拡大縮小が見やすいようにimage_show
関数をちょっと改変しました。
・code
%matplotlib inline import matplotlib.pyplot as plt from skimage import transform, data def image_show(img): h,w,c = img.shape plt.figure(figsize=[float(w/100),float(h/100)]) plt.title(f'w={w}, h={h}') plt.imshow(img) plt.xticks([]) plt.yticks([]) plt.show() rocket = data.rocket() image_show(rocket)
リサイズ・リスケール
transform.resize
で指定の画像サイズにリサイズできます。
第1引数:画像データ
第2引数:リサイズ後の画像サイズ(タプル)
第3以降の引数:mode, anti_aliasingなど
・code
# 元画像表示 image_show(rocket) # 画像の縮小 # mode='reflect'、anti_aliasing=True にする resize_img = transform.resize(rocket,(200,500),mode='reflect',anti_aliasing=True) image_show(resize_img) # 画像の拡大 # modeはどれでも適用可 resize_img = transform.resize(rocket,(800,800),mode='constant',anti_aliasing=True) image_show(resize_img)
・元画像
・縮小画像
・拡大画像
transform.rescale
は特定の倍率に画像を拡大・縮小するための関数です。
第1引数:画像データ
第2引数:倍率(拡大なら>1、縮小なら<1)
第3以降の引数:mode, anti_aliasingなど
・code
# 元画像表示 image_show(rocket) # 画像の縮小 # mode='reflect'、anti_aliasing=Trueにする # multichannelは明示(True/False) rescale_img = transform.rescale(rocket,0.2,mode='reflect',anti_aliasing=True,multichannel=True) image_show(rescale_img) # 画像の拡大 # modeはどれでも適用可 # multichannelは明示(True/False) rescale_img = transform.rescale(rocket,1.5,mode='constant',anti_aliasing=True,multichannel=True) image_show(rescale_img)
・元画像
・縮小画像
・拡大画像
回転
画像の回転はtransform.rotate
で行います。回転の際にリサイズするかどうかを選べます。
第1引数:画像データ
第2引数:角度(時計回り方向)
第3以降の引数:resizeなど
・code
# 元画像の表示 image_show(rocket) # リサイズなしの回転 rotate_img = transform.rotate(rocket,90,resize=False) image_show(rotate_img) # リサイズありの回転 rotate_img = transform.rotate(rocket,90,resize=True) image_show(rotate_img)
・元画像
・リサイズなしの回転
・リサイズありの回転
スワール(渦巻き化)
画像に渦巻き加工を入れる関数としてtransform.swirl
というものがあります。
第1引数:画像データ
第2以降の引数:mode, strengthなど
strengthを変えることで渦の強さを調節できます。
・code
for i in range(1,11,3): print(f'strength={i}') swirl_img = transform.swirl(rocket,mode='reflect',strength=i) image_show(swirl_img)
・元画像
・strength=1
・strength=4
・strength=7
・strength=10
アフィン変換
アフィン変換をマスターすると拡大縮小・平行移動・反転・回転・剪断変形などなんでもできて便利です。
「アフィン変換とは平行移動と線形変換を組み合わせた変換」のこと。(中略) 具体的には、線形変換(拡大縮小、剪断、回転)、平行移動があり、これらの組み合わせで表現される。
scikit-imageでのアフィン変換のやり方は、ここまで説明してきた変換とは手順が違うので注意が必要です。
1. transform.AffineTransform
クラスのインスタンスを作成
2. transform.warp
で画像に上記インスタンスの効果を適用
それぞれのクラス・関数の引数は以下の通りです。
transform.AffineTransform
の引数
scale:拡大縮小(縦・横のタプルで与える、マイナスで反転)
translation:平行移動(縦・横のタプルで与える)
rotation:回転
shear:剪断変形
反転・回転・剪断変形は画像が画面からはみ出ることが多いので、適宜translation
を組み合わせて使います。
transform.warp
の引数
第1引数:画像データ
第2引数: transform.AffineTransform
クラス等のインスタンス
・code
# 元画像の表示 image_show(rocket) # 拡大縮小のみ at = transform.AffineTransform(scale=(1.2,1.2)) warp_img = transform.warp(rocket,at) image_show(warp_img) # 平行移動のみ at = transform.AffineTransform(translation=(-30,-50)) warp_img = transform.warp(rocket,at) image_show(warp_img) #反転と平行移動 at = transform.AffineTransform(scale=(-1,1),translation=(640, 0)) warp_img = transform.warp(rocket,at) image_show(warp_img) # 回転と平行移動 at = transform.AffineTransform(rotation=0.5,translation=(300,-100)) warp_img = transform.warp(rocket,at) image_show(warp_img) # 剪断変形と拡大縮小、平行移動 at = transform.AffineTransform(shear=1,scale=(1.5,1.5),translation=(30,30)) warp_img = transform.warp(rocket,at) image_show(warp_img)
・元画像
・縮小
・平行移動
・反転と平行移動
・回転と平行移動
・剪断変形と拡大縮小、平行移動
おまけ:画像ピラミッド
画像ピラミッドに関してはOpenCVのTutorialページがわかりやすいです。
画像ピラミッド — OpenCV-Python Tutorials 1 documentation
例えば画像中で何かを探すとき(例えば顔)、画像中にどのような大きさで現れるか分かりません。そのような状況では様々な解像度の画像を用意し、全画像に対して物体検出を試みます。これらの異なる解像度を持つ画像の集合を画像ピラミッド(最大解像度の画像を下に、最小解像度の画像を上に積むとピラミッドのようになるからです)と呼びます。
画像ピラミッドの関数には、transform.pyramid_reduce
、transform.pyramid_expand
やジェネレーターとして機能するtransform.pyramid_gaussian
などがあります。
・code
#pyramidシリーズ image_show(rocket) pyramid_img = transform.pyramid_reduce(rocket,downscale=5,multichannel=True) image_show(pyramid_img) pyramid_img = transform.pyramid_expand(rocket,upscale=1.5,multichannel=True) image_show(pyramid_img)
・元画像
・transform.pyramid_reduce
・transform.pyramid_expand
これらは普通の拡大縮小とあまり変わらないですね。
次のようにジェネレーターを使うと画像ピラミッドっぽさが出ます。
・code
pyramid_gen = transform.pyramid_gaussian(rocket,downscale=2,multichannel=True) for i in range(5): pyramid_img = next(pyramid_gen) image_show(pyramid_img)
・1回目
・2回目
・3回目
・4回目
・5回目
今回はここまで。
2018/9/10訂正
アフィン変換の説明のところで引数に誤植があったため修正しました。