【Python3】OpenCV チュートリアルがpython2なので3にする・・Image Pyramid を例に【zipとか色々】

スポンサーリンク
広告

Pythonって2と3で違ってて少々ややこしい

Donkeyが、PythonとOpenCV使っているので。。(という訳でもないのですが・・)

Python はpyenvとかAnacondaとかでバージョン違いの開発環境を他に影響されなく作れるので便利なんですが、3系で作っている時にマージしようとすると、動かなくて困ります(笑)

実は。。前にも同じようなことが・・あったので、

【忘備録】WiFi IP camera ストリーミング、コントロール等Vstarcam C7837WIP(W)【OpenCV】

で、Python2.7系でやってたんですが、Donkeyは、Python3系なので(笑)

【ラジコン自動運転】Donkey 2のキャリブレーションとか。。やってみる【Python】

【ラジコン自動運転】Donkey 2のソフトウェアのインストールとか。。やってみる【Python】

【ラジコン自動運転】Donkeyの配線を確認するために・・回路図を探してみた【Raspberry Pi3】

【AWS】Robocar Rally re:Inventの自動運転ハッカソン Donkeyのブログをまとめておく【自動運転】 

Pythonやってて、画像でラジコン動かそうとすると、つまづくところって、意外としょーもないことだったりします(笑)。

ツールで、2to3というのがあるんですが、なぜか、いまいち使えなかったりします。

2から3への移植などの細かいことは、こちらのページに詳しくのっています。

で・・・言語のバージョン違いだったりで、コピペで動かなかったりするので、その例を、ちょっと紹介します。

いきなりですが、画像合成を例に

PythonとOpenCVを少し、勉強するのに、OpenCV-Python Tutorialsっていうのがあります。これいいんですが。。OpenCVのバージョンは進んで、いろんなチュートリアルあるくせに、Pythonが2のままのコードが沢山残っています(笑) 理解させるためにわざと間違っているのかも知れませんけど。。 画像処理・イメージプロセッシングのところで。。

Opencv-Python-tutrials.ioのチュートリアル

Opencv.orgのチュートリアル

実は、なんぼあるんかぃ!ってほど、このチュートリアルあるんですけど。。

日本語のOpenCV Pythonのチュートリアル

いつも見ています。

これの一番最後に載ってるコードを動かした時に、Python2のコードだったので、Python3にした時への変更点を書いておきます(自分の忘備録として)

ちなみに、何をするかっていうのは。。 アップルとオレンジの画像を、とってきて、ブレンドして表示するというものです。理論などは、変わっていないので、上記のページを読んでください。簡単に言うと、ぼかして、混ぜるというものです。パノラマ写真の合成などに使われる手法ですね。

PythonとOpenCVの環境

元のチュートリアルは、OpenCVはPython 2.7.x で書かれています。

まず、もともとのコードで、間違っているところがありまして、それはStackOverflowで見つけます。<そこから?

Stack Overflowで、間違いを直します。

具体的には、4行目

G = A.copy()
gpA = [G]
for i in xrange(6):
    G = cv2.pyrDown(G)
    gpA.append(G)

GをGでpyramid ダウンしていたのを治したりします。他にもありますので、Stack overflowを確認してください。

G = A.copy()
gpA = [G]
for i in xrange(6):
    G = cv2.pyrDown(gpA[i])
    gpA.append(G)

で、肝心なPython 2→Python 3ですが。。 既に訂正したもので、説明しちゃいますが・・

23行目 for i in xrange(6): となっていたのですが、3になって、xrangeなくなっています。それを range(6)にしてます。他にもあるので、訂正。

42行目 for la,lb in zip(lpA, lpB): となっていたのですが、zipの動きが変わっています。それを、for la,lb in list(zip(lpA, lpB)): っていう風に変えています。

その他

画像の大きさによっては、colsが奇数になってたりします。なので

ls = np.hstack((la[:,0:int(cols/2)],lb[:,int(cols/2):]))

2で割ったりすると、整数じゃないと怒られるので、整数にしたり。。

そうして一応動くようになったのが、これです。

import cv2
import numpy as np
from matplotlib import pyplot as plt

A = cv2.imread('apple.jpg')
B = cv2.imread('orange.jpg')
print("A")
plt.imshow(A),plt.show()
print("B")
plt.imshow(B),plt.show()

G = A.copy()
print("G")
plt.imshow(G),plt.show()

gpA = [G]
for i in range(6):
 G = cv2.pyrDown(gpA[i])
 gpA.append(G)

G = B.copy()
gpB = [G]
for i in range(6):
 G = cv2.pyrDown(gpB[i])
 gpB.append(G)

lpA = [gpA[5]]
for i in range(5, 0, -1):
 size = (gpA[i-1].shape[1], gpA[i-1].shape[0])
 GE = cv2.pyrUp(gpA[i], dstsize = size)
 L = cv2.subtract(gpA[i-1], GE)
 lpA.append(L)

lpB = [gpB[5]]
for i in range(5, 0, -1):
 size = (gpB[i-1].shape[1], gpB[i-1].shape[0])
 GE = cv2.pyrUp(gpB[i], dstsize = size)
 L = cv2.subtract(gpB[i-1], GE)
 lpB.append(L)

LS = []
for la,lb in list(zip(lpA, lpB)):
 rows, cols, dpt = la.shape
 ls = np.hstack((la[:,0:int(cols/2)],lb[:,int(cols/2):]))
 LS.append(ls)
 
ls_ = LS[0]
for i in range(1,6):
 size = (LS[i].shape[1], LS[i].shape[0])
 ls_ = cv2.pyrUp(ls_, dstsize = size)
 ls_ = cv2.add(ls_, LS[i])

real = np.hstack((A[:,:int(cols/2)],B[:,int(cols/2):]))
plt.imshow(ls_),plt.show()
cv2.imwrite('Pyramid_blending2.jpg',ls_)
cv2.imwrite('Direct_blending.jpg',real)

で・・・きれいにブレンドされるのか?というと、左右の絵が綺麗にそろってないと、こんな感じになります(笑)ダイレクトにひっつけたやつと、比べておいてみましたが・・・違いがあんまり分からないですね(笑)

やりたかったことと全然違うんですが。。忘備録として(笑)

参考文献

など。。

コメントを残していただけるとありがたいです

Loading Facebook Comments ...
%d人のブロガーが「いいね」をつけました。