介紹
OpenCV 徹底改變了整個影像處理領域,從影像分類到物件檢測,我們不僅可以使用 OpenCV 庫做一些很酷的事情,而且還可以構建一流的應用程式,
今天我們要實作一個有趣的東西,它是手機或電腦中的一種功能,即影像縮放,但在這里,它將是實時對幀上所需的影像進行虛擬縮放,
目錄
要求
目的
構建
結論
要求
對于這個專案,我們將使用 OpenCV 庫和另一個名為 Cvzone 的庫來使用虛擬縮放,
CVZone
它是一個建立在 OpenCV 和 MediaPipe 之上的庫,它使事情變得容易得多,
CVZone 具有一些非常有用的內置功能,例如手部跟蹤、面部標志檢測、姿勢估計等等,這些都可以通過幾行代碼來完成,
讓我們撰寫一段代碼來看看使用 CVZone 的手部檢測器的演示,首先,安裝 requirements ,你可以使用以下命令安裝它,也可以逐個安裝,
– pip install -r requirements.txt
或
– pip install opencv-python==3.4.11.43
– pip install cvzone==1.5.3
現在讓我們檢測手,
import cv2
from cvzone.HandTrackingModule import HandDetector
# Input from webcam
frame = cv2.VideoCapture(0)
frame.set(3, 1280)
frame.set(4, 720)
# initialize hand detector module with some confidence
handDetector = HandDetector(detectionCon=0.8)
# loop
while True:
# Read the frames from webcam
res, img = frame.read()
# detect the hands, by default it will detect two hands
hands = handDetector.findHands(img)
# show the output
cv2.imshow(“Sample CVZone output”, img)
cv2.waitKey(1)
首先,讓我們匯入所需的模塊,cv2,以及從 cvzone.HandTrackingModule 匯入HandDetector*,*
然后我們將使用 OpenCV 的 Videocapture 功能從網路攝像頭獲取輸入,設定視窗的高度和寬度,并以一定的檢測置信度初始化手部檢測器模塊,
然后在回圈內部從網路攝像頭讀取輸入幀并將其傳遞給手部檢測器模塊內部的方法,即 findHands,顯示影像,

與此類似,我們可以使用 CVZone 實作面部地標檢測、姿勢估計等,
目標
我們的目標是構建一個螢屏上有影像的專案,使用 OpenCV 進行虛擬縮放,并使用我們的手勢,即如果雙手的食指和拇指向上并且兩根手指彼此遠離,就放大,如果雙手的食指和拇指向上并且兩根手指彼此靠近,則縮小該影像或物件,牢記這一點,我們將制定一些步驟,
步驟
初始化來自網路攝像頭的輸入,
設定輸出視窗的高度和寬度,
初始化手部檢測器模塊,
分別宣告計算距離、縮放范圍、中心X和中心Y的4個變數,
讀取輸入幀,
檢測雙手,
讀取用于縮放操作的影像,
檢查是否檢測到兩只手,
檢查食指和拇指是否向上,
計算兩只手之間的距離,并將影像調整到兩只手的中心,
計算新的高度和寬度,然后調整影像大小,
顯示輸出,

構建
如上一節所述安裝所需的庫,現在讓我們開始吧,
首先,匯入所需的模塊,這里我們只需要 cv2 和 cvzone 的手部檢測器模塊,
匯入庫后,使用 cv2.VideoCapture(0) 從網路攝像頭獲取輸入,其中 0 是網路攝像頭 ID,
然后設定輸出視窗的寬度和高度,這里是 1280 x 720,
import cv2
from cvzone.HandTrackingModule import HandDetector
# Input from webcam
frame = cv2.VideoCapture(0)
frame.set(3, 1280)
frame.set(4, 720)
現在,我們將初始化手檢測模塊(handDetector),檢測置信度為 0.8,并將在 while 回圈中用于檢測手,
宣告 4 個變數,一個是初始存盤距離,它是None,一個是縮放范圍,初始是0,另外 2 個用于捕捉縮放物件的中心 X 和中心 Y,并設定一些隨機值,
這里代碼中的變數分別是 distStart、zoom_range、cx、cy,
# initialize hand detector module
handDetector = HandDetector(detectionCon=0.8)
distStart = None
zoom_range = 0
cx, cy = 500, 500
開始一個while回圈,從現在開始,一切操作都應該在這個回圈中,
從網路攝像頭讀取輸入,并使用上面初始化的手部檢測器模塊,我們可以呼叫方法 findHands 將幀作為輸入傳遞,此方法會在框架中找到手,默認它可以檢測框架中的兩只手并回傳手的串列,
我們可以從中訪問每只檢測到的手(這里:一只手為hands[0],另一只手為hands[1]),并且它還回傳影像,然后我們將使用 OpenCV 的 imread() 函式讀取螢屏上要縮放的影像,最好影像大小應低于 (250, 250),否則你可以使用 cv2.resize(img, (250,250)) 調整其大小,這里影像大小為 (225, 225),
while True:
# Read the input frame
res, img = frame.read()
# Detect the hands
hands, img = handDetector.findHands(img)
# Image to be zoomed
new_img = cv2.imread('resized_test.jpg')
現在,我們需要檢查框架中是否有兩只手,然后我們將檢查食指和拇指是否向上,這可以使用手檢測模塊中的 FingerUp() 方法輕松完成,
在下面的第一個 if 陳述句之后的代碼中,我們將使用兩個列印陳述句 print(handDetector.fingersUp(hands[0])) ,如果食指和拇指向上,則這將列印一個包含 5 個元素的串列,結果串列顯示一只手將是 [1, 1, 0, 0, 0],另一只手類似地執行 print(handDetector.fingersUp(hands[1])),
請參考下圖,
# if two hands are detected
if len(hands) == 2:
print("Start Zoom...")
print(handDetector.fingersUp(hands[0]))
print(handDetector.fingersUp(hands[1]))

