Object Tracking

Latifa Ega Nadhira
6 min readJan 11, 2021

--

Deteksi objek berdasarkan warna HSV menggunakan python dan OpenCV

Assalamualaikum wr.wb.

Pada kesempatan kali ini saya akan mencoba membuat object tracking atau deteksi objek dengan warna menggunakan python dan OpenCV. Tujuan yang diinginkan adalah mendeteksi keberadaan objek dengan warna hijau. Disini saya menggunakan python 3.8.6 dan text editor SublimeText.

Langkah awal yang dilakukan adalah install OpenCV dengan mengetik perintah berikut pada command prompt.

py -m pip install opencv-python

Kemudian install modul yang diperlukan yaitu argparse,

py -m pip install argparse

Dan juga modul imutils.

py -m pip install imutils

Setelah berhasil, buat coding seperti berikut. Coding ini dapat mendeteksi objek melalui webcam dan video dalam folder.

from collections import deque
from imutils.video import VideoStream
import numpy as np
import argparse
import cv2
import imutils
import time
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=64,
help="max buffer size")
args = vars(ap.parse_args())

Line(1)-(7) adalah import modul yang akan digunakan. Line(9)-(14) adalah argumen. Terdapat 2 pilihan argumen, yang pertama adalah “ — video” jika tersedia, maka OpenCV akan membaca frame dari video tersebut, jika tidak maka OpenCV akan mengakses webcam atau kamera komputer. Argumen kedua yaitu ”- -buffer” adalah ukuran maksimal dari “deque”, jika titik yang dideteksi sedikit maka garis tracking akan lebih pendek, sedangkan jika titik semakin banyak maka garis tracking semakin panjang. Perintah selanjutnya adalah seperti berikut.

greenLower = (29, 86, 6)
greenUpper = (64, 255, 255)
pts = deque(maxlen=args["buffer"])
if not args.get("video", False):
vs = VideoStream(src=0).start()
else:
vs = cv2.VideoCapture(args["video"])
time.sleep(2.0)

Line(15)-(16) tersebut mendefinisikan batas atas dan batas bawah warna hijau yang akan dideteksi dalam satuan HSV. Line(17) memberikan nilai pada “deque” dengan maksimal ukuran buffer yaitu 64 (default). Line(18)-(19) adalah perintah membaca webcam jika tidak tersedia video. Namun jika tersedia video maka sistem akan membacanya melalui perintah line(20)-(21). Selanjutnya adalah coding untuk proses looping (pengulangan).

while True:
frame = vs.read()
frame = frame[1] if args.get("video", False) else frame
if frame is None:
break
frame = imutils.resize(frame, width=600)
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, greenLower, greenUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
center = None
if len(cnts) > 0:
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
if radius > 10:
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
pts.appendleft(center)
for i in range(1, len(pts)):
if pts[i - 1] is None or pts[i] is None:
continue
thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)
cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break

Line(23) memulai proses looping dan line(55)-(56) mengakhiri looping jika menekan huruf q atau jika video sudah selesai. Line(26)-(27) adalah perintah mengakhiri looping jika frame tidak dapat membaca video. Line(28)-(30) mengatur ukuran frame yaitu lebar 600px agar mempercepat proses, membuat tampilan menjadi buram agar dapat fokus pada objek yang dideteksi, dan mengkonversi warna HSV. Line(31) untuk mengatur batas-batas warna HSV yang akan dideteksi. Line(36)-(47) adalah perintah untuk mengatur kontur objek yang akan dideteksi. Line(48) memulai looping untuk menggambar contrail dari objek. Jika objek tidak terdeteksi maka akan diabaikan dan melanjutkan looping. Line(51)-(52) mengatur ketebalan contrail dan menggambarnya dalam frame.

Secara keseluruhan coding yang digunakan adalah berikut.

