如何使用单应性来计算物体在平面上的位置
How to use homography to calculate the object's position on the plane
我要做以下工作:
1. Draw a chessboard with at least 9x6 squares.
2. Take a video using a still camera and place the chessboard on the scene to find a Homography.
3. Remove the calibration target from the scene and compute the background model.
4. Place a moving object in the scene on the same plane as the Chessboard. Just a few seconds are enough
5. Calculate a homography using the frame with the chessboard
6. For each frame with the object: a. Subtract the background and calculate the object's position in the image. B. Use a homography and calculate the object's position on the plane where the chessboard was
7. Draw on a graph as found and connect the dots
第 6b 点是什么意思,如何去做?
我的是这样的:
我说得对吗?或者不是这样:?
更新
我试过这段代码:
chessboard_frame = cv.imread('pen.png',0) # queryImage
chessboard_template = cv.imread('boardTemplate.png',0)
pattern_size = (10,10)
_, corners1 = cv.findChessboardCorners(chessboard_frame, pattern_size)
_, corners2 = cv.findChessboardCorners(chessboard_template, pattern_size)
H, _ = cv.findHomography(corners1, corners2)
但它抛出以下错误:
error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-czu11tvl\opencv\modules\calib3d\src\fundam.cpp:378: error: (-5:Bad argument) The input arrays should be 2D or 3D point sets in function 'cv::findHomography'
作业有点不清楚。这就是我所理解的你需要做的
- 下面的所有帧都应该是从稳定的相机以某个角度观察平面拍摄的。
- 用平面上的棋盘拍一帧。
- 取一帧没有棋盘的平面(此为背景帧)。
- 在平面(没有棋盘)的顶部拍摄一组运动物体的帧。
- 结果应该是对象位置相对于给定平面的 XY 图。棋盘实际上定义了平面的(0,0)和比例。
您还需要棋盘的模板图像。我建议使用 here.
中图案大小 (9,6) 的棋盘
首先求相机到模板的单应性H
(假设是灰度图):
pattern_size = (9,6)
_, corners1 = cv.findChessboardCorners(chessboard_frame, pattern_size)
_, corners2 = cv.findChessboardCorners(chessboard_template, pattern_size)
H, _ = cv.findHomography(corners1, corners2)
使用背景帧并从每个帧中减去只得到对象的蒙版:
object_mask = np.abs(frame-bg_frame) < threshold
取掩码的平均值以获得代表您的对象的一个像素坐标:
uv_coordinates = np.mean(np.argwhere(object_mask), axis=0)
最后,将 uv_coordinates
转换为 template_coordinates
以便您稍后逐帧绘制:
uv1_coordinates = np.append(uv_coordinates,1).reshape(-1,1) # now size 3X1
template_xy1_coordinates = H@uv1_coordinates # matrix multiplication
template_coordinates = template_xy1_coordinates.flatten()[:2] # result shape (2,)
我要做以下工作:
1. Draw a chessboard with at least 9x6 squares.
2. Take a video using a still camera and place the chessboard on the scene to find a Homography.
3. Remove the calibration target from the scene and compute the background model.
4. Place a moving object in the scene on the same plane as the Chessboard. Just a few seconds are enough
5. Calculate a homography using the frame with the chessboard
6. For each frame with the object: a. Subtract the background and calculate the object's position in the image. B. Use a homography and calculate the object's position on the plane where the chessboard was
7. Draw on a graph as found and connect the dots
第 6b 点是什么意思,如何去做?
我的是这样的:
我说得对吗?或者不是这样:?
更新
我试过这段代码:
chessboard_frame = cv.imread('pen.png',0) # queryImage
chessboard_template = cv.imread('boardTemplate.png',0)
pattern_size = (10,10)
_, corners1 = cv.findChessboardCorners(chessboard_frame, pattern_size)
_, corners2 = cv.findChessboardCorners(chessboard_template, pattern_size)
H, _ = cv.findHomography(corners1, corners2)
但它抛出以下错误:
error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-czu11tvl\opencv\modules\calib3d\src\fundam.cpp:378: error: (-5:Bad argument) The input arrays should be 2D or 3D point sets in function 'cv::findHomography'
作业有点不清楚。这就是我所理解的你需要做的
- 下面的所有帧都应该是从稳定的相机以某个角度观察平面拍摄的。
- 用平面上的棋盘拍一帧。
- 取一帧没有棋盘的平面(此为背景帧)。
- 在平面(没有棋盘)的顶部拍摄一组运动物体的帧。
- 结果应该是对象位置相对于给定平面的 XY 图。棋盘实际上定义了平面的(0,0)和比例。
您还需要棋盘的模板图像。我建议使用 here.
中图案大小 (9,6) 的棋盘首先求相机到模板的单应性H
(假设是灰度图):
pattern_size = (9,6)
_, corners1 = cv.findChessboardCorners(chessboard_frame, pattern_size)
_, corners2 = cv.findChessboardCorners(chessboard_template, pattern_size)
H, _ = cv.findHomography(corners1, corners2)
使用背景帧并从每个帧中减去只得到对象的蒙版:
object_mask = np.abs(frame-bg_frame) < threshold
取掩码的平均值以获得代表您的对象的一个像素坐标:
uv_coordinates = np.mean(np.argwhere(object_mask), axis=0)
最后,将 uv_coordinates
转换为 template_coordinates
以便您稍后逐帧绘制:
uv1_coordinates = np.append(uv_coordinates,1).reshape(-1,1) # now size 3X1
template_xy1_coordinates = H@uv1_coordinates # matrix multiplication
template_coordinates = template_xy1_coordinates.flatten()[:2] # result shape (2,)