然后是重要的部分,現在我們需要檢查雙手的食指和拇指是否向上,我們將再次使用 if 陳述句(在第一個 if 陳述句中:if handDetector.fingersUp(hands[0]) == [1, 1, 0, 0, 0] 和 handDetector.fingersUp(hands[1]) == [ 1, 1, 0, 0, 0]:) 然后求兩只手之間的距離,具體來說就是食指兩點之間的距離,
在下面的代碼中,findDistance() 方法將找到距離,這里我們將兩只手的中心作為引數與框架一起傳遞,findDistance() 方法將回傳三個專案距離,一個包含位置 4 和 5 的中心 X 和中心 Y 的元組以及影像,
如果僅當 distStart 為 None 時才執行條件,則將獲得的距離分配給我們之前宣告的第三個變數 distStart,然后,計算新距離并從舊距離 distStart 中減去它,并執行除以 2 (向下取整)以獲得縮放范圍,然后將中心坐標分配給變數cx,cy,然后,如果框架中沒有兩只手,則將 distStart 變數重置為 None,

if handDetector.fingersUp(hands[0]) == [1, 1, 0, 0, 0] and handDetector.fingersUp(hands[1]) == [1, 1, 0, 0, 0]:
# print("Start Zoom...")
lmList1 = hands[0]['lmList']
lmList2 = hands[1]['lmList']
# point 8 is tip of the index finger
if distStart is None:
# length, info, img = handDetector.findDistance(lmList1[8], lmList2[8], img)
# draw the connection points between right hand index and thum finger to left hand
length, info, img = handDetector.findDistance(hands[0]['center'], hands[1]['center'], img)
# print(length)
distStart = length
# length, info, img = handDetector.findDistance(lmList1[8], lmList2[8], img)
length, info, img = handDetector.findDistance(hands[0][‘center’], hands[1][‘center’], img)
# info gives center x and center y
# calculate the zoom range
zoom_range = int((length – distStart) // 2)
# calculate the center point so that we can place the zooming image at the center
cx, cy = info[4:] print(zoom_range)
else:
distStart = None
然后獲取要放大的影像的高度和寬度,并計算影像的新高度和寬度,這有點棘手,要獲得新的高度和寬度,我們需要將影像之前的高度和寬度添加到縮放范圍并執行向下取整除法,然后乘以 2,
然后我們可以動態找到放置縮放的位置影像(這里:img[cy – newH // 2:cy + newH // 2, cx – newW // 2:cx + newW // 2]),
但是還有一個問題,如果縮放后的影像低于視窗邊距,則會出錯,為了解決這個問題,我們將使用 try 和 except,然后顯示輸出,
try:
h, w, _ = new_img.shape
# new height and new width
newH, newW = ((h + zoom_range) // 2) * 2, ((w + zoom_range) // 2) * 2
new_img = cv2.resize(new_img, (newW, newH))
# we want the zooming image to be center and place it approx at the center
img[cy – newH // 2:cy + newH // 2, cx – newW // 2:cx + newW // 2] = new_img
except:
pass
# display output
cv2.imshow(‘output’, img)
cv2.waitKey(1)
完整的代碼也可以在這個 GitHub 中找到:
https://github.com/BakingBrains/Virtual_Zoom_usinf_OpenCV.git
結論
這就是這篇關于使用 OpenCV 進行虛擬縮放的博客的內容,如果你想即興發揮,讓它更有趣,你可以在螢屏上保留一些影像,每次選擇一個并放大它,或者你可以創建不同的形狀,使用不同的手勢來讓它變大或變小,這就是我們如何使用 OpenCV 實作虛擬縮放,
參考:
[1]. https://github.com/cvzone/cvzone
# https://en.wikipedia.org/wiki/OpenCV
☆ END ☆
如果看到這里,說明你喜歡這篇文章,請轉發、點贊,微信搜索「uncle_pn」,歡迎添加小編微信「 woshicver」,每日朋友圈更新一篇高質量博文,
↓掃描二維碼添加小編↓

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/435440.html
標籤:AI
上一篇:python 資料可視化01
