- 1.ビット演算とマスキング
- 2.畳み込みとぼかし
- 3.シャープネス-画像のぼかしを反転します
- 4.スレショディング(二値化)
- 5.拡張、侵食、開閉
- 6.エッジ検出と画像勾配
- 14.パースペクティブとアフィン変換
- 8.ライブスケッチアプリケーション
前のチュートリアルでは、OpenCVについて学び、基本的な画像処理を行いました。次のチュートリアルでは、トリミング、回転、画像変換など、OpenCVでの画像操作を行いました。したがって、前の画像操作チュートリアルに続いて、ここで学習します。チュートリアルのようないくつかの画像操作テクニックとチュートリアルの最後に、ウェブサイトのライブフィードからライブスケッチを作成するためのpython-opencvプログラムを構築します。このアプリケーションは、これまでに学習した、またはこのチュートリアルで学習する画像処理機能の多くを使用するため、これはすべての機能をカバーするための優れた実用的な例になります。
前のチュートリアルで説明したように、 OpenCVはオープンソースのCommuter Vision Library であり、C ++、Python、およびJavaインターフェイスを備え、Windows、Linux、Mac OS、iOS、およびAndroidをサポートしています。そのため、PythonおよびLinux環境のRaspberryPiに簡単にインストールできます。また、OpenCVとカメラが接続されたRaspberry Piを使用して、顔検出、顔ロック、オブジェクトトラッキング、車のナンバープレート検出、ホームセキュリティシステムなど、多くのリアルタイム画像処理アプリケーションを作成できます。
このチュートリアルでは、PythonOpenCVを使用した画像操作について説明します。ここでは、PythonOpenCVを使用して画像に次の関数を適用する方法を学習します。
- ビット演算とマスキング
- 畳み込みとぼかし
- シャープネス-画像のぼかしを反転させる
- しきい値処理(2値化)
- 膨張、侵食、開閉
- エッジ検出と画像勾配
- パースペクティブとアフィン変換
- ライブスケッチアプリケーション
1.ビット演算とマスキング
ビット演算は、画像のマスキングに役立ち、いくつかの単純な画像を作成するのに役立ちます。
正方形を作る
import cv2 import numpy as np #これはグレースケール画像であるため、2次元のみを使用します。 #colored画像 を使用している場合は、rectangle = np.zeros((300,300,3)、np.uint8)#を使用していました。正方形を作成する = np.zeros((300,300)、np.uint8) cv2.rectangle(square、(50,50)、(250,250)、255、-1) cv2.imshow( "square"、square) cv2。 waitKey(0)
楕円を作る
ellipse = np.zeros((300,300)、np.uint8) cv2.ellipse(ellipse、(150,150)、(150,150)、30,0,180,255、-1) cv2.imshow( "ellipse"、ellipse) cv2.waitKey(0 )
ビット演算の実験
#AND_2つが交差する場所のみを表示
BitwiseAND = cv2.bitwise_and(square、ellipse) cv2.imshow( "AND"、BitwiseAND) cv2.waitKey(0)
#OR_showsは、正方形または楕円のいずれかが存在する場所のみです
BitwiseOR = cv2.bitwise_or(square、ellipse) cv2.imshow( "OR"、BitwiseOR) cv2.waitKey(0)
#XOR_showsは、どちらかが単独で存在する場合にのみ表示されます
BitwiseXOR = cv2.bitwise_xor(square、ellipse) cv2.imshow( "XOR"、BitwiseXOR) cv2.waitKey(0)
#NOT_は、楕円の一部ではないすべてのものを表示し、 NOT操作は単一の図にのみ適用できます
BitwiseNOT_elp = cv2.bitwise_not(ellipse) cv2.imshow( "NOT_ellipse"、BitwiseNOT_elp) cv2.waitKey(0) cv2.destroyAllWindows()
2.畳み込みとぼかし
畳み込みは、典型的には、元の関数の修正バージョンである第三の関数を生成する二つの機能に対して行わ数学的操作です。
出力画像=画像機能カーネルサイズ
でコンピュータビジョン、我々は我々の画像の上に私たちの操作機能を実行する上でサイズを指定するには、カーネルのを使用しています。
ぼかしは、領域内のピクセルを平均化する操作です(カーネル)
OpenCVはカーネルを適用することで画像をぼかします。カーネルは、特定のピクセルの値をさまざまな量の隣接ピクセルと組み合わせて変更する方法を示します。カーネルは、画像内のすべてのピクセルに1つずつ適用され、最終的な画像を生成します。
簡単に言うと、画像の畳み込みは、2つの行列の要素ごとの乗算とそれに続く合計です。
次の例で簡単に理解できます。
上記は3X3カーネルです。
1/25を掛けて正規化します。つまり、合計を1にすると、画像を明るくしたり暗くしたりする場合と同様に、強度を上げたり下げたりしていました。
関数cv2.filter2D(image、-1、kernel)で与えられるopencvブラーメソッドfilter2Dをテストしてみましょう。
import cv2 import numpy as np image = cv2.imread( 'elephant.jpg') cv2.imshow( 'original'、image) cv2.waitKey(0)
#3x3カーネルマトリックスの作成
kernel_3x3 = np.ones((3,3)、np.float32)/ 9
#cv2.filter2Dを使用して、カーネルを画像で畳み込みます
ぼかし= cv2.filter2D(image、-1、kernel_3x3) cv2.imshow( '3x3_blurring'、 blured )cv2.waitKey(0)
#7x7カーネルマトリックスの作成
kernel_7x7 = np.ones((7,7)、np.float32)/ 49
#cv2.filter2Dを使用して、カーネルを画像で畳み込みます
ぼやけた= cv2.filter2D(画像、-1、カーネル_7x7)cv2.imshow( '7x7_blurring'、ぼやけた)cv2.waitKey(0)cv2.destroyAllWindows()
ある方法をぼかし、他のタイプすぎには:
cv2.blur –指定されたウィンドウの平均値。
cv2.GaussianBlur –同様ですが、ガウスウィンドウを使用します(中心の周りのポイントをより強調します)。
cv2.medianBlur –ウィンドウ内のすべての要素の中央値を使用します。
cv2.bilateralFilter –エッジをシャープに保ちながらぼかし、エッジとラインの詳細を保持します。
以下に1つずつ表示します。最初に、以下のコードを使用して元の画像を表示します。
import cv2 import numpy as np image = cv2.imread( 'elephant.jpg') cv2.imshow( 'original'、image) cv2.waitKey(0)
cv2.blur:
この方法では、画像を正規化されたボックスフィルタで畳み込むことによって平均化が行われます。これはボックスの下で行われ、中央の要素を置き換えます。ここで、ボックスのサイズは奇数で正である必要があります 。
#cv2.blurblur = cv2.blur(image、(3,3)) cv2.imshow( 'Averaging'、blur) cv2.waitKey(0)
cv2.GaussianBlur:
#cv2.GaussianBlur# ボックスフィルターの代わりに、ガウスカーネルを試してみましょうGaussian = cv2.GaussianBlur(image、(7,7)、0) cv2.imshow( 'ガウスぼかし'、ガウス) cv2.waitKey(0)
cv2.medianBlur:
カーネル領域の下のすべてのピクセルの中央値を取り、中央要素はこの中央値に置き換えられます。
#cv2.medianBlur# カーネル領域の下のすべてのピクセルの中央値を取得し、中央要素 #はこの中央値に置き換えられます。 中央値= cv2.medianBlur(画像、5)cv2.imshow( 'メジアンぼかし'、中央値) cv2.waitKey(0)
cv2.bilateralFilter:
バイラテラルは、エッジをシャープに保ちながら、ノイズ除去に非常に効果的です
#cv2.bilateralFilter #Bilateralは、エッジをシャープに保ちながら、ノイズ除去に非常に効果的 です。bilateral = cv2.bilateralFilter(image、9,75,75) cv2.imshow( 'bilateralblurring'、bilateral) cv2.waitKey(0) cv2。 destroyAllWindows()
画像のノイズ除去-非ローカルはノイズ除去を意味します
import cv2 import numpy as np image = cv2.imread( 'elephant.jpg') cv2.imshow( 'original'、image) cv2.waitKey(0)
なしの後の#パラメータはフィルタ強度です 'h'(5-10は適切な範囲です) #nextは色成分のhであり、hと同じ値に再度設定します
dst = cv2.fastNlMeansDenoisingColored(image、None、6,6,7,21) cv2.imshow( 'Fast mean denois'、dst) cv2.waitKey(0) cv2.destroyAllWindows()
非局所的手段のノイズ除去には4つのバリエーションがあります
cv2.fastNlMeansDenoising() –単一のグレースケール画像用
cv2.fastNlMeansDenoisingColored() –単色画像
cv2.fastNlmeansDenoisingMulti() –画像シーケンスのグレースケール用
cv2.fastNlmeansDenoisingcoloredMulti() –色付きの画像シーケンス用
3.シャープネス-画像のぼかしを反転します
シャープネスはぼかしの反対で、画像のエッジを強調または強調します。
カーネル=、、
カーネル行列の合計は1になるため、正規化する必要はありません(つまり、元の明るさと同じ明るさの係数を掛けます)。カーネルが1に正規化されていない場合、画像は明るくなったり暗くなったりします。
import cv2 import numpy as np image = cv2.imread( 'elephant.jpg') cv2.imshow( 'original'、image) cv2.waitKey(0)
kernel_sharpening = np.array(、
、
])
#入力画像にシャープカーネルを適用する
Sharpened = cv2.filter2D(image、-1、kernel_sharpening) cv2.imshow( 'sharpened image'、sharpened) cv2.waitKey(0) cv2.destroyAllWindows()
4.スレショディング(二値化)
しきい値処理は、画像をバイナリ形式に変換する行為です。opencvには、次のように定義されたしきい値処理用の個別の関数があります。
Cv2.threshold(画像、しきい値、最大値、しきい値タイプ)
次のしきい値タイプがあります。
- cv2.THRESH_BINARY –最も一般的
- cv2。THRESH_BINARY_INV –最も一般的
- cv2.THRESH_TRUNC
- cv2.THRESH_TOZERO
- cv2。THRESH_TOZERO_INV
注:しきい値処理の前に、画像をグレースケールに変換する必要があります
import cv2 import numpy as np #load image as greyscale image = cv2.imread( 'gradient.jpg'、0) cv2.imshow( 'original'、image) cv2.waitKey(0)
127未満の#値は0(黒)になり、127を超える値は255(白)になります
_、thresh1 = cv2.threshold(image、127,255、cv2.THRESH_BINARY)cv2.imshow( '1 threshold'、thresh1) cv2.waitKey(0)
127未満の#値は255になり、127を超える値は0になります(上記の逆)
_、thresh2 = cv2.threshold(image、127,255、cv2.THRESH_BINARY_INV) cv2.imshow( '2 threshold'、thresh2) cv2.waitKey(0)
127を超える#valueは127で切り捨てられ(保持され)、255引数は使用されません。
_、thresh3 = cv2.threshold(image、127,255、cv2.THRESH_TRUNC) cv2.imshow( '3 thresh trunc'、thresh3) cv2.waitKey(0)
127未満の#値は0になり、127を超える値は変更されません
_、thresh4 = cv2.threshold(image、127,255、cv2.THRESH_TOZERO) cv2.imshow( '4 threshold'、thresh4) cv2.waitKey(0)
#上記のRevesrse、127未満は変更されず、127を超えるとゼロになります
_、thresh5 = cv2.threshold(image、127,255、cv2.THRESH_TOZERO_INV) cv2.imshow( '5 threshold'、thresh5) cv2.waitKey(0) cv2.destroyAllWindows()
5.拡張、侵食、開閉
これらは数理形態学の分野での操作です
膨張–画像内のオブジェクトの境界にピクセルを追加します。
侵食–画像内のオブジェクトの境界にあるピクセルを削除します。
開口部–侵食とそれに続く拡張。
クロージング–拡張とそれに続く侵食。
開くと、最初に侵食によって画像が薄くなり(ノイズが除去され)、次に画像が拡張されるため、画像のノイズ除去に非常に役立ちます。
拡張と侵食との混同
opencvは白い背景を元の画像ではなく拡張または侵食される画像と見なすため、通常は白い背景の画像では、膨張と侵食の間に混乱が生じることがあります。この場合、画像サンプルに示すように、侵食は膨張として機能し、その逆も同様です。下に示された。
Dilationは画像内のオブジェクトの境界にピクセルを追加し、Erosionは画像内のオブジェクトの境界にあるピクセルを削除することを忘れないでください
import cv2 import numpy as np image = cv2.imread( 'imagecv.png'、0) cv2.imshow( 'original'、image) cv2.waitKey(0)
#Erosion
#カーネルサイズを定義しましょう
kernel = np.ones((5,5)、np.uint8)
#今、私たちは画像を侵食します、ここでの反復はあなたが画像を侵食したい回数ではありません
erosion = cv2.erode(image、kernel、iterations = 1) cv2.imshow( 'Erosion'、erosion) cv2.waitKey(0)
#dilation
dilation = cv2.dilate(image、kernel、iterations = 1) cv2.imshow( 'dilation'、dilation) cv2.waitKey(0)
#オープニング、ノイズ除去に最適
open = cv2.morphologyEx(image、cv2.MORPH_OPEN、kernel) cv2.imshow( 'opening'、opening) cv2.waitKey(0)
#閉じる、ノイズを取り除くのに適しています
クロージング= cv2.morphologyEx(image、cv2.MORPH_CLOSE、kernel) cv2.imshow( 'クロージング'、クロージング) cv2.waitKey(0) cv2.destroyAllWindows()
6.エッジ検出と画像勾配
エッジ検出は、特に輪郭を扱う場合、コンピュータビジョンで非常に重要な領域です。
エッジは画像の境界として定義できます。実際には、エッジは画像内のオブジェクトを定義するエッジであり、画像に関する多くの情報を保持します。
正式には、エッジは画像の突然の変化(不連続性)として定義でき、ピクセルと同じ量の情報をエンコードできます。
上の画像は、コンピュータビジョンが画像を識別および認識する方法を示しています。
エッジ検出アルゴリズム:-エッジ検出アルゴリズムには主に3つのタイプがあります
- Sobel –垂直または水平の画像を強調します。
- ラプラシアン–エラー率が低く、エッジが明確に定義され、正確に検出されるため、最適です。
- キャニーエッジ検出アルゴリズム(1986年にjohn.F.Cannyによって開発されました)
1.ガウスぼかしを適用します
2.画像の強度勾配を見つけます
3.非最大抑制を適用します(つまり、エッジではないピクセルを削除します)。
4.ヒステリシスはしきい値を適用します(つまり、ピクセルが上限と下限のしきい値内にある場合、それはエッジと見なされます)
import cv2 import numpy as np image = cv2.imread( 'input.jpg'、0) height、width = image.shape
#sobel
#ソーベルエッジの抽出
sobel_x = cv2.Sobel(image、cv2.CV_64F、0,1、ksize = 5) sobel_y = cv2.Sobel(image、cv2.CV_64F、1,0、ksize = 5) cv2.imshow( 'original'、image) cv2.waitKey(0) cv2.imshow( 'sobelx'、sobel_x)cv2.waitKey(0)
#Sobely
cv2.imshow( 'sobely'、sobel_y) cv2.waitKey(0)
sobel_OR = cv2.bitwise_or(sobel_x、sobel_y)cv2.imshow( 'sobelOR'、sobel_OR)cv2.waitKey(0)
#laplaian
laplacian = cv2.Laplacian(image、cv2.CV_64F) cv2.imshow( 'Laplacian'、 laplacian )cv2.waitKey(0)
#cannyエッジ検出アルゴリズムは、しきい値として勾配値を使用します。
#cannyでは、threshold1とthreshold2の2つの値を指定する必要があります。
#しきい値2より大きい勾配は、エッジと見なされます。
#しきい値1より大きい勾配は、エッジではないと見なされます。
閾値1と閾値2との間で#valuesエッジ又は非エッジのいずれかであり
、この中で、それらの強度が接続されている方法#onケース60以下の任意の値がされていると考え
縁#non wheareas 120上の任意の値がエッジと考えられます。
canny = cv2.Canny(image、60,120) cv2.imshow( 'canny'、canny) cv2.waitKey(0) cv2.destroyAllWindows()
14.パースペクティブとアフィン変換
一歩下がって、アフィン変換と非アフィン変換を見てみましょう。下に示す元の画像は、エッジがいつか出会うため、明らかに非アフィン画像ですが、ワープして遠近法をとることでまっすぐにすることができます変換します。
この透視変換では、元の画像の4つの座標と、出力画像の4つの点が必要です。これらは、points_Aとpoints_Bで表されます。まず、これらのポイントを使用して、 getPerspectiveTransform関数 を使用して変換行列Mを計算し ます。
そして、この行列が warpPerspective 関数に渡され、最終出力が生成されます。
今度は、聞かせて最初の視点変換してみてください。
import cv2 import numpy as np import matplotlib.pyplot as plt image = cv2.imread( 'paper.jpg') cv2.imshow( 'original'、image) cv2.waitKey(0)
#元の画像の4つの角の座標
points_A = np.float32(,,,])
#目的の出力の4つのコーナーの
座標#A4用紙の比率を1:1.41使用します
points_B = np.float32(,,,])
#2点の2つのセットを使用して、予測変換行列Mを計算します
M = cv2.getPerspectiveTransform(points_A、points_B) warped = cv2.warpPerspective(image、M、(420,594)) cv2.imshow( 'warpprespective'、warped) cv2.waitKey(0) cv2.destroyAllWindows()
アフィン変換は、変換を取得するために3つのポイントしか必要としないため、非アフィン変換よりも簡単です。プロセス全体は同じですが、パースペクティブ変換の代わりにアフィン変換があり、手動で入力する代わりに、shape関数から warpAffineの 列と行を定義します。
import cv2 import numpy as np import matplotlib.pyplot as plt image = cv2.imread( 'box.jpg') rows、cols = image.shape cv2.imshow( 'original'、image) cv2.waitKey(0)
#元の画像の3つの角の座標
points_A = np.float32(,,])
#目的の出力の3つのコーナーの
座標#A4用紙の比率を1:1.41使用します
points_B = np.float32(,,])
#2点の2つのセットを使用して、アフィン#変換行列、Mを計算します
M = cv2.getAffineTransform(points_A、points_B) warped = cv2.warpAffine(image、M、(cols、rows)) cv2.imshow( 'warpaffine'、warped) cv2.waitKey(0) cv2.destroyAllWindows()
8.ライブスケッチアプリケーション
まず、上記のすべての画像操作機能を読んだ後、このミニプロジェクトを完成させたことを祝福します。したがって、Python OpenCVのこのミニプロジェクトでは、ループと関数のいくつかの新しい概念を学習します。プログラミングに精通している場合は、関数とループが何であるかについてより広い考えを持っている必要があります。ただし、Pythonでは、ループと関数の基本的な概念は同じですが、それらを定義する方法が少し異なります。
したがって、このプログラムの開始時に、「def Sketch(image):」の下にある特定のステートメントのグループを見ることができます。これは、特定の出力に対して一緒に機能するステートメントのグループの関数の正式な定義です。
したがって、このスケッチは関数です。Pythonでは、関数は「def」で定義され、「:」マークで終わります。また、関数内にある必要があるステートメント、または関数が正しく機能するために必要なステートメントは、関数によって自動的にサイドアラインされます。したがって、関数から抜け出すには、ステートメントを完全に左揃えにする必要がありました。詳細については、Pythonで関数がどのように定義されているかについてGoogleを参照してください。
そのため、このスケッチ関数では、画像処理のいくつかのレイヤーを導入し、それらを組み合わせて出力を提供します。まず、画像をグレースケールに変換してopencvで簡単に処理できるようにし、次にガウスぼかしをグレースケール画像に適用してノイズを低減します。次に、キャニーのエッジ検出アルゴリズムを使用してエッジを抽出し、エッジ定義の画像にバイナリインバースを適用します。ここでは、バイナリインバースもbitwise_NOTで実行できますが、自由度が得られるため、このしきい値のバイナリインバースを意図的に選択しました。鮮明な画像が得られるまでパラメータを設定します。
また、この関数は引数imageを受け取り、2つの引数retとmaskを返すことに注意してください。 retは関数が正常に実行されたかどうかを示すブール値であり、マスクは関数の最終出力、つまり処理された画像です。
次に、2番目の概念は cv2.VideoCapture(0) 関数によって実行される opencvで Webカメラを操作することです 。 この関数は cap.read() 関数でキャップを読み取ることができるオブジェクト キャップに 画像を格納します 。 ここでもその キャップ に注意してください 。 read()は 、ライブビデオの感覚を与えるために、画像を継続的にキャプチャする必要があるため、無限の whileループ 内に あります。 ビデオのフレームレートは、ほとんどが24〜60のWebカメラのフレームレートになります。 fps。
cap.read() はretとframeを返します。ここで、retは関数が正常に実行されたかどうかを示すブール値であり、フレームにはWebカメラで撮影された画像が含まれています。
以下は、LiveSketchを実行するための完全なPythonOpenCVコードです。
import cv2 import numpy as np #sketch生成関数defsketch (image): #画像をグレースケールに 変換img_gray = cv2.cvtColor(image、cv2.COLOR_BGR2GRAY) #ガウスぼかしを使用して画像をクリーンアップ img_gray_blur = cv2.GaussianBlur(img_gray、( 5,5)、0) #エッジを 抽出canny_edges = cv2.Canny(img_gray_blur、10,70) #画像を2値化して反転します ret、mask = cv2.threshold(canny_edges、70,255、cv2.THRESH_BINARY_INV) return mask #initialize website 、capは、ビデオキャプチャ によって提供されるオブジェクトです。#itには、成功したかどうかを示すブール値が含まれます(ret ) #itには、webcam(frame) cap = cv2.VideoCapture(0) から収集された画像も含まれますがTrue: ret、frame = cap.read() cv2.imshow( 'livesketcher'、sketch(frame)) if cv2.waitKey (1)== 13:#13はエンターキー ブレーク #releaseカメラでウィンドウを閉じます。cap.release() cap.release() cv2.destroyAllWindows()を使用してWebカメラを解放することを忘れないでください
これで、Pythonでの画像操作のパート2-OpenCVは終了です。コンピュータービジョンとOpenCVを十分に理解するには、以前の記事(PythonOpenCVとPythonOpenCVでの画像操作の開始(パート1))に目を通すと、コンピュータービジョンで何かクールなものを作ることができます。