Python を使用して OpenCV のバージョンをチェックする

opencv_versions_header

OpenCV 3 のリリースは、いくつかの OpenCV 2.4.X 関数と下位互換性を壊すことが避けられないものでした。 cv2.findContourscv2.normalize は、私の頭の中からすぐに思い浮かびました。

では、生産環境が使用している OpenCV のバージョンに関係なく、コードが動作することをどのようにして確認しますか。

さて、簡単に言うと、問題のある関数のそれぞれについて if 文を作成する必要があるということです (または、OpenCV のバージョンに基づいて適切な関数を呼び出す処理を行う別のメソッドに関数を分離して抽象化する)。

この投稿のソース コードをお探しですか。

ダウンロードセクションへジャンプ

OpenCV のバージョンは特別な cv2.__version__ 変数に含まれており、次のようにアクセスできます:

$ python>>> import cv2>>> cv2.__version__'3.0.0'

cv2.__version__ 変数は単純にメジャーとマイナーバージョンに分けることができる文字列です:

>>> (major, minor, _) = cv2.__version__.split(".")>>> major'3'>>> minor'0'

もちろん OpenCV のバージョンをチェックしたいときに毎回この操作を行うことは少し面倒なことです。 この問題を解決するために、私はimutilsパッケージに3つの新しい関数を追加しました。これは、OpenCVとPythonによる基本的な画像処理機能をより簡単にするための便利な関数のシリーズです。

以下の is_cv2is_cv3 、および check_opencv_version 関数をご覧ください。

def is_cv2(): # if we are using OpenCV 2, then our cv2.__version__ will start # with '2.' return check_opencv_version("2.")def is_cv3(): # if we are using OpenCV 3.X, then our cv2.__version__ will start # with '3.' return check_opencv_version("3.")def is_cv4(): # if we are using OpenCV 3.X, then our cv2.__version__ will start # with '4.' return check_opencv_version("4.")def check_opencv_version(major, lib=None): # if the supplied library is None, import OpenCV if lib is None: import cv2 as lib # return whether or not the current OpenCV version matches the # major version number return lib.__version__.startswith(major)

このコードは非常に単純で、単に cv2.__version__ 文字列が 2 で始まっているかどうかをチェックし、これは OpenCV 2.X を使用していることを示します。

繰り返しになりますが、これらの関数はすでに imutils パッケージに含まれており、pip を使用してインストールできます。

$ pip install imutils

すでに imutils をインストールしている場合、次の方法で最新バージョンにアップグレードできます。

$ pip install --upgrade imutils

Checking your OpenCV version: a real-world example

さて、Python を使用して OpenCV のバージョンを確認する方法と、バージョン確認を容易にするための便利な関数をいくつか定義しましたので、これらの関数を実際の例でどのように使用するかを見てみましょう。

ここでの目標は、次の画像から輪郭を検出することです。

Figure 1: OpenCV 2.4.X と OpenCV 3 を使用して、テトリス ブロックの輪郭を検出するつもりです。
Figure 1: OpenCV 2.4.X と OpenCV 3 を利用して、テトリス ブロックの輪郭 (すなわちアウトライン) を検出します。

画像の輪郭を検出するには、cv2.findContours関数を使用する必要があります。 しかし、ご存知のように、cv2.findContours の戻り値は OpenCV のバージョン 3 と 2.4 で若干変更されています (OpenCV 3 バージョンの cv2.findContours はタプルに追加値を返します)。したがって、スクリプトがエラーにならないように、cv2.findContours を呼び出す前に OpenCV バージョンを確認する必要があります。

# import the necessary packagesfrom __future__ import print_functionimport imutilsimport cv2# load the Tetris block image, convert it to grayscale, and threshold# the imageprint("OpenCV Version: {}".format(cv2.__version__))image = cv2.imread("tetris_blocks.png")gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)thresh = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV)# check to see if we are using OpenCV 2.X or OpenCV 4if imutils.is_cv2() or imutils.is_cv4():(cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# check to see if we are using OpenCV 3elif imutils.is_cv3():(_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# draw the contours on the imagecv2.drawContours(image, cnts, -1, (240, 0, 159), 3)cv2.imshow("Image", image)cv2.waitKey(0)

見ての通り、必要なのは is_cv2is_cv4is_cv3 を呼び出し、バージョン固有のコードを if 文ブロック内に記述することだけです。

OpenCV 2.4 を使用してスクリプトを実行すると、問題なく動作します。

Figure 2: cv2.findContours への呼び出しは OpenCV 2.4.X.
Figure 2: cv2.findContours への呼び出しは OpenCV 2.X で動作している。4.X.

また,OpenCV 3 についても同様です:

Figure 3: Python で is_cv2 と is_cv3 関数を用いて OpenCV バージョンを検出するので OpenCV 3 でも同じことが言えます.
Figure 3: そして、Python を使って OpenCV のバージョンを検出するために is_cv2 と is_cv3 関数を使用しているので、OpenCV 3 でも同様です。

まとめ

このブログ記事で、Pythonを使って OpenCV のバージョンを確認する方法について学びました。 OpenCV のバージョンは、cv2.__version__という特別な文字列変数に含まれています。

最後に、OpenCVのバージョンをより簡単に、よりPythonらしくチェックするために、imutilsパッケージの中でいくつかの便利なメソッドを定義しています。 もし、常に OpenCV のバージョンをチェックする必要があるなら、このライブラリをチェックアウトすることを検討してください。

コメントを残す

メールアドレスが公開されることはありません。