Rabu, 16 Desember 2020

OPENCV Canny Edge Detection¶

dalam tutorial ini kitas akan mempelajari cany detection dan fungi dari cv2.Canny()
Teori¶
Canny Edge Detection adalah algoritma deteksi tepi yang populer. Ini dikembangkan oleh John F. Canny pada tahun 1986. Ini adalah algoritma multi-tahap dan kita akan melalui setiap tahapan.

Pengurangan kebisingan
Karena deteksi tepi rentan terhadap noise pada gambar, langkah pertama adalah menghilangkan noise pada gambar dengan filter Gaussian 5x5. Kami telah melihat ini di bab sebelumnya.

Menemukan Gradien Intensitas Gambar
Citra yang telah dihaluskan kemudian disaring dengan kernel Sobel baik horizontal maupun vertikal untuk mendapatkan turunan pertama dalam arah horizontal (G_x) dan arah vertikal (G_y). Dari kedua gambar tersebut, kita dapat menemukan gradien tepi dan arah untuk setiap piksel sebagai berikut:

Edge\_Gradient \; (G) = \sqrt{G_x^2 + G_y^2}

Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg)
Arah gradien selalu tegak lurus dengan tepi. Ini dibulatkan ke salah satu dari empat sudut yang mewakili arah vertikal, horizontal dan dua arah diagonal.

Penindasan Non-maksimum
Setelah mendapatkan besaran dan arah gradien, pemindaian penuh gambar dilakukan untuk menghilangkan piksel yang tidak diinginkan yang mungkin bukan merupakan tepi. Untuk ini, pada setiap piksel, piksel diperiksa jika itu adalah maksimum lokal di lingkungannya dalam arah gradien. Periksa gambar di bawah ini:

Non-Maximum Suppression

Titik A ada di pinggir (dalam arah vertikal). Arah gradien normal ke tepi. Titik B dan C berada dalam arah gradien. Jadi titik A diperiksa dengan titik B dan C untuk melihat apakah itu membentuk maksimum lokal. Jika demikian, maka akan dipertimbangkan untuk tahap berikutnya, jika tidak maka akan ditekan (dimasukkan ke nol).

Singkatnya, hasil yang Anda dapatkan adalah gambar biner dengan "tepi tipis".

Histeresis Thresholding
Tahap ini memutuskan mana semua sisi yang benar-benar tepian dan mana yang tidak. Untuk ini, kami membutuhkan dua nilai ambang, minVal dan maxVal. Setiap tepi dengan gradien intensitas lebih dari maxVal pasti merupakan tepi dan yang di bawah minVal pasti bukan tepi, jadi buang. Mereka yang berada di antara dua ambang batas ini diklasifikasikan sebagai tepi atau non-tepi berdasarkan konektivitas mereka. Jika mereka terhubung ke piksel “sure-edge”, mereka dianggap sebagai bagian dari edge. Jika tidak, mereka juga akan dibuang. Lihat gambar di bawah ini:

Hysteresis Thresholding



tepi A berada di atas maxVal, sehingga dianggap sebagai "edge-pasti". Meskipun edge C berada di bawah maxVal, namun terhubung ke edge A, sehingga juga dianggap sebagai edge yang valid dan kami mendapatkan kurva penuh tersebut. Tetapi tepi B, meskipun berada di atas minVal dan berada di wilayah yang sama dengan tepi C, ia tidak terhubung ke "tepi-pasti", sehingga dibuang. Jadi, sangat penting bagi kami untuk memilih minVal dan maxVal yang sesuai untuk mendapatkan hasil yang benar.

Tahap ini juga menghilangkan noise piksel kecil dengan asumsi bahwa tepinya adalah garis panjang.

Jadi yang akhirnya kami dapatkan adalah tepi yang kuat pada gambar.

Deteksi Tepi Canny di OpenCV¶
OpenCV menempatkan semua hal di atas dalam fungsi tunggal, cv2.Canny (). Kami akan melihat cara menggunakannya. Argumen pertama adalah gambar masukan kami. Argumen kedua dan ketiga adalah minVal dan maxVal kami masing-masing. Argumen ketiga adalah aperture_size. Ini adalah ukuran kernel Sobel yang digunakan untuk menemukan gradien gambar. Standarnya adalah 3. Argumen terakhir adalah gradien L2 yang menentukan persamaan untuk mencari besaran gradien. Jika Benar, itu menggunakan persamaan yang disebutkan di atas yang lebih akurat, jika tidak menggunakan fungsi ini:
Edge\_Gradient \; (G) = |G_x| + |G_y|

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

