如何估算前方人物的距離?

撰寫/攝影 CH.Tseng
部落格 https://chtseng.wordpress.com/
Facebook https://www.facebook.com/chenghsun.tseng

我們都知道,組合兩台相機(stereo camera)可讓我們以模擬人眼的方式,在已知相機焦距以及兩台相機距離的情況下,透過視差來計算前方物體的距離。那麼… 單台的相機可以計算出前方物件的距離嗎?可以的,如果只想使用一台相機來計算距離,我們只要先知道該物體的實際大小(寬或高)以及相機的焦距,就能依據物體在相片上的尺寸(pixels),計算出該物體相距我們有多遠。

最早是在pyimagesearch.com看到這篇文章「Find distance from camera to object/marker using Python and OpenCV」(https://www.pyimagesearch.com/2015/01/19/find-distance-camera-objectmarker-using-python-opencv/),作者Adrian介紹如何利用計算相機焦距來反算出鏡頭中目標物體的距離,這勾起了我的興趣,我們是否能夠利用此種方式,很快的計算出前方陌生人距離我們有多遠呢?

什麼是焦距 Focal length

首先,瞭解一下相機焦距是什麼?它又是怎麼計算的?

維基百科的解釋是:

“焦距,也稱為焦長,是光學系統中衡量光的聚集或發散的度量方式,指從透鏡中心到光聚集之焦點的距離。”

如下圖,不同的凹透鏡與凸透鏡,因光的折射方向不同,其焦距f有不同的計算,但總而言之,從光線焦點到透鏡之間的距離就是焦距,如下方不同的透鏡有不同的焦距量測方法。

攝影愛好者通常擁有很多支鏡頭用來適應不同的攝影場景。除了光圈大小,這些攝影鏡頭最大的差異就是焦距上的不同。不同的鏡頭有不同的焦距,不同的焦距會使得相同大小的物體在感光元件上呈現不同的大小,焦距愈短的鏡頭,在相同的感光元件尺寸可容納更多眼前的物體,代表它的視野愈廣,反之,焦距愈長的鏡頭,能將遠處物體放得更大更適合特寫,這也就是所謂的望遠鏡頭,如下圖所示。

焦距範圍 <20mm 24 ~35mm 50mm 80~300mm >300mm
視野 超廣角 廣角 標準 望遠 超望遠

焦距的計算

為什麼要計算焦距?因為當攝影師確定要拍攝的場景或物體之後,心中會有個構圖希望在相片中它的比例是多大,再決定要使用何種焦距的鏡頭來滿足此構圖。例如,我們想要去機場拍攝747客機的特寫, 747-100型客機的長度為70.8公尺,全幅感光元件的長度為36mm,距離飛機跑道為500公尺,根據這些資訊我們就可以推算出鏡頭的焦距,然後選擇必要的鏡頭。

你知道這公式怎麼來的嗎?這是來自於一個國中數學的章節:相似三角形定理(triangle similarity),兩個相似三角形其邊長比例是相等的觀念。

距離的計算

反推,假設我們已經知道了相機的焦距,那麼,也能夠計算出物體與相機之間的距離了,只要把上述的公式左右兩邊稍微移動一下,然後把感測器大小替換為物體在影像上的pixels數目,就能計算出距離了。

從上面的公式得知,如果要計算影像中物件的距離,我們必須先知道:

  1. 鏡頭焦距
  2. 被攝物體的尺寸(長度或寬度)
  3. 影像中該物體的pixels數(長度或寬度)

實際計算說明

假設我們要量測下圖中膠水瓶的距離,該膠水瓶長度為11.5cm。

首先,如果我們不知道目前相機鏡頭的焦距,先如下計算取得焦距:

  1. 將該膠水瓶放置於離相機一定的距離,例如30cm。
  2. 拍攝一張相片計算膠水瓶在相片中的長度有多少pixels,假設為150 pixels。
  3. 於是計算出相機焦距為: 30cm x 150pixels / 11.5cm = 391.3mm。

把這數值記下來,以後就可以用在推算其它物體的距離了。

接下來,我們將膠水瓶放在如上圖中的位置,然後拍攝一張計算看它的距離為多遠。

1. 拍攝後發現該物體在相片中的長度為90pixels

2. 計算距離:391.3mm x 11.5cm / 90 pixels = 49.999 cm

故可透過拍攝的相片計算出該物體目前距離為49.999cm。

計算未知尺寸物件的距離

如果我們要透過影像大小來計算該物體的距離,依據上述公式我們必須知道該物體的實際尺寸才行,但在實際場合我們經常無法預先得知該物體的尺寸。例如,一台停在遠方的汽車,想要計算它距離我們有多遠但不知該汽車的實際長寬,要如何才能使用上述公式計算它距離我們多遠呢?我的想法是,可以透過該汽車上已知物件的尺寸來計算,例如,車子輪胎長度、車牌、車高等尺寸差異較小,我們可改為抓取計算該特定物件來估算出汽車的距離。

如何計算人物的距離

如果相片中是人呢?我們要怎麼估算出他距離有多遠?同樣的想法,首先尋找人類身上特定已知尺寸的物件,你覺得會是什麼?我所想到的是頭顱的寬度,人類無論高矮胖瘦種族,頭圍的尺寸(尤其是寬度)應該是每個人外觀差異最小的部份,例如下方的圖表(摘自維基百科:https://en.wikipedia.org/wiki/Human_head)。

誤差

男女的人臉不含耳朵的寬度介於12.5~15.9cm,中間值則介於13.3~14.5cm。假設我們採用13.9cm作為人臉的寬度平均,那麼,該平均值與最小及最大人臉的寬度差距分別為-1.4cm與+2.0cm。換句話說,假設我們使用13.9來作為每個人的人臉寬度,那麼,最差的情況是少估了1.4cm或多估了2.0cm。

假設我們是在最差情況下,少估了1.4cm或多估了2.0cm,那對於計算出的距離影響有多大呢?以女兒為例,她的臉寬約12.8cm,我用iPhone SE手機在距離她大約100cn處拍攝一張如下,計算出其焦距大約為:100cm * 814 pixels / 12.8cm = 3179.69:

接著再往前移動約一半距離再拍攝一張,此時可利用公式計算出該照片的距離為:

3179.69 x 12.8 / 944 = 43.11 cm

 

如果當初我將女兒的臉寬分別少估與多估了1.0cm,亦即11.8cm與13.8cm,那麼計算出的距離將分別由43.11cm變成39.75cm與46.48cm。

3179.69 x 11.8 / 944 = 39.75cm

3179.69 x 13.8 / 944 = 46.48cm

故得知在距離為43.11cm時,臉部1cm的誤差對於距離計算的影響大約正負3.36cm。

如果再看一次公式

會發現,距離愈遠將使得作為分母的臉寬影像pixels更小,造成誤差值會更大,例如下圖:

在距離更遠的情況下,假設將臉寬一樣分別少估與多估了1.0cm,那麼計算出的距離將分別為326.26cm與381.56cm,,影響範圍擴大至正負27.65cm。

3179.69 x 12.8 / 115 = 353.91cm

3179.69 x 11.8 / 115 = 326.26cm

3179.69 x 13.8 / 115 = 381.56cm

不過,正如先前所提到,人臉寬度男與女平均分別為14.5cm與13.3cm,假設我們使用13.9來作為每個人的人臉寬度,那麼,最差的情況就是少估了1.4cm或多估了2.0cm。如果真的希望能降低誤差,可考慮先辨識其性別後再使用該性別的平均臉寬,先針對臉部作align後再取得其實際pixels,應可減少距離的誤差。

實際測試

結論

在已知相機的焦距情況下,我們可以將臉孔寬度預設為13.9cm用以推算人物的大致距離,雖然最終其值無法很準確(距離為43.11cm時,臉部1cm的誤差對於距離計算的影響大約正負3.36cm),但用於大略的估計是可行的。如果需要準確的偵測距離,那我們必須先得知該人實際的臉孔寬度(或長度)才行,但這在實務應用上比較不可行。

另一替代方式,可利用人物身上明確已知尺寸大小的要的物作為替代人臉的量測標準,例如,已知該人物的身高、襯衫普遍的鈕釦直徑等。

想了解更多CH.Tseng,可以點此連結 瀏覽更多文章喔~

 

5 thoughts on “如何估算前方人物的距離?

    • CAVEDU小編 says:

      您好,本篇文章是與CH.Tseng合作轉發文章
      建議相關疑問至原作者平台上詢問喔~
      感謝您,祝順心

  1. 空白 says:

    因為沒有看到留言 所以再發一次 如果有發過當作沒看到
    你好
    請問可以跟您要份代碼?
    我學校專題有類式的東西要製作
    方便給代碼 會對我幫助很大
    謝謝

    • CAVEDU小編 says:

      您好,本篇文章是與CH.Tseng合作轉發文章
      若有文章相關疑問歡迎至CH.Tseng 原作者平台上詢問喔~
      感謝您,祝順心

    • CAVEDU小編 says:

      您好,本篇文章是與CH.Tseng合作轉發文章
      建議相關疑問至原作者平台上詢問喔~
      感謝您,祝順心

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *