对不起,因为我是编码的新手。首先,出于该项目的目的,我正在使用 Python绑定到OpenCV的库。
我的相机已经过校准,以显示鱼眼失真。我分别获得了K和D,相机固有矩阵和失真矩阵的以下值:
K = [[438.76709 0.00000 338.13894]
[0.00000 440.79169 246.80081]
[0.00000 0.00000 1.00000]]
D = [-0.098034379506 0.054022224927 -0.046172648829 -0.009039512970]
Focal length: 2.8mm
Field of view: 145 degrees (from manual)
当我不变形并显示图像时,我得到的图像在被拉伸得太远(预期)的区域具有黑色像素。但是,由于对象不大,因此不会妨碍对象宽度的计算,并且会填充图像的20%。
我将放置物体距相机镜头 10cm 。根据我在针孔相机模型上阅读的内容,我将需要用于控制3D到2D转换的外部参数。但是,我不确定应该如何推导它。
假设我有2个点的像素坐标(每个点都沿着它们之间的边缘,我想测量距离),我如何使用这些导出的矩阵找到这两个点之间的真实距离?
如果我的矩形对象不平行于相机的主轴,那么即使在这种情况下,有没有一种算法可以计算宽度?
答案 0 :(得分:1)
我将使用类似的三角形来确定图像中的宽度与对象宽度成比例的(distance of camera to object)/(focal length)
,在您的情况下为100/2.8
。这是在假设对象位于图像中心(即相机正前方)的情况下进行的。
答案 1 :(得分:0)
鉴于相机和物体之间的距离是固定的,您可以做的是首先找出所找到的拐角之间的像素距离,然后将其转换为毫米使用像素/毫米比率/比例因子来确定您的对象宽度。
使用的算法是哈里斯角点检测 Harris Corner Detection
捕获其中包含对象的框架
cap = cv2.VideoCapture(0)
while(True):
#Capture frame-by-frame
ret, frame = cap.read()
cv2.imshow('LIVE FRAME!', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
#Save it to some location
cv2.imwrite('Your location', frame)
首先使用参考对象校准像素/毫米比。
#Read Image
image = cv2.imread('Location of your previously saved frame with the object in it.')
object_width = input(int("Enter the width of your object: ")
object_height = input(int("Enter the height of your object: ")
#Find Corners
def find_centroids(dst):
ret, dst = cv2.threshold(dst, 0.01 * dst.max(), 255, 0)
dst = np.uint8(dst)
# find centroids
ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)
# define the criteria to stop and refine the corners
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100,
0.001)
corners = cv2.cornerSubPix(gray,np.float32(centroids[1:]),(5,5),
(-1,-1),criteria)
return corners
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv2.cornerHarris(gray, 5, 3, 0.04)
dst = cv2.dilate(dst, None)
# Get coordinates of the corners.
corners = find_centroids(dst)
for i in range(0, len(corners)):
print("Pixels found for this object are:",corners[i])
image[dst>0.1*dst.max()] = [0,0,255]
cv2.circle(image, (int(corners[i,0]), int(corners[i,1])), 7, (0,255,0), 2)
for corner in corners:
image[int(corner[1]), int(corner[0])] = [0, 0, 255]
a = len(corners)
print("Number of corners found:",a)
#List to store pixel difference.
distance_pixel = []
#List to store mm distance.
distance_mm = []
P1 = corners[0]
P2 = corners[1]
P3 = corners[2]
P4 = corners[3]
P1P2 = cv2.norm(P2-P1)
P1P3 = cv2.norm(P3-P1)
P2P4 = cv2.norm(P4-P2)
P3P4 = cv2.norm(P4-P3)
pixelsPerMetric_width1 = P1P2 / object_width
pixelsPerMetric_width2 = P3P4 / object_width
pixelsPerMetric_height1 = P1P3 / object_height
pixelsPerMetric_height2 = P2P4 / object_height
#Average of PixelsPerMetric
pixelsPerMetric_avg = pixelsPerMetric_width1 + pixelsPerMetric_width2 + pixelsPerMetric_height1 + pixelsPerMetric_height2
pixelsPerMetric = pixelsPerMetric_avg / 4
print(pixelsPerMetric)
P1P2_mm = P1P2 / pixelsPerMetric
P1P3_mm = P1P3 / pixelsPerMetric
P2P4_mm = P2P4 / pixelsPerMetric
P3P4_mm = P3P4 / pixelsPerMetric
distance_mm.append(P1P2_mm)
distance_mm.append(P1P3_mm)
distance_mm.append(P2P4_mm)
distance_mm.append(P3P4_mm)
distance_pixel.append(P1P2)
distance_pixel.append(P1P3)
distance_pixel.append(P2P4)
distance_pixel.append(P3P4)
以像素和毫米为单位打印距离,即宽度和高度
print(distance_pixel)
print(distance_mm)
pixelsPerMetric
是您的比例因子,它给出每毫米的平均像素数。您可以修改此代码以使其符合您的需求。