img = cv2.imread('messi5.jpg',0)
edges = cv2.Canny(img,100,200)

plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

plt.show()

Canny Edge Detection



opencv blur filter

 Buramkan citra dengan berbagai filter akses rendah

Terapkan filter yang dibuat khusus ke gambar (konvolusi 2D)

Konvolusi 2D (Penyaringan Gambar) ¶

Sedangkan untuk sinyal satu dimensi, gambar juga dapat difilter dengan berbagai filter low-pass (LPF), filter high-pass (HPF), dll. LPF membantu menghilangkan noise, atau mengaburkan gambar. Filter HPF membantu menemukan tepi pada gambar.


OpenCV menyediakan fungsi, cv2.filter2D (), untuk menggabungkan kernel dengan sebuah image. Sebagai contoh, kami akan mencoba filter averaging pada gambar. Kernel filter rata-rata 5x5 dapat didefinisikan sebagai berikut:

K =  \frac{1}{25} \begin{bmatrix} 1 & 1 & 1 & 1 & 1  \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \end{bmatrix}

Pemfilteran dengan hasil kernel di atas dilakukan sebagai berikut: untuk setiap piksel, jendela 5x5 dipusatkan pada piksel ini, semua piksel yang termasuk dalam jendela ini dijumlahkan, dan hasilnya kemudian dibagi 25. Ini sama dengan menghitung rata-rata dari nilai piksel di dalam jendela itu. Operasi ini dilakukan untuk semua piksel pada gambar untuk menghasilkan gambar keluaran yang difilter. Coba kode ini dan periksa hasilnya:

JANGAN LUPA SIAPKAN GAMBAR DENGAN NAMA OPENCV_LOGO.PNG

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

img = cv2.imread('opencv_logo.png')

kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)

plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dst),plt.title('Averaging')
plt.xticks([]), plt.yticks([])
plt.show()

Averaging Filter

Image Blurring (Image Smoothing)

Pemburaman gambar dicapai dengan menggabungkan gambar dengan kernel filter lolos-rendah. Berguna untuk menghilangkan kebisingan. Ini benar-benar menghilangkan konten frekuensi tinggi (misalnya: noise, tepi) dari gambar yang mengakibatkan tepi menjadi kabur saat filter ini diterapkan. (Nah, ada teknik pengaburan yang tidak mengaburkan tepian). OpenCV menyediakan empat jenis teknik pengaburan.

1. Averaging

Ini dilakukan dengan membelit gambar dengan filter kotak yang dinormalisasi. Ini hanya mengambil rata-rata dari semua piksel di bawah area kernel dan menggantikan elemen pusat dengan rata-rata ini. Ini dilakukan oleh fungsi cv2.blur () atau cv2.boxFilter (). Periksa dokumen untuk detail lebih lanjut tentang kernel. Kita harus menentukan lebar dan tinggi kernel. Filter kotak normalisasi 3x3 akan terlihat seperti ini:

K =  \frac{1}{9} \begin{bmatrix} 1 & 1 & 1  \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix}

Jika Anda tidak ingin menggunakan filter kotak yang dinormalisasi, gunakan cv2.boxFilter () dan teruskan argumen normalize = False ke fungsi tersebut.


Periksa contoh demo di bawah ini dengan ukuran kernel 5x5:

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

img = cv2.imread('opencv_logo.png')

blur = cv2.blur(img,(5,5))

plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()


Averaging Filter

2. Gaussian Filtering


Dalam pendekatan ini, alih-alih filter kotak yang terdiri dari koefisien filter yang sama, digunakan kernel Gaussian. Itu dilakukan dengan fungsi, cv2.GaussianBlur (). Kita harus menentukan lebar dan tinggi kernel yang harus bernilai positif dan ganjil. Kita juga harus menentukan deviasi standar dalam arah X dan Y, sigmaX dan sigmaY masing-masing. Jika hanya sigmaX yang ditentukan, sigmaY dianggap sama dengan sigmaX. Jika keduanya diberikan sebagai nol, keduanya dihitung dari ukuran kernel. Pemfilteran Gaussian sangat efektif dalam menghilangkan noise Gaussian dari gambar.

Jika mau, Anda dapat membuat kernel Gaussian dengan fungsi cv2.getGaussianKernel ().

Kode di atas dapat dimodifikasi untuk mengaburkan Gaussian:

blur = cv2.GaussianBlur(img,(5,5),0)

Gaussian Blurring

3. Median Filtering