from collections import deque
from imutils.video import VideoStream
import numpy as np
import argparse
import cv2
import imutils
import time
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=64,
help="max buffer size")
args = vars(ap.parse_args())
greenLower = (29, 86, 6)
greenUpper = (64, 255, 255)
pts = deque(maxlen=args["buffer"])
if not args.get("video", False):
vs = VideoStream(src=0).start()
else:
vs = cv2.VideoCapture(args["video"])
time.sleep(2.0)
while True:
frame = vs.read()
frame = frame[1] if args.get("video", False) else frame
if frame is None:
break
frame = imutils.resize(frame, width=600)
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, greenLower, greenUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
center = None
if len(cnts) > 0:
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
if radius > 10:
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
pts.appendleft(center)
for i in range(1, len(pts)):
if pts[i - 1] is None or pts[i] is None:
continue
thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)
cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
if not args.get("video", False):
vs.stop()
else:
vs.release()
cv2.destroyAllWindows()

Tampilan pada SublimeText seperti berikut.

Simpan dengan nama file ball.py ke dalam folder E:\ball.

Untuk percobaan ini, saya menggunakan video dari youtube Green Ball Adventure yang dapat dilihat pada link ini. Video tersebut disimpan pada folder ball dengan nama ball.mp4.

Kemudian, jalankan file dengan perintah berikut pada command prompt.

E:\ball\ball.py -v ball.mp4

Maka akan muncul frame seperti berikut.

Bola hijau tersebut dapat terdeteksi dengan baik, dan terdapat contrail merah yang mengikutinya.

Jika ingin mengganti warna objek dapat dilakukan perubahan pada line(15)-(16) seperti berikut untuk warna biru.

blueLower = (94, 80, 2)
blueUpper = (126, 255, 255)

Dan pada line(31) menjadi :

mask = cv2.inRange(hsv, blueLower, blueUpper)

Secara keseluruhan sebagai berikut.

from collections import deque
from imutils.video import VideoStream
import numpy as np
import argparse
import cv2
import imutils
import time
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help="e:\\ball\\")
ap.add_argument("-b", "--buffer", type=int, default=64,
help="max buffer size")
args = vars(ap.parse_args())
blueLower = (94, 80, 2)
blueUpper = (126, 255, 255)
pts = deque(maxlen=args["buffer"])
if not args.get("video", False):
vs = VideoStream(src=0).start()
else:
vs = cv2.VideoCapture(args["video"])
time.sleep(2.0)
while True:
frame = vs.read()
frame = frame[1] if args.get("video", False) else frame
if frame is None:
break
frame = imutils.resize(frame, width=600)
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, blueLower, blueUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
center = None
if len(cnts) > 0:
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
if radius > 10:
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
pts.appendleft(center)
for i in range(1, len(pts)):
if pts[i - 1] is None or pts[i] is None:
continue
thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)
cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
if not args.get("video", False):
vs.stop()
else:
vs.release()
cv2.destroyAllWindows()

Simpan dengan file baru blue.py pada folder E:\ball. Kemudian untuk video yang akan digunakan adalah video dari youtube Blue Ball Adventure yang disimpan pada folder E:\ball dengan nama file blue.mp4.

Jalankan file pada command prompt dengan perintah berikut.

E:\ball\blue.py -v blue.mp4

Hasilnya adalah seperti berikut.

Jika ingin mencoba warna lain, dapat diubah pada line(15)-(16) dan (31) seperti tadi.

Selanjutnya, coding ini juga dapat mendeteksi objek warna dari webcam. Cara menjalankan file pada command prompt menggunakan perintah berikut.

E:\ball\ball.py

Saya coba menggunakan gambar bola hijau dari HP dan hasilnya dapat dideteksi seperti berikut.

Untuk deteksi objek warna biru, jalankan perintah berikut pada command prompt.

E:\ball\blue.py

Saya menggunakan benda disekitar yang berwarna biru, dan hasilnya benda dapat dideteksi seperti berikut.

Sekian yang dapat saya sampaikan mengenai Object Detection ini, terima kasih telah mengikuti sampai akhir.

Wassalamualaikum wr. wb.

Referensi:

https://pysource.com/2019/02/15/detecting-colors-hsv-color-space-opencv-with-python/
https://www.pyimagesearch.com/2015/09/14/ball-tracking-with-opencv/

--

--

Latifa Ega Nadhira
Latifa Ega Nadhira

Written by Latifa Ega Nadhira

Statistika — Universitas Islam Indonesia

No responses yet