Skip to content

Instantly share code, notes, and snippets.

@Outsiders17711
Last active September 6, 2021 06:07
Show Gist options
  • Save Outsiders17711/6c6236b12e0ab97586e8bd39bf16658b to your computer and use it in GitHub Desktop.
Save Outsiders17711/6c6236b12e0ab97586e8bd39bf16658b to your computer and use it in GitHub Desktop.
This code below fixes the bug where the program crashes if the zoomed image moves out of the webcam image's bounds. The zoomed image slice is updated to show the visible part.
# %%
# [Virtual Zoom Gesture using OpenCV Python | CVZone](https://www.youtube.com/watch?v=VPaFV3QBsEw)
# --- Murtaza Hassan ---
# Code & Resources: n/a
# %%
# [start]____________________________________________________________
import cv2 as cv
from cvzone.HandTrackingModule import HandDetector
cap = cv.VideoCapture(0, cv.CAP_DSHOW)
cap.set(cv.CAP_PROP_FRAME_HEIGHT, 720)
cap.set(cv.CAP_PROP_FRAME_WIDTH, 1280)
detector = HandDetector(detectionCon=0.7)
initialDist = None
scale, scale_buffer = -100, 2
cx = int(cap.get(cv.CAP_PROP_FRAME_WIDTH) / 2)
cy = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT) / 2)
while True:
success, imgw = cap.read()
imgw = cv.flip(imgw, 1)
imgz = cv.imread(r"resources/pc.jpg")
allHands, imgw = detector.findHands(imgw, flipType=True, draw=False)
if len(allHands) == 2:
fingers = detector.fingersUp(allHands[0]), detector.fingersUp(allHands[1])
# print(fingers)
if fingers[0] == fingers[1] == [1, 1, 0, 0, 0]:
lmlist0 = allHands[0]["lmList"]
lmlist1 = allHands[1]["lmList"]
if initialDist is None:
# find the distance between the index fingers
indexDists = detector.findDistance(lmlist0[8], lmlist1[8])[0]
initialDist = indexDists
indexDists, info = detector.findDistance(lmlist0[8], lmlist1[8])[:2]
scale = int((indexDists - initialDist) // scale_buffer)
cx, cy = info[4:]
else:
# reset the initial index fingers distance
initialDist = None
# the new height and width is being divided and multiplied by 2 consecutively to prevent the loss of single pixels if the new values are odd
# losing pixels gives error such as below when slicing `imgz` with `imgw`:
# ValueError: could not broadcast input array from shape (447,661,3) into shape (446,660,3)
izh, izw = imgz.shape[:2]
n_izh, n_izw = ((izh + scale) // 2) * 2, ((izw + scale) // 2) * 2
imgz = cv.resize(imgz, dsize=(n_izw, n_izh))
# [start slicing]____________________________________________________________
# [BUG FIXED!!] the code below fixes the bug where the program crashes if the zoomed image moves out of the webcam image's bounds
# the zoomed image slice is updated to show the visible part
#
imgw_h_s = cy - n_izh // 2
imgz_h_s = 0
if imgw_h_s < 0:
imgz_h_s = abs(imgw_h_s)
imgw_h_s = 0
#
imgw_h_e = cy + n_izh // 2
imgz_h_e = n_izh
if imgw_h_e > imgw.shape[0]:
imgz_h_e -= imgw_h_e - imgw.shape[0]
imgw_h_e = imgw.shape[0]
#
imgw_w_s = cx - n_izw // 2
imgz_w_s = 0
if imgw_w_s < 0:
imgz_w_s = abs(imgw_w_s)
imgw_w_s = 0
#
imgw_w_e = cx + n_izw // 2
imgz_w_e = n_izw
if imgw_w_e > imgw.shape[1]:
imgz_w_e -= imgw_w_e - imgw.shape[1]
imgw_w_e = imgw.shape[1]
#
# print(imgw_h_s, imgw_h_e, imgw_w_s, imgw_w_e)
# print(imgz_h_s, imgz_h_e, imgz_w_s, imgz_w_e)
#
imgw[imgw_h_s:imgw_h_e, imgw_w_s:imgw_w_e] = imgz[
imgz_h_s:imgz_h_e, imgz_w_s:imgz_w_e
]
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-[end slicing]
cv.imshow("Virtual Zoom Gesture", imgw)
cv.moveWindow("Virtual Zoom Gesture", 0, 0)
if cv.waitKey(1) & 0xFF in [27, 32]:
break
cap.release()
cv.destroyAllWindows()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment