我是python和opencv的新手,并尝试使用opencv跟踪API开发一个简单的对象跟踪GUI。我正在使用我的网络摄像头进行测试。我的目的是在当前帧中选择目标对象。为此,我在窗口的中心绘制一个矩形,并参考矩形选择目标对象。由于矩形形状可能无法跟踪操作,因此我想从原始帧中选择目标对象。在代码中我创建了两个不同的框架,称为rawInp和outImage。 rawInp是输入视频。 outImage是最终结果,我希望所有形状都绘制在此图像中。我使用外部函数绘制矩形。我还会显示rawInp来检查它。但是,我在此输出中也看到了矩形形状。怎么可能,我该如何解决这个问题?另外,如何只对两个操作使用rawInp变量?因为复制相同的变量不是一个好办法。我正在添加我的代码的相关部分,但如果你想看到我可以添加的整个代码。提前感谢您的任何答案。
import sys
import cv2
import numpy as np
from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSlot, QTimer
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QDialog, QApplication, QFileDialog, QMainWindow
from PyQt5.uic import loadUi
cap = cv2.VideoCapture(0)
if not cap.isOpened(): print ("Could not open video") ,sys.exit()
ok, frame = cap.read(0)
height, width, channels = frame.shape
upper_left = (3*int(width/8), 3*int(height/8))
bottom_right = (5*int(width/8), 5*int(height/8))
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
class trackingApp(QMainWindow):
def __init__(self):
super(trackingApp,self).__init__()
loadUi('tracking_ui.ui',self)
self.rawInp = None
self.outImage = None
self.stBtclk = False
self.trckBtclk = False
self.startButton.clicked.connect(self.start_webcam)
self.trackingButton.clicked.connect(self.tracking_clicked)
@pyqtSlot()
def start_webcam(self):
self.stBtclk = True
self.capture = cv2.VideoCapture(0)
self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT,480)
self.capture.set(cv2.CAP_PROP_FRAME_WIDTH,620)
self.timer=QTimer(self)
self.timer.timeout.connect(self.update_frame)
self.timer.start(5)
def update_frame(self):
ret, self.rawInp = self.capture.read()
self.rawInp = cv2.flip(self.rawInp,1)
self.rawInp = cv2.cvtColor(self.rawInp, cv2.COLOR_BGR2GRAY)
self.rawInp = clahe.apply(self.rawInp)
self.rawInp = cv2.cvtColor(self.rawInp, cv2.COLOR_GRAY2BGR)
self.outImage = self.rawInp
if self.trckBtclk: self.tracker_update()
self.displayImage(self.outImage,1)
def plotCenter(self, outImage):
cv2.rectangle(outImage, upper_left, bottom_right, (0, 255, 0), 2)
# Plot the central horizontal and vertical lines
cv2.line(outImage,(50,int(height/2)),(width-50,int(height/2)),(0,255,0),1)
cv2.line(outImage,(int(width/2),50),(int(width/2),height-50),(0,255,0),1)
cv2.imshow('rawInp',self.rawInp)
@pyqtSlot()
def tracking_clicked(self):
if self.stBtclk:
self.trckBtclk = True
self.tracker = cv2.TrackerKCF_create()
bbox = (3*int(width/8), 3*int(height/8), 2*int(width/8), 2*int(height/8))
self.tracker.init(self.rawInp, bbox)
marker=self.rawInp[3*int(height/8):5*int(height/8), 3*int(width/8):5*int(width/8)]
self.surf = cv2.xfeatures2d.SURF_create(500)
kp, des = self.surf.detectAndCompute(marker,None)
marker = cv2.drawKeypoints(marker,kp,None,(0,0,255),4)
cv2.imshow("marker", marker)
else: pass
def tracker_update(self):
ok, bbox = self.tracker.update(self.outImage)
if ok:
# Tracking success
p1 = (int(bbox[0]), int(bbox[1]))
p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
cv2.rectangle(self.outImage, p1, p2, (0,255,255), 2, 1)
kp, des = self.surf.detectAndCompute(self.outImage,None)
# self.outImage = cv2.drawKeypoints(self.outImage,kp,None,(0,0,255),4)
cv2.putText(self.outImage, "Tracking", (5,20), cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,255,0),2)
else:
# Tracking failure
cv2.putText(self.outImage, "Tracking failure detected", (5,20), cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2)
def displayImage(self, outImage, window):
self.plotCenter(self.outImage)
qformat=QImage.Format_Indexed8
if len(outImage.shape)==3: #[0]=rows, [1]=columns, [2]=channels
if(outImage.shape[2])==4:
qformat=QImage.Format_RGBA8888
else:
qformat=QImage.Format_RGB888
outImg=QImage(outImage,outImage.shape[1],outImage.shape[0],outImage.strides[0],qformat)
outImg=outImg.rgbSwapped() #BRG>>RGB
if window==1:
self.trackingScreen.setPixmap(QPixmap.fromImage(outImg))
self.trackingScreen.setScaledContents(True)
if __name__=="__main__":
app = QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
window = trackingApp()
window.show()
#sys.exit(app.exec_())
app.exec_()
这是一个示例屏幕截图:
第一个窗口显示ui和最终输出,而第二个窗口名为" rawInp",显示未处理的输入视频。我不希望在第二个窗口看到绿色矩形