Python OpenCV Haar特征检测,仅限于Camshift跟踪区域

Python OpenCV Haar特征检测,仅限于Camshift跟踪区域,python,image-processing,opencv,computer-vision,Python,Image Processing,Opencv,Computer Vision,从一个视频文件开始,我逐帧扫描视频,直到使用OpenCV Haar frontal face cascade找到一张脸。然后,我将这些坐标传递给Camshift(使用OpenCV示例代码),以便从该帧开始跟踪该面。然后我在Camshift返回的跟踪框中使用Haar眼睛/嘴巴检测,假设这是我感兴趣的区域 当我这样做时,眼睛/嘴检测返回的结果很少/没有 如果我只是在视频中使用相同的眼睛和嘴巴检测器(不带Camshift)进行基本的运行,那么它们会检测眼睛和嘴巴(虽然通常将嘴巴检测为眼睛,反之亦然,但

从一个视频文件开始,我逐帧扫描视频,直到使用OpenCV Haar frontal face cascade找到一张脸。然后,我将这些坐标传递给Camshift(使用OpenCV示例代码),以便从该帧开始跟踪该面。然后我在Camshift返回的跟踪框中使用Haar眼睛/嘴巴检测,假设这是我感兴趣的区域

当我这样做时,眼睛/嘴检测返回的结果很少/没有

如果我只是在视频中使用相同的眼睛和嘴巴检测器(不带Camshift)进行基本的运行,那么它们会检测眼睛和嘴巴(虽然通常将嘴巴检测为眼睛,反之亦然,但检测效果仍比Camshift跟踪ROI方法好得多)

这与我的期望背道而驰——难道不应该将搜索限制在已知和跟踪人脸的ROI范围内,从而实现比对整个视频帧进行哑扫描更可靠的人脸特征检测吗?也许我的搜索坐标有点不合适

非常感谢您的帮助

将numpy导入为np
进口cv2
导入cv
从通用导入时钟,绘制
导入视频
类应用程序(对象):
定义初始化(自,视频):
如果视频_src==“网络摄像头”:
self.cam=video.create\u捕获(0)
其他:
self.vidFile=cv.CaptureFromFile('sources/'+video_src+'.mp4'))
self.vidFrames=int(cv.GetCaptureProperty(self.vidFile,cv.cv\u CAP\u PROP\u FRAME\u COUNT))
self.cascade\u fn=“haarcascade/haarcascade\u frontalface\u default.xml”
self.cascade=cv2.cascade分类器(self.cascade\u fn)
self.left\u eye\u fn=“haarcascades/haarcascade\u eye.xml”
self.left_eye=cv2.cascade分类器(self.left_eye\u fn)
self.mouth\u fn=“haarcascades/haarcascade\u mcs\u mouth.xml”
self.mouth=cv2.cascade分类器(self.mouth\u fn)
self.selection=None
self.drag\u start=None
self.tracking_state=0
self.show\u backproj=False
self.face\u frame=0
cv2.namedWindow(“camshift”)
cv2.namedWindow(“来源”)
#cv2.namedWindow(“历史”)
如果视频_src==“网络摄像头”:
尽管如此:
ret,img=self.cam.read()
self.rects=self.faceSearch(img)
打印“搜索人脸…”
如果len(self.rects)!=0:
打破
其他:
对于X范围内的f(自视频帧):
img=cv.QueryFrame(self.vidFile)
tmp=cv.CreateImage(cv.GetSize(img),8,3)
cv.CVT颜色(img、tmp、cv.cv_BGR2RGB)
img=np.asarray(cv.GetMat(tmp))
打印“搜索框”,f+1
self.face_frame=f
self.rects=self.faceSearch(img)
如果len(self.rects)!=0:
打破
def面部搜索(自我,img):
灰色=cv2.CVT颜色(img,cv2.COLOR\U BGR2GRAY)
灰色=cv2。均衡器历史(灰色)
rects=自检测(灰色、自级联)
如果len(rects)!=0:
打印“检测到的人脸”
sizeX=rects[0][2]-rects[0][0]
sizeY=rects[0][3]-rects[0][1]
打印“面大小为”,sizeX,“由”,sizeY
返回矩形
其他:
返回[]
def检测(自身、img、级联):
#标志=cv.cv\u HAAR\u比例\u图像
rects=cascade.detectMultiScale(img,scaleFactor=1.1,minNeighbors=2,minSize=(80,80),flags=cv.cv\u HAAR\u SCALE\u IMAGE)
如果len(rects)==0:
返回[]
rects[:,2:::+=rects[:,:2]
返回矩形
def绘制矩形(自身、img、矩形、颜色):
对于矩形中的x1、y1、x2、y2:
cv2.矩形(img,(x1,y1),(x2,y2),颜色,2)
def显示历史(自我):
bin_count=self.hist.shape[0]
bin_w=24
img=np.zero((256,bin_count*bin_w,3),np.uint8)
对于X范围内的i(料仓计数):
h=int(self.hist[i])
cv2.矩形(img,(i*bin_w+2255),((i+1)*bin_w-22555-h),(int(180.0*i/bin_计数),255,255),-1)
img=cv2.CVT颜色(img,cv2.COLOR_HSV2BGR)
cv2.imshow(“历史”,img)
cv.MoveWindow('hist',0440)
def faceTrack(自身、img):
vis=img.copy()
hsv=cv2.CVT颜色(img,cv2.COLOR\U BGR2HSV)
掩码=cv2.inRange(hsv,np.数组((0,60,32.)),np.数组((180,255,255.))
x0,y0,x1,y1=自矩形[0]
self.track_window=(x0,y0,x1-x0,y1-y0)
hsv_roi=hsv[y0:y1,x0:x1]
掩模_roi=掩模[y0:y1,x0:x1]
hist=cv2.calcHist([hsv_roi],[0],mask_roi,[16],[0180])
标准化(hist,hist,0,255,cv2.NORM\u MINMAX);
self.hist=历史重塑(-1)
#self.show_hist()
vis_roi=vis[y0:y1,x0:x1]
cv2.按位\u非(相对于roi,相对于roi)
vis[mask==0]=0
prob=cv2.calcBackProject([hsv],[0],self.hist[0180],1)
prob&=掩码
期限标准=(cv2.期限标准EPS | cv2.期限标准计数,10,1)
跟踪框,self.track\u窗口=cv2.CamShift(prob,self.track\u窗口,术语临界值)
如果self.show\u backproj:
vis[:]=prob[…,np.newaxis]
try:cv2.椭圆(可视,轨迹盒,(0,0,255),2)
除外:打印跟踪框
灰色=cv2.CVT颜色(img,cv2.COLOR\U BGR2GRAY)
灰色=cv2。均衡器历史(灰色)
xc=轨道箱[0][0]
yc=轨道箱[0][1]
xsize=轨道箱[1][0]
ysize=轨道箱[1][1]
x1=int(xc-(xsize/2))
y1=int(yc-(ysize/2))
x2=int(xc+(xsize/2))
y2=int(yc+(ysize/2))
roi_-rect=y1,y2,x1,x2
roi=灰色[y1:y2,x1:x2]
vis_roi=img.copy()[y1:y2,x1:x2]
subrects_left_eye=self.detect(roi.copy(),self.left_eye)
subrects\u mouth=self.detect(roi.copy(),self.mouth)
如果是左眼下方!=[]:
打印“眼睛:”,左眼下直肌,“在roi:”,roi\u-rect
自绘制矩形(视觉roi,左眼下矩形,(255,0,0))
自绘制矩形(相对于roi,次矩形(0,255,0))
cv2.imshow(“测试”,可视投资回报率)
dt=时钟()-self.t
绘图(可视,(20,20),'时间:%.1f毫秒'%(dt*1000))
#画图(视觉,(20,35),'帧:%d'%f]
cv2.imshow(“来源”,img)
cv.MoveWindow('源',500,0)
cv2.imshow('camshift',vis)