Python使用OpenCV實現(xiàn)虛擬縮放效果
介紹
OpenCV 徹底改變了整個圖像處理領(lǐng)域。從圖像分類到對象檢測,我們不僅可以使用 OpenCV 庫做一些很酷的事情,而且還可以構(gòu)建一流的應(yīng)用程序。
今天我們要實現(xiàn)一個有趣的東西,它是手機或電腦中的一種功能,即圖像縮放。但在這里,它將是實時對幀上所需的圖像進行虛擬縮放。
要求
對于這個項目,我們將使用 OpenCV 庫和另一個名為 Cvzone 的庫來使用虛擬縮放。
CVZone
它是一個建立在 OpenCV 和 MediaPipe 之上的庫。它使事情變得容易得多。
CVZone 具有一些非常有用的內(nèi)置功能,例如手部跟蹤、面部標志檢測、姿勢估計等等。這些都可以通過幾行代碼來完成。
讓我們編寫一段代碼來看看使用 CVZone 的手部檢測器的演示。首先,安裝 requirements 。你可以使用以下命令安裝它,也可以逐個安裝。
– pip install -r requirements.txt
或
– pip install opencv-python==3.4.11.43
– pip install cvzone==1.5.3
現(xiàn)在讓我們檢測手。
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 功能從網(wǎng)絡(luò)攝像頭獲取輸入。設(shè)置窗口的高度和寬度,并以一定的檢測置信度初始化手部檢測器模塊。
然后在循環(huán)內(nèi)部從網(wǎng)絡(luò)攝像頭讀取輸入幀并將其傳遞給手部檢測器模塊內(nèi)部的方法,即 findHands。顯示圖像。
與此類似,我們可以使用 CVZone 實現(xiàn)面部地標檢測、姿勢估計等。
目標
我們的目標是構(gòu)建一個屏幕上有圖像的項目,使用 OpenCV 進行虛擬縮放,并使用我們的手勢,即如果雙手的食指和拇指向上并且兩根手指彼此遠離,就放大,如果雙手的食指和拇指向上并且兩根手指彼此靠近,則縮小該圖像或?qū)ο蟆@斡涍@一點,我們將制定一些步驟。
步驟
初始化來自網(wǎng)絡(luò)攝像頭的輸入。
設(shè)置輸出窗口的高度和寬度。
初始化手部檢測器模塊。
分別聲明計算距離、縮放范圍、中心X和中心Y的4個變量。
讀取輸入幀。
檢測雙手。
讀取用于縮放操作的圖像。
檢查是否檢測到兩只手。
檢查食指和拇指是否向上。
計算兩只手之間的距離,并將圖像調(diào)整到兩只手的中心。
計算新的高度和寬度,然后調(diào)整圖像大小。
顯示輸出。
構(gòu)建
如上一節(jié)所述安裝所需的庫?,F(xiàn)在讓我們開始吧。
首先,導入所需的模塊。這里我們只需要 cv2 和 cvzone 的手部檢測器模塊。
導入庫后,使用 cv2.VideoCapture(0) 從網(wǎng)絡(luò)攝像頭獲取輸入,其中 0 是網(wǎng)絡(luò)攝像頭 ID。
然后設(shè)置輸出窗口的寬度和高度。這里是 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)
現(xiàn)在,我們將初始化手檢測模塊(handDetector),檢測置信度為 0.8,并將在 while 循環(huán)中用于檢測手。
聲明 4 個變量,一個是初始存儲距離,它是None,一個是縮放范圍,初始是0,另外 2 個用于捕捉縮放對象的中心 X 和中心 Y,并設(shè)置一些隨機值。
這里代碼中的變量分別是 distStart、zoom_range、cx、cy。
# initialize hand detector module handDetector = HandDetector(detectionCon=0.8) distStart = None zoom_range = 0 cx, cy = 500, 500
開始一個while循環(huán),從現(xiàn)在開始,一切操作都應(yīng)該在這個循環(huán)中。
從網(wǎng)絡(luò)攝像頭讀取輸入,并使用上面初始化的手部檢測器模塊,我們可以調(diào)用方法 findHands 將幀作為輸入傳遞。此方法會在框架中找到手,默認它可以檢測框架中的兩只手并返回手的列表。
我們可以從中訪問每只檢測到的手(這里:一只手為hands[0],另一只手為hands[1]),并且它還返回圖像。然后我們將使用 OpenCV 的 imread() 函數(shù)讀取屏幕上要縮放的圖像。最好圖像大小應(yīng)低于 (250, 250),否則你可以使用 cv2.resize(img, (250,250)) 調(diào)整其大小。這里圖像大小為 (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')
現(xiàn)在,我們需要檢查框架中是否有兩只手,然后我們將檢查食指和拇指是否向上,這可以使用手檢測模塊中的 FingerUp() 方法輕松完成。
在下面的第一個 if 語句之后的代碼中,我們將使用兩個打印語句 print(handDetector.fingersUp(hands[0])) ,如果食指和拇指向上,則這將打印一個包含 5 個元素的列表,結(jié)果列表顯示一只手將是 [1, 1, 0, 0, 0],另一只手類似地執(zhí)行 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]))
然后是重要的部分,現(xiàn)在我們需要檢查雙手的食指和拇指是否向上。我們將再次使用 if 語句(在第一個 if 語句中:if handDetector.fingersUp(hands[0]) == [1, 1, 0, 0, 0] 和 handDetector.fingersUp(hands[1]) == [ 1, 1, 0, 0, 0]:) 然后求兩只手之間的距離,具體來說就是食指兩點之間的距離。
在下面的代碼中,findDistance() 方法將找到距離,這里我們將兩只手的中心作為參數(shù)與框架一起傳遞。findDistance() 方法將返回三個項目距離,一個包含位置 4 和 5 的中心 X 和中心 Y 的元組以及圖像。
如果僅當 distStart 為 None 時才執(zhí)行條件,則將獲得的距離分配給我們之前聲明的第三個變量 distStart。然后,計算新距離并從舊距離 distStart 中減去它,并執(zhí)行除以 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
然后獲取要放大的圖像的高度和寬度,并計算圖像的新高度和寬度。這有點棘手,要獲得新的高度和寬度,我們需要將圖像之前的高度和寬度添加到縮放范圍并執(zhí)行向下取整除法,然后乘以 2。
然后我們可以動態(tài)找到放置縮放的位置圖像(這里: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 中找到
結(jié)論
這就是這篇關(guān)于使用 OpenCV 進行虛擬縮放的博客的內(nèi)容。如果你想即興發(fā)揮,讓它更有趣,你可以在屏幕上保留一些圖像,每次選擇一個并放大它,或者你可以創(chuàng)建不同的形狀,使用不同的手勢來讓它變大或變小。這就是我們?nèi)绾问褂?OpenCV 實現(xiàn)虛擬縮放。
到此這篇關(guān)于Python使用OpenCV實現(xiàn)虛擬縮放效果的文章就介紹到這了,更多相關(guān)Python OpenCV虛擬縮放內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python閉包之返回函數(shù)的函數(shù)用法示例
這篇文章主要介紹了 Python閉包之返回函數(shù)的函數(shù)用法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01Python實現(xiàn)FTP上傳文件或文件夾實例(遞歸)
本篇文章主要介紹了Python實現(xiàn)FTP上傳文件或文件夾實例(遞歸),具有一定的參考價值,有興趣的可以了解一下。2017-01-01Python實現(xiàn)暴力破解wifi密碼并打包成exe
python號稱是編程界的萬金油,那么是否可以做個讀取電腦網(wǎng)卡wifi并暴力破解的小腳本呢?在這個基礎(chǔ)上為了方便體驗是不是可以將其打包成exe這樣方便執(zhí)行的小應(yīng)用呢?本文就來和大家一起聊聊2022-09-09基于Python中isfile函數(shù)和isdir函數(shù)使用詳解
今天小編就為大家分享一篇基于Python中isfile函數(shù)和isdir函數(shù)使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11python機器基礎(chǔ)邏輯回歸與非監(jiān)督學習
這篇文章主要為大家介紹了python機器基礎(chǔ)邏輯回歸與非監(jiān)督的學習講解u,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2021-11-11