Segmentasi Objek dengan Memanfaatkan Deteksi Tepi

Tulisan ini akan membahas tentang teknik segmentasi objek pada latar seragam dengan memanfaatkan algoritma deteksi tepi Canny. Latar seragam yang dimaksud di sini adalah latar (background) dengan satu warna (warna apapun) atau dengan gradasi warna yang tidak mencolok. Sebagai contoh gambar di bawah ini:

shoes

shoes.jpg

Tujuan akhir dari proses segmentasi ini adalah untuk menghilangkan background (warna abu-abu pada gambar di atas) sehingga didapatkan gambar dengan objeknya saja, seperti yang ditampilkan pada gambar di bawah ini:

result

result.jpg

Berikut adalah source code segmentasi dalam bahasa Python dengan menggunakan library OpenCV dan NumPy:

import cv2
import numpy as np

def segment(image):
    """
    Object Segmentation in Uniform Background using Edge Detection
    """

    # convert BGR image to grayscale
    image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
    image_gray = cv2.GaussianBlur(image_gray, (5, 5), 0)

    # get contours
    edges = cv2.Canny(image_gray, 20, 60)
    contours, _ = cv2.findContours(edges, mode=cv2.cv.CV_RETR_EXTERNAL,
                                   method=cv2.cv.CV_CHAIN_APPROX_SIMPLE)

    # compute object mask
    cv2.drawContours(edges, contours, -1, 255, 2)
    inv_edges = cv2.bitwise_not(edges)
    retval, rect = cv2.floodFill(inv_edges, None, (0, 0), 0)
    mask = cv2.bitwise_or(edges, inv_edges)

    # masking object
    result = np.zeros(image.shape, dtype='uint8')
    result[mask > 0, :] = image[mask > 0, :]

    return result

if __name__ == '__main__':
    image = cv2.imread('shoes.jpg')
    result = segment(image)
    cv2.imwrite('result.jpg', result)

Mari kita bahas tiap – tiap baris dari kode di atas.

import cv2
import numpy as np

Baris 1 dan 2 menunjukkan bahwa kita akan menggunakan library OpenCV dan Numpy.

image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
image_gray = cv2.GaussianBlur(image_gray, (5, 5), 0)

Pada baris ke-10, kita melakukan konversi gambar dari format BGR (Blue-Green-Red) ke format Grayscale. Sedangkan pada baris ke-11, kita melakukan operasi Gaussian Blur untuk menyamarkan noise pada gambar.

edges = cv2.Canny(image_gray, 20, 60)
contours, _ = cv2.findContours(edges, mode=cv2.cv.CV_RETR_EXTERNAL,
                                   method=cv2.cv.CV_CHAIN_APPROX_SIMPLE)

Pada baris ke-14, kita melakukan operasi Canny untuk deteksi tepi. Sedangkan pada baris ke 15, dari hasil edges yang telah didapatkan sebelumnya, dicari contour terluar dengan menggunakan fungsi findContours pada OpenCV.

cv2.drawContours(edges, contours, -1, 255, 2)
inv_edges = cv2.bitwise_not(edges)
retval, rect = cv2.floodFill(inv_edges, None, (0, 0), 0)
mask = cv2.bitwise_or(edges, inv_edges)

Baris ke-19 hingga 22 adalah inti dari proses segmentasi. Ide dasar dari proses segmentasi ini adalah dengan mencari tepi terluar pada objek, dengan begitu kita dapat memastikan bahwa area di dalam garis terluar tersebut adalah area objek. Sedangkan area yang ada di luar dari garis terluar objek dikategorikan sebagai background.

Untuk melakukan hal tersebut, terlebih dahulu kita memperbesar ukuran tebal garis dengan cara menggambar ulang contours pada matriks edges (baris ke-19). Hal ini dilakukan untuk mengurangi efek adanya garis yang tidak terdeteksi sehingga mengakibatkan garis terluar tersebut tidak membentuk objek yang tertutup (closed edges). Pada baris ke-20, kita melakukan operasi inverse pada matriks edges. Setelah itu pada baris ke-21, kita melakukan operasi floodFill, yaitu mengisi seluruh area terluar objek dengan nilai tertentu. Dalam hal ini kita warnai area tersebut dengan nilai 0 (hitam). Dari operasi ini didapatkan area bernilai 255 (warna putih) hanya pada bagian dalam objek saja. Langkah terakhir adalah dengan menggabungkan tepi terluar objek dengan bagian dalam objek, yaitu dengan menggunakan operasi bitwise_or pada baris ke-22. Hasil dari operasi ini kita dapatkan mask objek pada gambar.

Langkah berikutnya adalah melakukan masking pada gambar asli untuk menghasilkan gambar dengan background yang telah dihilangkan.

result = np.zeros(image.shape, dtype='uint8')
result[mask > 0, :] = image[mask > 0, :]

Terlebih dahulu kita membuat matriks dengan ukuran yang sama dengan gambar asli dan kita isi matriks tersebut dengan nilai 0 (warna hitam). Setelah itu operasi masking dilakukan untuk menghasilkan gambar hasil (baris ke-26).

Untuk ilustrasi masing – masing tahapan bisa dilihat pada gambar di bawah ini:

segmentation_steps

step-by-step segmentation process

Sekian tulisan ini, semoga bermanfaat.

Iklan

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s