OpenCV实现人脸检测及旋转处理(2)

代码段

if angle%90 == 0: # 90° 裁剪图片 logging.debug("90° 裁剪图片") logging.debug(f"{ix}, {iy}, {x}, {y}, {w}, {h}") length2 = min(ix, iy) # 如果人脸太小,放大区域但又不超过图片长度 length = int(w*2.5) length = min(length2, length) logging.debug(f"length: {length2} {length}") ow = length-w ow1 = ow//2 oh = length-h oh1 = oh//2 y1, y2 = y-oh1, y+h+oh1 x1, x2 = x-ow1, x+w+ow1 # 检测图片溢出 logging.debug(f"{y1}, {y2}, {x1}, {x2}") if y1 < 0: logging.debug('裁剪:1 顶部溢出') y1 = 0 y2 = length if y2 > iy: logging.debug('裁剪:2 底部溢出') y2 = iy y1 = iy-length if x1 < 0: logging.debug('裁剪:3 左侧溢出') x1 = 0 x2 = length if x2 > ix: logging.debug('裁剪:4 右侧溢出') x2 = ix x1 = ix-length # 裁剪标记 cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2)

斜矩形裁剪探索

那么gakki那张斜的如何裁剪呢,斜矩形之外有黑色背景。举例:应该取到绿色矩形的扩大版,但又没有取到黑色背景。比如这样的蓝色区域

OpenCV实现人脸检测及旋转处理

转换为数学方法为:todo, 画在本子上的,最后再补

编写数学函数:

else: # 非90°裁剪图片 logging.debug(f"{angle}°裁剪图片") # 1. 求A点坐标 origin_h, origin_w = self.img_bgr.shape[:2] # 旋转角度取的ab ad边不同 if angle%180<90: ab = origin_w ad = origin_h else: ab = origin_h ad = origin_w op = ix ap = math.cos(math.radians(angle)) * ab oa = op-ap A = Point(oa, 0) logging.debug(f"ab={ab}, ad={ad}, op={op}, ap={ap}, oa={oa}, {A}") # 2. 人脸中心Z坐标 face_rect = Rectangle(Point(x, y), w, h) z = face_rect.center_p logging.debug(f"{face_rect} center point is {z}") # 3. Z到AB、AD距离 k = math.tan(math.radians(angle)) # tan(α) k2 = -1/k # 垂直 logging.info(f"k1 = {k}, k2 = {k2}") z_ab_len = abs(k*z.x-z.y-oa*k)/math.sqrt(k**2+1) z_ad_len = abs(k2*z.x-z.y-oa*k2)/math.sqrt(k2**2+1) logging.debug(f"z-ab len is {z_ab_len}, z-ad len is {z_ad_len}") # 4. 距离四边最小距离 h1 = z_ab_len h2 = z_ad_len h3 = ad-h1 h4 = ab-h2 min_len = min(h1, h2, h3, h4) logging.debug(f"face around len is {h1} {h2} {h3} {h4}, min:{int(min_len)}") # 5. 圆形标注 #cv2.line(img, z.r_tuple(), (50, 100), (0,255,0)) for r in (h1, h2, h3, h4): r = int(r) if int(min_len) == r: cv2.circle(img, z.r_tuple(), r, (255, 0, 0), 3) else: cv2.circle(img, z.r_tuple(), r, (0, 0, 255), 2)

来测试一波,最后的圆形标注只是为了辅助验证。

其实是有问题的,看效果,最小的蓝色圆形标注位置不对,超出原图片了,而且观察其他三个圆也不在图片边上。

OpenCV实现人脸检测及旋转处理

if angle%180<90: ab = origin_w ad = origin_h else: ab = origin_h ad = origin_w

这块处理不同角度下取的矩形ABCD边不同,数学角度看是没有错的,但是Opencv坐标圆心在左上角,所以得将数学图形画为:todo

上面赋值代码只需改为

if angle%180<90: ab = origin_h ad = origin_w else: ab = origin_w ad = origin_h

OpenCV实现人脸检测及旋转处理

蓝色圈已经是我们要求的矩形头像外接圆了,其他三个圆输出也是贴紧各自的边框,完美。

在蓝圈中画黑色正方形:

OpenCV实现人脸检测及旋转处理

是想要的效果,最后裁剪即可。

OpenCV实现人脸检测及旋转处理

多角度修复

测试初始角度为横向或者侧向时,需修复角度:

# 最后取的图片和角度无关,只取锐角 angle=angle%90

测试三张不同角度照片,和一张不需旋转的图:

OpenCV实现人脸检测及旋转处理

结果为:

OpenCV实现人脸检测及旋转处理

过程:

OpenCV实现人脸检测及旋转处理

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/a8a23ed9ba4b26f4a129e9ac04661132.html