安全帽人脸与头部数据集自动裁剪如何调整参数包含安全帽
问题原因及解决方法
首先你的代码存在一个基础变量名错误,会直接导致运行报错:detect_face 函数里你把灰度图命名为 heregray,但后续人脸检测调用的是未定义的 gray,先修正这个问题:
def detect_face(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') faces = face_cascade.detectMultiScale(gray, scaleFactor=1.7, minNeighbors=5) return faces
裁剪区域坐标逻辑说明
OpenCV的图像坐标系原点在左上角,x轴向右延伸,y轴向下延伸:
- 人脸检测返回的
(ex, ey)是人脸框的左上角坐标 ew是人脸框的宽度,eh是人脸框的高度- 原代码的裁剪逻辑
var_img[ey:eh+ey, ex:ex+ew]是y方向从人脸顶部(ey)裁到人脸底部(ey+eh),x方向从人脸左边缘裁到右边缘,刚好只取人脸区域
你之前的修改是把y方向的结束点加了100,相当于往图像下方多裁了100像素,所以只会裁到人脸下半部分,和你要取上方安全帽的需求完全相反。
正确修改方案
要包含人脸上方的安全帽,需要把y方向的裁剪起始点往上调(数值减小),同时要做边界判断避免数组越界:
for(ex, ey, ew, eh) in face: # y方向起始点往上挪100像素留安全帽空间,最小不能小于0避免越界 y_top = max(0, ey - 100) # y方向结束点保持人脸底部不变,也可以根据需求往下加余量 y_bottom = ey + eh # 可选:左右也各加20像素余量,避免安全帽边缘被截断 x_left = max(0, ex - 20) x_right = min(var_img.shape[1], ex + ew + 20) # 执行裁剪 crop_image = var_img[y_top:y_bottom, x_left:x_right] # 后续显示、保存逻辑不变 cv2.imshow("cropped", crop_image) cv2.waitKey(0) cv2.imwrite(os.path.join("outputs/",str(img)),crop_image)
你可以根据自己数据集里安全帽的实际大小调整上方预留的像素值,比如安全帽偏大就把ey - 100里的100改成120或150即可。
内容的提问来源于stack exchange,提问作者Vitaliy Yashar
相关产品推荐
相关产品推荐