Di sini, fungsi cv2.medianBlur () menghitung median dari semua piksel di bawah jendela kernel dan piksel pusat diganti dengan nilai median ini. Ini sangat efektif dalam menghilangkan kebisingan garam dan merica. Satu hal yang menarik untuk diperhatikan adalah, dalam filter Gaussian dan kotak, nilai yang difilter untuk elemen pusat dapat berupa nilai yang mungkin tidak ada pada gambar asli. Namun ini tidak terjadi pada pemfilteran median, karena elemen pusat selalu diganti dengan beberapa nilai piksel pada gambar. Ini mengurangi kebisingan secara efektif. Ukuran kernel harus berupa bilangan bulat ganjil positif.

Dalam demo ini, kami menambahkan 50% noise ke gambar asli kami dan menggunakan filter median. Periksa hasilnya:
median = cv2.medianBlur(img,5)


Median Blurring


4. Bilateral Filtering

Seperti yang kami catat, filter yang kami sajikan sebelumnya cenderung mengaburkan tepian. Ini tidak terjadi pada filter bilateral, cv2.bilateralFilter (), yang telah ditentukan untuk, dan sangat efektif dalam menghilangkan derau sambil mempertahankan tepinya. Tetapi operasinya lebih lambat dibandingkan dengan filter lain. Kita sudah melihat bahwa filter Gaussian mengambil lingkungan di sekitar piksel dan menemukan rata-rata tertimbang Gaussian. Filter Gaussian ini adalah fungsi ruang saja, yaitu piksel terdekat dipertimbangkan saat memfilter. Ini tidak mempertimbangkan apakah piksel memiliki nilai intensitas yang hampir sama dan tidak mempertimbangkan apakah piksel berada di tepi atau tidak. Efek yang dihasilkan adalah filter Gaussian cenderung memburamkan tepinya, yang tidak diinginkan.

Filter bilateral juga menggunakan filter Gaussian dalam domain luar angkasa, tetapi juga menggunakan satu lagi komponen filter Gaussian (perkalian) yang merupakan fungsi dari perbedaan intensitas piksel. Fungsi ruang Gaussian memastikan bahwa hanya piksel yang merupakan 'tetangga spasial' yang dipertimbangkan untuk pemfilteran, sedangkan komponen Gaussian yang diterapkan dalam domain intensitas (fungsi perbedaan intensitas Gaussian) memastikan bahwa hanya piksel dengan intensitas yang serupa dengan yang ada di pusat. piksel ('intensitas tetangga') disertakan untuk menghitung nilai intensitas kabur. Akibatnya, metode ini mempertahankan tepi, karena untuk piksel yang terletak di dekat tepi, piksel tetangga yang ditempatkan di sisi lain tepi, dan karena itu menunjukkan variasi intensitas yang besar jika dibandingkan dengan piksel pusat, tidak akan disertakan untuk pemburaman.

Contoh di bawah ini menunjukkan penggunaan pemfilteran bilateral (Untuk detail tentang argumen, lihat dokumen OpenCV).

blur = cv2.bilateralFilter (img, 9,75,75)



Bilateral Filtering






Opencv gambar bgr to gray ,bgr to hsv

pengertian hsv adalah  model yang mewakili ruang warna yang mirip dengan model warna RGB. Karena saluran hue memodelkan jenis warna, ini sangat berguna dalam tugas pemrosesan gambar yang perlu menyegmentasikan objek berdasarkan warnanya. Variasi saturasi berubah dari tidak jenuh menjadi warna abu-abu dan jenuh penuh (tanpa komponen putih). Value channel menggambarkan kecerahan atau intensitas warna. Gambar berikutnya menunjukkan silinder HSV.

Threshold_inRange_HSV_colorspace.jpg

Karena warna dalam ruang warna RGB dikodekan menggunakan tiga saluran, maka lebih sulit untuk menyegmentasikan objek dalam gambar berdasarkan warnanya.


Threshold_inRange_RGB_colorspace.jpg


untuk konversi warna kita akan menggunakan fungsi cv2.cvtColor(input_image, flag)dimana flag menentukan conversi

untuk konversi bgr>gray kita menggunakan flag cv2.COLOR_BGR2GRAY. untuk bgr > hsv kita menggunakan cv2.COLOR_BGR2HSV

sebenernya ada banyak flag dari cv2 untuk konvert ke lainnya untuk mengetahui apa aja yang ada kamu bisa run kode di terminal python kamu dengan kode ini

>>import cv2

>>flags = [i for i in dir(cv2) if i.startswith('COLOR_')]

>>print flags

Untuk HSV, Hue range [0,179], Saturation range [0,255] dan Value range [0,255]. Perangkat lunak yang berbeda menggunakan skala yang berbeda. Jadi jika Anda membandingkan nilai OpenCV dengan mereka, Anda perlu menormalkan rentang ini.


