RGB Color Threshold

Dengan menggunakan color threshold, kita bisa memilih area tertentu pada sebuah image. Memilih area of intesrest adalah salah satu contoh dalam computer vision pipeline.

Berikut contoh penggunaan color threshold adalah blue screen background untuk memisahkan object/subject dari background dalam Python dan OpenCV.

TIPS: Untuk memudahkan latihan, gunakan jupyter notebook.

Image untuk tutorial, bisa download di https://drive.google.com/file/d/18AOdUcvAwNn0omikrQYaWqH5om4oWOcR/view?usp=sharing

Atau ada bisa menggunakan image sendiri, selama background nya berwarna hijau.

Pertama import library yang digunakan yaitu matplotlib, numpy dan cv2 (openCV).

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

Load image, perintah print untuk melihat ukuran image yang akan digunakan untuk croping background image.

Dari perintah shape, dapat diketahui ukuran gambar adalah 720 x 1280 dengan 3 komponen warna.

img = cv2.imread('green-screen.jpg')
print('Type: ', type(img), 'Dimension: ', img.shape)
Type:  <class 'numpy.ndarray'> Dimension:  (720, 1280, 3)

Adalah kebiasan baik untuk mengcopy data, untuk mecegah kerusakan pada file asli. Gunakan np.copy() untuk mengcopy image.

Lalu gunakan perintah cvtColor() untuk mengganti profile dari BGR ke RGB. OpenCV menggunakan profile BGR (Blue Green Red), sementara semua image menggunakan profle RGB.

%matplotlib inline

img_copy = np.copy(img)
img_copy = cv2.cvtColor(img_copy, cv2.COLOR_BGR2RGB)
plt.imshow(img_copy)

Berikutnya kita tentukan threshold untuk warna hijau background. Urutannya adalah RGB, jadi array pertama bernilai hijau 230, red dan blue 0. Sama halnya dengan array yang kedua.

low_green = np.array([0, 230, 0])
upp_green = np.array([200, 255, 240])

#jika background biru, gunakan threshold seperti berikut.
#low_blue = np.array([0, 0, 230])
#upp_blue = np.array([200, 200, 255])

Buat masking dengan fungsi cv2.inRange dengan parameter threshold diatas.

Terlihat dari gambar dibawah, warna background berhasil kita pilih. Anda bisa tuning nilai low_green dan upp_green agar hasil masking lebih baik.

mask = cv2.inRange(img_copy, low_green, upp_green)
plt.imshow(mask, cmap='gray')

Code dibawah adalah proses mengisi background dengan warna hitam. Pertama copy dulu kedalam file baru yaitu masked_img.

Kemudian isi area background dengan warna hitam dengan memberi nilai [0, 0, 0] yaitu dimana mask != 0.

masked_img = np.copy(img_copy)
masked_img[mask != 0] = [0, 0, 0]
plt.imshow(masked_img)

Berikutnya kita load background image, lalu ganti profile menjadi RGB.

bg_img = cv2.imread('bg01.jpg')
bg_img = cv2.cvtColor(bg_img, cv2.COLOR_BGR2RGB)

Jika kita cek, shape dari image background dan image wanita dengan background hijau berbeda

bg_img.shape
(900, 1440, 3)

Crop image dengan perintah berikut. Nilai 720 dan 1280 adalah ukuran tinggi x lebar dari image wanita dengan background hijau.

crop_bg = bg_img[0:720, 0:1280]

Untuk Background image, area yang dimasking adalah dimana wanita pada gambar diatas berdiri. Yaitu dimana nilai mask = 0.

Lalu kita gabungkan kedua image tersebut dengan operasi matematik biasa. Karena pada dasarnya, kedua gambar tersebut adalah array 2 dimensi yang memilki ukuran yang sama.

crop_bg[mask == 0] = [0, 0, 0]

fin_img = crop_bg + masked_img
plt.imshow(fin_img)

Dengan contoh sederhana ini, kita sudah melakukan latihan menggunakan color threshold untuk mendapatkan area of interest.

Kesimpulan

Pendekatan ini masih ada kelemahan, kondisi gambar diatas sudah disiapkan dengan baik, jadi subject bisa dipisahkan dari background dengan cukup mudah dan cukup baik.

Jika lighting background tidak merata dan terdapat shadow, pendekatan diatas tidak akan dapat memisahkan subject dan background dengna baik.

Berikut isi keseluruhan program sederhana diatas

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

img = cv2.imread('green-screen.jpg')
print('Type: ', type(img), 'Dimension: ', img.shape)

%matplotlib inline
img_copy = np.copy(img)
img_copy = cv2.cvtColor(img_copy, cv2.COLOR_BGR2RGB)
plt.imshow(img_copy)

low_green = np.array([0, 230, 0])
upp_green = np.array([200, 255, 240])

mask = cv2.inRange(img_copy, low_green, upp_green)
plt.imshow(mask, cmap='gray')

masked_img = np.copy(img_copy)
masked_img[mask != 0] = [0, 0, 0]
plt.imshow(masked_img)

bg_img = cv2.imread('bg01.jpg')
bg_img = cv2.cvtColor(bg_img, cv2.COLOR_BGR2RGB)

crop_bg = bg_img[0:720, 0:1280]
crop_bg[mask == 0] = [0, 0, 0]

fin_img = crop_bg + masked_img
plt.imshow(fin_img)
Sharing is caring:

Leave a Comment