背景
由于我们在做项目的时候可能会涉及到某个指定区域进行目标检测或者人脸识别等任务,所以这篇博客是为了探究如何在传统目标检测的基础上来结合特定区域进行检测,以OpenCV自带的包为例。
一般来说有两种方式实现区域指定:
- 第一种:在网络处理之前,将特定区域划分出来,然后在送入到神经网络进行检测
- 第二种:在网络处理之后,直接来划分区域的坐标对网络处理后目标进行判定,判定此目标是否在这个区域中,如果在则show,否则则略过
很明显通过第一种方式,网络可以减少很大的计算复杂度,因为不用将整张图片送入到网络中进行处理。
代码
这个代码是直接通过对特定区域结合OpenCV自带人脸检测器来进行人脸检测。若区域内,目标则被检测,超过区域则不被记录。
import cv2
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
# 定义感兴趣区域的坐标和大小
roi_x = 200
roi_y = 100
roi_width = 300
roi_height = 300
while True:
# 读取一帧图像
ret, frame = cap.read()
if not ret:
print("无法读取摄像头图像")
break
# 获取感兴趣区域
roi = frame[roi_y:roi_y+roi_height, roi_x:roi_x+roi_width]
# 将感兴趣区域转换为灰度图像
gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
# 使用人脸检测器检测人脸区域
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
# 在原始图像上绘制感兴趣区域矩形
cv2.rectangle(frame, (roi_x, roi_y), (roi_x+roi_width, roi_y+roi_height), (255, 0, 0), 2)
# 在感兴趣区域上绘制人脸区域矩形
for (x, y, w, h) in faces:
cv2.rectangle(roi, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 在窗口中显示图像
cv2.imshow("Camera", frame)
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
这个代码在上面代码的基础上,加入了鼠标点击事件,用户可以通过自己来划分特定检测区域,划分之后将从整张图片的检测转换为特定区域的检测。
import cv2
def draw_roi(event, x, y, flags, param):
global roi_x, roi_y, roi_width, roi_height, drawing
if event == cv2.EVENT_LBUTTONDOWN:
# 鼠标按下,开始绘制
roi_x, roi_y = x, y
elif event == cv2.EVENT_LBUTTONUP:
# 鼠标释放,结束绘制
roi_width, roi_height = x - roi_x, y - roi_y
drawing = True
if __name__ == '__main__':
# 创建一个全局变量来存储感兴趣区域的坐标和大小
roi_x, roi_y, roi_width, roi_height = 0, 0, 0, 0
drawing = False
over = 0
cap = cv2.VideoCapture(0)
# 创建窗口并绑定鼠标事件
cv2.namedWindow("Camera")
cv2.setMouseCallback("Camera", draw_roi)
# 加载人脸检测器
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
while True:
ret, frame = cap.read()
if not ret:
print("无法读取摄像头图像")
break
# 如果触发了鼠标事件,则在感兴趣区域上运行人脸检测器
roi = frame[roi_y:roi_y + roi_height, roi_x:roi_x + roi_width]
# 在原始图像上绘制感兴趣区域矩形
cv2.rectangle(frame, (roi_x, roi_y), (roi_x + roi_width, roi_y + roi_height), (255, 0, 0), 2)
if drawing:
gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
for (x, y, w, h) in faces:
cv2.rectangle(roi, (x, y), (x + w, y + h), (0, 255, 0), 2)
else:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Camera", frame)
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()