Object Tracking

Sekarang kita tahu cara mengonversi gambar BGR ke HSV, kita dapat menggunakan ini untuk mengekstrak objek berwarna. Di HSV, lebih mudah untuk merepresentasikan warna daripada ruang warna RGB. Dalam aplikasi kami, kami akan mencoba mengekstrak objek berwarna biru. Jadi inilah caranya:

>Rekam setiap frame video

>Konversi dari BGR ke ruang warna HSV

>Kami membatasi citra HSV untuk rentang warna biru

>Sekarang ekstrak objek biru saja, kita dapat melakukan apapun pada gambar yang kita inginkan.

kode program sebagai contoh

import cv2

import numpy as np

cap = cv2.VideoCapture(0)#ambil vidio

while(1):

  # Take each frame

    _, frame = cap.read()#ambilperframe


    # Convert BGR to HSV

    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)


    # define range of blue color in HSV

    lower_blue = np.array([110,50,50])

    upper_blue = np.array([130,255,255])


    # Threshold the HSV image to get only blue colors

    mask = cv2.inRange(hsv, lower_blue, upper_blue)


    # Bitwise-AND mask and original image

    res = cv2.bitwise_and(frame,frame, mask= mask)


    cv2.imshow('frame',frame)

    cv2.imshow('mask',mask)

    cv2.imshow('res',res)

    k = cv2.waitKey(5) & 0xFF

    if k == 2:

        break


cv2.destroyAllWindows()

gambar kira2 akan seperti ini

Ada beberapa noise pada gambar. Kami akan melihat cara menghapusnya
kisaran warna2 lainnya antara lain adalah sbb:
  • [0, 0, 0], [255, 255, 150] – Hitam
  • [0, 100, 100], [3, 255, 255] – Merah
  • [4, 100, 100], [18, 255, 255] – Orange
  • [20, 100, 100], [40, 255, 255] – Kuning
  • [50, 100, 100], [70, 255, 255] – Hijau
  • [100, 100, 100], [120, 255, 255] – Biru
  • [120, 100, 100], [140, 255, 255] – Ungu
  • [0, 0, 0], [255, 255, 140] – Abu-Abu
  • [0, 0, 0], [255, 255, 200] – Putih
  • [14, 100, 100], [34, 255, 140] – Emas
  • [0, 0, 0], [255, 255, 120] – Silver

Ini adalah metode paling sederhana dalam pelacakan objek. Setelah Anda mempelajari fungsi kontur, Anda dapat melakukan banyak hal seperti menemukan pusat massa objek ini dan menggunakannya untuk melacak objek, menggambar diagram hanya dengan menggerakkan tangan di depan kamera dan banyak hal lucu lainnya.

bagaimana Cara menemukan nilai HSV untuk dilacak??nilai hsv disini maksudnya nilai warna biru seperti dicontoh itu adalah deteksi warna biru
Ini adalah pertanyaan umum yang ditemukan di stackoverflow.com. Ini sangat sederhana dan Anda dapat menggunakan fungsi yang sama, cv2.cvtColor (). Alih-alih meneruskan gambar, Anda cukup meneruskan nilai BGR yang Anda inginkan. Misalnya, untuk menemukan nilai HSV Green, coba perintah berikut di terminal Python:
 >>>green = np.uint8([[[0,255,0 ]]])
>>> hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
>>> print hsv_green
[[[ 60 255 255]]]
Sekarang Anda mengambil [H-10, 100.100] dan [H + 10, 255, 255] 
sebagai batas bawah dan batas atas. Selain metode ini, Anda
dapat menggunakan alat pengeditan gambar apa pun seperti GIMP 
atau konverter online apa pun untuk menemukan nilai ini, tetapi
 jangan lupa untuk menyesuaikan rentang HSV.
fungsi2 yang kita pakai dalam kode ini adalah


cap = cv2.VideoCapture(0)#ambil vidio

    _, frame = cap.read()#ambilperframe

    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # Convert BGR to HSV

    lower_blue = np.array([110,50,50]) # define range of blue color in HSV

    upper_blue = np.array([130,255,255])

    mask = cv2.inRange(hsv, lower_blue, upper_blue)  # Threshold the HSV image to get only blue colors

    res = cv2.bitwise_and(frame,frame, mask= mask)  # Bitwise-AND mask and original image

    cv2.imshow('frame',frame)#menampilkan gambar

    cv2.imshow('mask',mask)

    cv2.imshow('res',res)