前言
整体实验步骤:
graph TD
拍摄图像 --> 横切向矫正
横切向矫正 --> 获取目标物坐标框
获取目标物坐标框 --> 根据坐标计算目标像素宽高
根据坐标计算目标像素宽高 --> 根据比例计算目标距离
横切向矫正图像
构造函数CorrectImage 我们需要从单目相机参数中获取:内参矩阵、K\P值 如下代码段中所示。整体完成效果表示为:输入一张原始图像,输入一张矫正后的图像,这样可以减少测量距离误差。
def CorrectImage(Frame):
cameraMatrix = np.array([[1321.395754, 13.90004046, 1254.996814],
[0, 1308.603399, 621.1465241],
[0, 0, 1]])
# 相机畸变系数矩阵,5*1矩阵(k1,k2,p1,p2,k3)
distCoeffs = np.array([0.080593716, -0.025207783, 0.007709644, 0.014762425, 0])
h, w = Frame.shape[:2]
newCameraMatrix, roi = cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, (w, h), 1, (w, h), 0)
# 计算无畸变和修正转换关系
mapx, mapy = cv2.initUndistortRectifyMap(cameraMatrix, distCoeffs, None, newCameraMatrix, (w, h),
cv2.CV_16SC2)
# 重映射 输入是矫正后的图像
CorrectFrame = cv2.remap(Frame, mapx, mapy, cv2.INTER_LINEAR)
return CorrectFrame
获取目标物坐标框&根据坐标计算目标像素宽高
这里我选用较为方便的圆检测,也可以替换为人脸检测,详情可以参考我的另外两篇博客,进行更改函数。
圆形检测: juejin.cn/post/708073…
人脸检测: juejin.cn/post/707483…
这里分开介绍:一个是圆形检测的另一个是人脸检测,这两种检测的差异在于圆心检测返回值是三个(圆心坐标x,y;圆的半径r)人脸检测返回的坐标是四个(左上角起始点x,y 和 目标物的宽高w,h)
对于圆形的高和宽为其直径(2xr),对于矩形框其宽高分别为(w,h)
根据比例计算目标距离
在上面我们得到了矫正后的图像,也对矫正后的图像进行了目标检测得到了目标物的像素宽和高。我们可以根据单目相机的像素(FX,FY),根据相似原理计算出目标距离。
这里仅以圆形为例子,给大家讲解如何利用比例进行测距,这里需要拿倒张氏标定得到的焦距FX和FY以及测量待测物的宽和高(在这里圆形的宽高相等为2r)。
FX对应了实体物体的宽
FY对应了实体物体的高
通过公式:距离= (焦距(X,Y) * 实体物的宽或高)/ 像素宽或高
def FindCoin(CoinImg):
# 将图像转换为灰度图像
gray_img = cv2.cvtColor(CoinImg, cv2.COLOR_BGR2GRAY)
# 高斯滤波降噪
gaussian_img = cv2.GaussianBlur(gray_img, (7, 7), 0)
# 利用Canny进行边缘检测
edges_img = cv2.Canny(gaussian_img, 80, 180, apertureSize=3)
# 自动检测圆
circles1 = cv2.HoughCircles(edges_img, cv2.HOUGH_GRADIENT, 1, 1000, param1=300, param2=10, minRadius=5, maxRadius=30)
if circles1 is None:
pass
else:
circles = circles1[0, :, :]
circles = np.uint16(np.around(circles))
for i in circles[:]:
cv2.circle(CoinImg, (i[0], i[1]), i[2], (0, 0, 255), 2)
# print(i[0], i[1], i[2])
r = 2 * i[2]
FX = 1321.395754
Coin_x = 0.054 # 实体圆的直径
FY = 1308.603399
Coin_y = 0.054 # 实体圆的直径
Distensx = (FX * Face_x) / r
Distensy = (FY * Face_y) / r
print("宽度计算的距离", Distensx)
print("高度计算的距离", Distensy)
测试截图: