このチュートリアルは、シリーズの「レッスン2」として提供されるコンピュータビジョンの基礎です。これからさらに多くのレッスンが開催され、独自のディープラーニングベースのコンピュータビジョンプロジェクトを構築する範囲について話し合われます。こちらから完全なシラバスと目次をご覧いただけます.
この記事からの主なポイント:
- ディスクからの画像の読み込み.
- 画像の‘高さ’、‘幅’、‘深さ’の取得.
- 画像のR, G, B成分の検索.
- OpenCVを使用した描画.
ディスクからの画像の読み込み
画像に対して何らかの操作や操作を行う前に、ディスクに選択した画像をロードすることが重要です。このアクティビティはOpenCVを使用して実行されます。このロード操作を実行する方法は2つあります。1つの方法は、画像パスと画像ファイルをOpenCVの「imread」関数に単に渡すことで画像をロードする方法です。もう1つの方法は、コマンドライン引数を使用してpythonモジュールargparseを通じて画像を渡す方法です.
#ディスクからの画像の読み込み
import cv2
image = cv2.imread(“C:/Sample_program/example.jpg”)
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
メモ帳++で「Loading_image_from_disk.py」というファイル名を作成しましょう。まず、画像処理機能を含むOpenCVライブラリをインポートします。ライブラリは最初のコード行でcv2としてインポートします。2行目のコードでは、OpenCVのcv2.imread関数を使用して画像を読み込み、画像のパスをパラメータとして渡します。パスには、画像のファイル名とその画像形式拡張子(.jpg、.jpeg、.png、または.tiff)も含まれている必要があります。
構文 — // image=cv2.imread(“path/to/your/image.jpg”) //
ファイル拡張子名を指定する際には、絶対的な注意が必要です。拡張子名を間違えると、以下のエラーが発生する可能性があります。
ERROR :
c:\Sample_program>python Loading_image_from_disk.py
Traceback (most recent call last):
File “Loading_image_from_disk.py”, line 4, in <module>
cv2.imshow(‘Image’, image)
cv2.error: OpenCV(4.3.0) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in function ‘cv::imshow’
3行目のコードでは、実際に読み込んだ画像を表示します。最初のパラメータは文字列、つまりウィンドウの「名前」です。2番目のパラメータは画像が読み込まれたオブジェクトです。
最後に、cv2.waitKeyへの呼び出しは、キーボードでキーを押すまでスクリプトの実行を一時停止します。「0」というパラメータを使用すると、任意のキーストロークで実行が再開されます。最後の行のコードをプログラムに含めずにプログラムを実行して、違いを確認してください。
#Argparseを使用したディスクからの画像読み込み
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
コマンドライン引数(argparse)を使用して画像やファイルを読み込む方法を知っておくことは、絶対に必要なスキルです。
最初の2行のコードでは、必要なライブラリをインポートします。ここでは、OpenCVとArgparseをインポートします。これはコース全体を通じて繰り返されます。
以下の3行のコードは、コマンドライン引数のパースを担当しています。必要な唯一の引数は—imageで、これはディスク上の画像へのパスです。最後に、引数をパースし、それらを`args`という名前の辞書に格納します。
ちょっと時間を取って、—imageスイッチが何であるかを正確に説明しましょう。—image「スイッチ」(「スイッチ」は「コマンドライン引数」の同義語で、これらの用語は交換可能に使用できます)は、コマンドラインで指定する文字列です。このスイッチは、Loading_image_from_disk.pyスクリプトに、ロードしたい画像がディスク上のどこにあるかを伝えます。
最後の3行のコードは以前に説明されています。cv2.imread関数は、コマンドプロンプトで提供する画像であるargs[“image”]をパラメータとして取ります。cv2.imshowは、前の行から既に画像オブジェクトに保存されている画像を表示します。最後の行は、キーボードでキーを押すまでスクリプトの実行を一時停止します。
argparseを使用してコマンドライン引数を使用する主な利点の1つは、プログラム内の画像パスを変更することなく、動的に画像パスを渡すことで、異なるフォルダー位置から画像をロードできることです。例:「C:\CV_Material\image\sample.jpg」をコマンドプロンプトで引数として渡しながら、Pythonプログラムを実行します。
c:\Sample_program>python Loading_image_from_disk.py — image C:\CV_Material\session1.JPG
ここでは、「-image」パラメータとともに画像のパスC:\CV_Material\session1.JPGを渡して、c:\sample_programロケーションからLoading_image_from_disk.pyPythonファイルを実行しています。
画像の「高さ」、「幅」、「深さ」を取得
画像がNumPy配列として表されているため、.shape属性を簡単に使用して幅、高さ、およびチャンネル数を調べることができます。
先にロードした画像オブジェクトに.shape属性を使用することで、画像の高さ、幅、および深さを見つけることができます。前回のレッスン—1で説明したように、画像の高さと幅はMS Paintで画像を開くことで確認できます。前回のレッスンを参照してください。画像の深さについては次のレッスンで説明します。深さもまた画像のチャンネルとして知られています。カラー画像は通常、RGB成分による画素の構成のため3チャンネルであり、グレースケール画像は1チャンネルです。これは前回のLesson-1で説明した内容です。
#画像の高さ、幅、および深さを取得
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
#前回のコードとの唯一の違い—画像オブジェクトに形状属性を適用
print(f’(Height,Width,Depth) of the image is: {image.shape}’)
image = cv2.imread(args[“image”])
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
出力:
画像の(高さ、幅、深さ)は:(538, 723, 3)
前回のコードとの唯一の違いは、ロードされた画像オブジェクトに形状属性を適用するprint文です。f’ はF文字列@動的に変数を取り、印刷するフォーマットされた文字列です。
f’ write anything here that you want to see in the print statement: {variables, variables, object, object.attribute,}’
ここでは、フラワーブラケット内で{object.attribute}を使用して、.shape属性を計算し、画像オブジェクトの高さ、幅、および深さを求めています。
#高さ、幅、および深さを個別に取得
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
#NumPy配列スライシングにより、高さ、幅、および深さを個別に取得
print(“height: %d pixels” % (image.shape[0]))
print(“width: %d pixels” % (image.shape[1]))
print(“depth: %d” % (image.shape[2]))
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
出力:
幅: 723ピクセル
高さ: 538ピクセル
深さ: 3
ここでは、タプルとして(高さ、幅、および深さ)を一緒に取得する代わりに、配列スライシングを実行し、画像の高さ、幅、および深さを個別に取得しています。配列の0番目のインデックスには画像の高さが含まれ、1番目のインデックスには画像の幅が含まれ、2番目のインデックスには画像の深さが含まれます。
画像のR、G、およびB成分を見つける
出力:
位置(321, 308)における画像のブルー、グリーン、レッド成分の値は: (238, 242, 253)
y値がx値の前に渡される方法に注意してください―この構文は最初は直感的に感じられないかもしれませんが、行列内の値にアクセスする方法と一致しています: 最初に行番号を指定し、次に列番号を指定します。そこから、画像のブルー、グリーン、レッド成分を表すタプルが得られます。
また、特定の位置のピクセルの色を変更するために、逆の操作を行うこともできます。
#(x,y)位置の画像のR,B,Gを見つける
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
#ユーザーからピクセル座標値[y,x]を受け取り、RGB値を計算する
[y,x] = list(int(x.strip()) for x in input().split(‘,’))
#受け取ったピクセル座標の(ブルー、グリーン、レッド)値を抽出
(b,g,r) = image[y,x]
print(f’The Blue Green Red component value of the image at position {(y,x)} is: {(b,g,r)}’)
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
(b,g,r) = image[y,x] to image[y,x] = (b,g,r)
ここでは、(BGR)の色を画像のピクセル座標に割り当てます。位置(321,308)のピクセルにRED色を割り当ててみて、その正しさを指定された位置でピクセルのBGRを印刷することで確認してみましょう。
#ピクセルにRGB値を割り当てる操作を逆にする
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
#ユーザーからRGB値を計算するためのピクセル座標値[y,x]を受け取る
[y,x] = list(int(x.strip()) for x in input().split(‘,’))
#受け取ったピクセル座標の(ブルー,グリーン,レッド)値を抽出する
image[y,x] = (0,0,255)
(b,g,r) = image[y,x]
print(f’The Blue Green Red component value of the image at position {(y,x)} is: {(b,g,r)}’)
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
出力:
位置(321, 308)の画像のブルー、グリーン、レッドの成分値は(0, 0, 255)です
上記のコードでは、図2.6に示すようにコマンドプロンプトを通じてピクセル座標を受け取り、(0,0,255)、つまり(ブルー, グリーン, レッド)を割り当てることでピクセル座標に赤色を割り当て、入力ピクセル座標を印刷することでその正しさを確認します。
OpenCVを使用した描画
OpenCVを使用して長方形、正方形、円などの異なる形状を描く方法を学びましょう。目を覆うために円を描き、唇を覆うために長方形を描き、私の隣にあるマントラレイフィッシュを覆うために長方形を描きます。
出力は次のようになります:
この写真はMS Paintを使用して形状でマスクされています。OpenCVを使用して目の周りに円を描き、唇と私の隣にあるマントラレイフィッシュを覆うために長方形を描いて同じことを試みます。
長方形を描くためにはcv2.rectangleメソッドを、円を描くためにはcv2.circleメソッドをOpenCVで使用します。
cv2.rectangle(image, (x1, y1), (x2, y2), (Blue, Green, Red), Thickness)
cv2.rectangleメソッドは、矩形を描画したい画像を最初の引数として受け取ります。ここでは、ロードした画像オブジェクトに矩形を描画したいため、それをメソッドに渡しています。2つ目の引数は、矩形の開始位置(x1, y1)です。ここでは、点(156と340)から矩形を開始します。次に、矩形の終了位置(x2, y2)を指定する必要があります。ここでは、点(360, 450)で矩形を終了することにしました。次の引数は、描画する矩形の色です。ここでは、BGR形式で黒色、すなわち(0,0,0)を渡しています。最後に、線の太さを指定する引数を渡します。図2.6に示すように、-1を指定することで塗りつぶされた図形を描画します。
同様に、cv2.circleメソッドを使用して円を描画します。
cv2.circle(image, (x, y), r, (Blue, Green, Red), Thickness)
cv2.circleメソッドは、円を描画したい画像を最初の引数として受け取ります。ここでは、ロードした画像オブジェクトに円を描画したいため、それをメソッドに渡しています。2つ目の引数は、円の中心位置(x, y)です。ここでは、点(343, 243)に円を配置します。次の引数は、描画する円の半径です。その次の引数は、円の色です。ここでは、BGR形式で赤色、すなわち(0,0,255)を渡しています。最後に、線の太さを指定する引数を渡します。図2.6に示すように、-1を指定することで塗りつぶされた図形を描画します。
わかった!これらの知識を持って、始めたことを達成してみましょう。画像内の形状を描画するために、マスキング領域の開始および終了(x,y)座標を特定し、対応するメソッドに渡す必要があります。
どうやるの?
もう一度MS Paintの助けを借ります。マスキング領域の座標(左上または右下)の1つの上にカーソルを置くと、MS Paintのハイライト表示された部分に座標が表示されます(図2.7参照)。
同様に、図2.8に示すように、すべてのマスキング領域の座標(x1,y1)(x2,y2)を取得します。
#OpenCVを使用して目、口、および近くのオブジェクトをマスクして描画
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
cv2.rectangle(image, (415, 168), (471, 191), (0, 0, 255), -1)
cv2.circle(image, (425, 150), 15, (0, 0, 255), -1)
cv2.circle(image, (457, 154), 15, (0, 0, 255), -1)
cv2.rectangle(image, (156, 340), (360, 450), (0, 0, 0), -1)
#出力画像を表示
cv2.imshow(“Output drawing “, image)
cv2.waitKey(0)
結果:

Source:
https://dzone.com/articles/computer-vision-tutorial-2-image-basics