攝像頭單目測距原理及實現
一.測距原理
空間的深度或距離等資料的攝像頭。
人的眼睛長在頭部的前方,兩隻眼的視野範圍重疊,兩眼同時看某一物體時,產生的視覺稱為雙眼視覺。
雙眼視覺的優點是可以彌補單眼視野中的盲區缺損,擴大視野,並產生立體視覺。
也就是說,假如只有乙隻眼睛,失去立體視覺後,人判斷距離的能力將會下降。
這也就是單目失明的人不能考取駕照的原因。
單純的單目視覺測距,必須已知乙個確定的長度。
f為攝像頭的焦距,c為鏡頭光心。物體發出的光經過相機的光心,然後成像於影象感測器或者也可以說是像平面上,如果設物體所在平面與相機平面的距離為d,物體實際高度為h,在感測器上的高度為h,h一定要是已知的,我們才能求得距離d。
假設我們有乙個寬度為 w 的目標或者物體。然後我們將這個目標放在距離我們的相機為 d 的位置。我們用相機對物體進行拍照並且測量物體的畫素寬度 p 。這樣我們就得出了相機焦距的公式:
f = (p x d) / w
例如,假設現在我們有一張a4紙(8.27in x 11.69in), in代表英吋,1in = 25.4mm。紙張寬度w=11.69in,相機距離紙張的距離d = 32in,此時拍下的**中a4紙的畫素寬度為p=192px(我的相機實際測量得到的值)。
此時我們可以算出焦距f=(192x30)/11.69。
當我們將攝像頭遠離或者靠近a4紙時,就可以用相似三角形得到相機距離物體的距離。
此時的距離: d』 = (w』 x f ) / p』。
(注意:這裡測量的距離是相機到物體的垂直距離,產生夾角,測量的結果就不準確了。)
二.測距步驟:
1. 使用攝像機採集道路前方的影象;
2. 在道路區域對物體進行檢測,通過矩形框將物體形狀框出來。
3. 結合矩形框資訊,找到該矩形框底邊的兩個像平面座標,分別記為(u1,v1)和(u2,v2);
4. 使用幾何關係推導法,由像平面座標點(u1, v1)、(u2, v2)推導出道路平面座標(x1,y1)、(x2, y2);(投影到地面上,z軸為0)
5. 通過歐氏距離公式計算出d。
三.難點整理:
1.影象畸變矯正模型的理解;
(標定引數,內參矩陣,畸變矩陣,外參矩陣(平移、旋轉向量矩陣))
2.畫素座標與世界座標公式的推導及驗證;
3.測距方法,對於檢測物體在攝像頭前方、左側、右側的判別思路;
4.弄清反畸變;對於畸變矯正後的影象中的檢測框中的點進行反畸變處理。
四.相機鏡頭畸變矯正-->得到相機的內外引數、畸變引數矩陣
1. 外引數矩陣。世界座標經過旋轉和平移,然後落到另乙個現實世界點(攝像機座標)上。
2. 內引數矩陣。告訴你上述那個點在1的基礎上,是如何繼續經過攝像機的鏡頭、並通過針孔成像和電子轉化而成為畫素點的。
3. 畸變矩陣。告訴你為什麼上面那個畫素點並沒有落在理論計算該落在的位置上,還產生了一定的偏移和變形.
五.實現**
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# date: 18-10-29
import numpy as np # 匯入numpy庫
import cv2 # 匯入opencv庫
known_distance = 32 # 這個距離自己實際測量一下
known_width = 11.69 # a4紙的寬度
known_height = 8.27
image_paths = ["picture1.jpg", "picture2.jpg", "picture3.jpg"] # 將用到的放到了乙個列表中
# 定義目標函式
def find_marker(image):
gray_img = cv2.cvtcolor(image, cv2.color_bgr2gray) # 將彩色圖轉化為灰度圖
gray_img = cv2.gaussianblur(gray_img, (5, 5), 0) # 高斯平滑去噪
edged_img = cv2.canny(gray_img, 35, 125) # canny運算元閾值化
cv2.imshow("降噪效果圖", edged_img) # 顯示降噪後的
# 獲取紙張的輪廓資料
# print(len(countours))
c = max(countours, key=cv2.contourarea) # 獲取最大面積對應的點集
rect = cv2.minarearect(c) # 最小外接矩形
return rect
# 定義距離函式
def distance_to_camera(knownwidth, focallength, perwidth):
return (knownwidth * focallength) / perwidth
# 計算攝像頭的焦距(內參)
def calculate_focaldistance(img_path):
first_image = cv2.imread(img_path) # 這裡根據準備的第一張,計算焦距
# cv2.imshow('first image', first_image)
marker = find_marker(first_image) # 獲取矩形的中心點座標,長度,寬度和旋轉角度
focallength = (marker[1][0] * known_distance) / known_width # 獲取攝像頭的焦距
# print(marker[1][0])
print('焦距(focallength) = ', focallength) # 列印焦距的值
return focallength
# 計算攝像頭到物體的距離
def calculate_distance(image_path, focallength_value):
image = cv2.imread(image_path)
# cv2.imshow("原圖", image)
marker = find_marker(image) # 獲取矩形的中心點座標,長度,寬度和旋轉角度, marke[1][0]代表寬度
distance_inches = distance_to_camera(known_width, focallength_value, marker[1][0])
box = cv2.boxpoints(marker)
# print("box = ", box)
box = np.int0(box)
print("box = ", box)
cv2.drawcontours(image, [box], -1, (0, 255, 0), 2) # 繪製物體輪廓
cv2.puttext(image, "%.2fcm" % (distance_inches * 2.54), (image.shape[1] - 300, image.shape[0] - 20),
cv2.font_hershey_******x, 2.0, (0, 255, 0), 3)
cv2.imshow("單目測距", image)
雙攝像頭測距
開篇之前,首先要感謝maxwellsdemon和wobject,沒有和你們的討論,也就沒有此篇的成文。說到雙攝像頭測距,首先要複習一下測距原理,把learning opencv翻到416和418頁,可以看到下面兩幅圖 圖1.雙攝像頭模型俯檢視 圖2,雙攝像頭模型立體檢視 圖1解釋了雙攝像頭測距的原理...
深度攝像頭測距原理簡介
深度檢測主要技術方法 1.雙目匹配 雙rgb攝像頭 可選的照明系統 三角測量原理即目標點在左右兩幅檢視中成像的橫座標之間存在的差異 視差disparity 與目標點到成像平面的距離成反比例的關係 z ft d 得到深度資訊。雙目匹配採用三角測量原理完全基於影象處理技術,通過尋找兩個影象中的相同的特徵...
攝像頭測距
深度檢測主要技術方法 1.雙目匹配 雙rgb攝像頭 可選的照明系統 三角測量原理即目標點在左右兩幅檢視中成像的橫座標之間存在的差異 視差disparity 與目標點到成像平面的距離成反比例的關係 z ft d 得到深度資訊。雙目匹配採用三角測量原理完全基於影象處理技術,通過尋找兩個影象中的相同的特徵...