整体解决思路:
前提:拍摄场景光线稳定,证件没有放在图像边缘;且图片使用的证件阅读器拍摄的红外图片,采用了开灯和关灯各拍摄一张图片,图像相减,进行了背景去除;
1)使用二值化和膨胀腐蚀以及sobel算子等进行图像的预处理;
2)进行凸包计算,通过角度,进行证件区域的计算;
最终的结果:
涉及到的数学知识:
1.已知四个坐标点,怎样求出四边形的四个内角
思路:利用三个坐标点构造三角形,使用三条边的长度,进行角度计算
已知三角形的三条边,怎样求解角度:(已知三边长怎么求三角形的角度_百度知道)
方法:设三角形中角A所对应的边长是a,角B所对应的边长是b,角C所对应的边长是c。再利用公式:
①CosA=(c^2+b^2-a^2)/2bc
②CosB=(a^2+c^2-b^2)/2ac
③CosC=(a^2+b^2-c^2)/2ab
算出每一个角的余弦值,利用计算器上的反余弦函数功能就可以计算出各自的角度值。
代码:
def get_angle(pt1, pt2, pt0):
'''
判断角度有没有满足90°
计算三个点中间的那个点的角度
:param p1:
:param p2:
:param p3:
:return:
'''
dx1 = np.abs(pt1[0][0] - pt0[0][0])
dy1 = np.abs(pt1[0][1] - pt0[0][1])
dx2 = np.abs(pt2[0][0] - pt0[0][0])
dy2 = np.abs(pt2[0][1] - pt0[0][1])
dx12 = np.abs(pt1[0][0] - pt2[0][0])
dy12 = np.abs(pt1[0][1] - pt2[0][1])
# return (dx1 * dx2 + dy1 * dy2) / math.sqrt((dx1 * dx1 + dy1 * dy1) * (dx2 * dx2 + dy2 * dy2) + 1e-10)
length0_2 = math.sqrt(dx1 * dx1 + dy1 * dy1)
length0_1 = math.sqrt(dx2 * dx2 + dy2 * dy2)
length2_1 = math.sqrt(dx12 * dx12 + dy12 * dy12)
cosin0 = (math.pow(length0_2, 2) + math.pow(length0_1, 2) - math.pow(length2_1, 2)) / (length0_2 * length0_1 * 2)
return cosin0
maxCosine = 0
for j in range(2, 5):
cosine = np.abs(get_angle(approx[j%4], approx[j-2], approx[j-1]))
maxCosine = max(maxCosine, cosine)
cosine = np.abs(get_angle(approx[1], approx[3], approx[0]))
2.求解四边形面积
思路:求解2个三角形的面积,进行面积加和;
参考链接:
OpenCV4学习笔记(25)——凸包检测_邱小兵的博客-CSDN博客_凸包检测
Python | 凸多边形间重叠面积计算_lovetaozibaby的博客-CSDN博客_python判断两个多边形是否存在交集
opencv-python 详解轮廓及findContours()、drawContours()函数_RayChiu_Labloy的博客-CSDN博客_findcontours() opencv 实现对摄像头输入图像中文件及证件等的实时跟踪,四边形检测及提取_javastart的博客-CSDN博客_opencv实时处理图像【OpenCV入门学习--python】凸包算法(convex hull)_喜欢星星的田螺姑娘的博客-CSDN博客_python 凸包