0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用Python和OpenCV查找從相機(jī)到物體/標(biāo)記的距離

新機(jī)器視覺 ? 來(lái)源: 程序員阿德 ? 作者: 程序員阿德 ? 2022-11-29 17:44 ? 次閱讀

攝像頭測(cè)距就是計(jì)算照片中的目標(biāo)物體到相機(jī)的距離??梢允褂孟嗨迫切危╰riangle similarity)方法實(shí)現(xiàn),或者使用更復(fù)雜但更準(zhǔn)確的相機(jī)模型的內(nèi)參來(lái)實(shí)現(xiàn)這個(gè)功能。

使用相似三角形計(jì)算物體到相機(jī)的距離

假設(shè)物體的寬度為 W,將其放到離相機(jī)距離為 D 的位置,然后對(duì)物體進(jìn)行拍照。在照片上量出物體的像素寬度 P,于是可以得出計(jì)算相機(jī)焦距 F 的公式: dceaa3a8-6d8f-11ed-8abf-dac502259ad0.svg

比如我在相機(jī)前 24 英寸距離(D=24 inches)的位置橫著放了一張 8.5 x 11 英寸(W=11 inches)的紙,拍照后通過(guò)圖像處理得出照片上紙的像素寬度 P=248 pixels。所以焦距 F 等于:

dd0636cc-6d8f-11ed-8abf-dac502259ad0.svg

此時(shí)移動(dòng)相機(jī)離物體更近或者更遠(yuǎn),我們可以應(yīng)用相似三角形得到計(jì)算物體到相機(jī)的距離的公式: dd1d3886-6d8f-11ed-8abf-dac502259ad0.svg

原理大概就是這樣,接下來(lái)使用 OpenCV 來(lái)實(shí)現(xiàn)。

獲取目標(biāo)輪廓

# import the necessary packages
from imutils import paths
import numpy as np
import imutils
import cv2
def find_marker(image):
    # convert the image to grayscale, blur it, and detect edges
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (5, 5), 0)
    edged = cv2.Canny(gray, 35, 125)
    # find the contours in the edged image and keep the largest one;
    # we'll assume that this is our piece of paper in the image
    cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    c = max(cnts, key = cv2.contourArea)
    # compute the bounding box of the of the paper region and return it
    return cv2.minAreaRect(c)

定義一個(gè) find_marker 函數(shù),接收一個(gè)參數(shù) iamge,用來(lái)找到要計(jì)算距離的物體。這里我們用一張 8.5 x 11 英寸的紙作為目標(biāo)物體。第一個(gè)任務(wù)是在圖片中找到目標(biāo)物體。

下面這三行是先將圖片轉(zhuǎn)換為灰度圖,并進(jìn)行輕微模糊處理以去除高頻噪聲,然后進(jìn)行邊緣檢測(cè)。

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 35, 125)

做了這幾步后圖片看起來(lái)是這樣的:

dd2de104-6d8f-11ed-8abf-dac502259ad0.png

現(xiàn)在已經(jīng)可以清晰地看到這張紙的邊緣,接下來(lái)需要做的是找出這張紙的輪廓。

cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key = cv2.contourArea)

用 cv2.findContours 函數(shù)找到圖片中的眾多輪廓,然后獲取其中面積最大的輪廓,并假設(shè)這是目標(biāo)物體的輪廓。

這種假設(shè)只適用于我們這個(gè)場(chǎng)景,在實(shí)際使用時(shí),在圖片中找出目標(biāo)物體的方法與應(yīng)用場(chǎng)景有很大關(guān)系。

我們這個(gè)場(chǎng)景用簡(jiǎn)單的邊緣檢測(cè)并找出最大的輪廓就可以了。當(dāng)然為了使程序更具有魯棒性,也可以用輪廓近似,并剔除不是四個(gè)點(diǎn)的輪廓(紙張是一個(gè)有四個(gè)點(diǎn)的矩形),然后再找出面積最大,具有四個(gè)點(diǎn)的輪廓。

注意: 關(guān)于這個(gè)方法,詳情可以查看這篇文章,用于構(gòu)建一個(gè)移動(dòng)文本掃描工具。

我們也可以根據(jù)顏色特征在圖片中找到目標(biāo)物體,因?yàn)槟繕?biāo)物體和背景的顏色有著很明顯的不同。還可以應(yīng)用關(guān)鍵點(diǎn)檢測(cè)(keypoint detection),局部不變性描述子(local invariant descriptors)和關(guān)鍵點(diǎn)匹配(keypoint matching)來(lái)尋找目標(biāo)。但是這些方法不在本文的討論范圍內(nèi),而且高度依賴具體場(chǎng)景。

我們現(xiàn)在得到目標(biāo)物體的輪廓了,find_marker 函數(shù)最后返回的是包含輪廓 (x, y) 坐標(biāo)、像素長(zhǎng)度和像素寬度的邊框,

計(jì)算距離

接下來(lái)該使用相似三角形計(jì)算目標(biāo)到相機(jī)的距離。

def distance_to_camera(knownWidth, focalLength, perWidth):
    # compute and return the distance from the maker to the camera
    return (knownWidth * focalLength) / perWidth

distance_to_camera 函數(shù)傳入目標(biāo)的實(shí)際寬度,計(jì)算得到的焦距和圖片上目標(biāo)的像素寬度,就可以通過(guò)相似三角形公式計(jì)算目標(biāo)到相機(jī)的距離了。

下面是調(diào)用 distance_to_camera 函數(shù)之前的準(zhǔn)備:

# initialize the known distance from the camera to the object, which
# in this case is 24 inches
KNOWN_DISTANCE = 24.0


# initialize the known object width, which in this case, the piece of
# paper is 12 inches wide
KNOWN_WIDTH = 11.0


# load the furst image that contains an object that is KNOWN TO BE 2 feet
# from our camera, then find the paper marker in the image, and initialize
# the focal length
image = cv2.imread("images/2ft.jpg")
marker = find_marker(image)
focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH

首先是測(cè)量目標(biāo)物體的寬度,和目標(biāo)物體到相機(jī)的距離,并根據(jù)上面介紹的方法計(jì)算相機(jī)的焦距。其實(shí)這些并不是真正的攝像機(jī)標(biāo)定。真正的攝像機(jī)標(biāo)定包括攝像機(jī)的內(nèi)參,相關(guān)知識(shí)可以可以查看這里。

使用 cv2.imread 函數(shù)從磁盤加載圖片,然后通過(guò) find_marker 函數(shù)得到圖片中目標(biāo)物體的坐標(biāo)和長(zhǎng)寬信息,最后根據(jù)相似三角形計(jì)算出相機(jī)的焦距。

現(xiàn)在有了相機(jī)的焦距,就可以計(jì)算目標(biāo)物體到相機(jī)的距離了。

# loop over the images
for imagePath in sorted(paths.list_images("images")):
    # load the image, find the marker in the image, then compute the
    # distance to the marker from the camera
    image = cv2.imread(imagePath)
    marker = find_marker(image)
    inches = distance_to_camera(KNOWN_WIDTH, focalLength, marker[1][0])


    # draw a bounding box around the image and display it
    box = cv2.cv.BoxPoints(marker) if imutils.is_cv2() else cv2.boxPoints(marker)
    box = np.int0(box)
    cv2.drawContours(image, [box], -1, (0, 255, 0), 2)
    cv2.putText(image, "%.2fft" % (inches / 12),
        (image.shape[1] - 200, image.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX,
        2.0, (0, 255, 0), 3)
    cv2.imshow("image", image)
    cv2.waitKey(0)

使用 for 循環(huán)遍歷每個(gè)圖片,計(jì)算每張圖片中目標(biāo)對(duì)象到相機(jī)的距離。在結(jié)果中,我們根據(jù)得到的輪廓信息將方框畫了出來(lái),并顯示出了距離。下面是得到的幾個(gè)結(jié)果圖:

dd3e0cb4-6d8f-11ed-8abf-dac502259ad0.png

dd4f0a00-6d8f-11ed-8abf-dac502259ad0.png

總結(jié)

通過(guò)這篇文章,我們學(xué)會(huì)了使用相似三角形計(jì)算圖片中一個(gè)已知物體到相機(jī)的距離。

需要先測(cè)量出目標(biāo)物體的實(shí)際寬度和目標(biāo)物體到相機(jī)的距離,然后使用圖像處理的方法自動(dòng)計(jì)算圖片中目標(biāo)物體的像素寬度,并使用相似三角形計(jì)算出相機(jī)的焦距。

根據(jù)相機(jī)的焦距就可以計(jì)算圖片中的目標(biāo)物體到相機(jī)的距離。

原文作者Adrian Rosebrock博士 在此特別鳴謝

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 機(jī)器視覺
    +關(guān)注

    關(guān)注

    161

    文章

    4320

    瀏覽量

    119996
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4284

    瀏覽量

    62325
  • OpenCV
    +關(guān)注

    關(guān)注

    29

    文章

    625

    瀏覽量

    41214
  • python
    +關(guān)注

    關(guān)注

    55

    文章

    4768

    瀏覽量

    84376

原文標(biāo)題:使用OpenCV實(shí)現(xiàn)攝像頭測(cè)距

文章出處:【微信號(hào):vision263com,微信公眾號(hào):新機(jī)器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【芯靈思A83T試用申請(qǐng)】嵌入式視覺--遠(yuǎn)距離物體跟蹤與定位

    OpenCV環(huán)境,連接工業(yè)相機(jī)3)物體跟蹤與定位算法的實(shí)現(xiàn)4)結(jié)項(xiàng)與項(xiàng)目演示具體描述:本方案擬以嵌入式開發(fā)為基礎(chǔ),基于CMOS相機(jī)和數(shù)字圖像處理技術(shù)的遠(yuǎn)
    發(fā)表于 04-27 14:18

    LabVIEW+Python+openCV

    的,動(dòng)態(tài)鏈接庫(kù)也需要配置,還需要知道各個(gè)參數(shù)含義和類型,這里提供另外一種方法,那就是PythonopenCV工具包,絕對(duì)開源和免費(fèi),LabVIEW可以利用Python節(jié)點(diǎn)調(diào)用Python
    發(fā)表于 12-07 20:59

    如何使用Python中的OpenCV模塊檢測(cè)顏色

    的HSV顏色貼圖獲得較低和較高的 HSV 值。在 OpenCV 中,色調(diào)的值0180,飽和度的值0255。因此,
    發(fā)表于 02-09 16:31

    OpenCV-Python-Toturial-中文版

    python編寫opencv的入門資料,介紹了python的各個(gè)函數(shù)的應(yīng)用
    發(fā)表于 03-23 14:55 ?0次下載

    Python下使用OpenCV的技巧教程與典型應(yīng)用案例

    Python下使用OpenCV教程,本篇將介紹和深度學(xué)習(xí)數(shù)據(jù)處理階段最相關(guān)的基礎(chǔ)使用,并完成4個(gè)有趣實(shí)用的小例子: - 延時(shí)攝影小程序 - 視頻中截屏采樣的小程序 - 圖片數(shù)據(jù)增加(data augmentation)的小工具 -
    發(fā)表于 11-15 18:43 ?1.2w次閱讀

    python圖像處理opencv步驟是怎么樣的

    越來(lái)越覺得python是一強(qiáng)大的工具,處理樣本確實(shí)不錯(cuò)。最近因項(xiàng)目需要涉及圖片處理,所以開始用python調(diào)用opencv,再次覺得python
    發(fā)表于 12-04 15:29 ?4393次閱讀

    簡(jiǎn)述我們?cè)撊绾问褂?b class='flag-5'>OpenCV測(cè)量圖像中物體之間的距離

    計(jì)算物體之間的距離與計(jì)算圖像中物體的大小算法思路非常相似——都是參考對(duì)象開始的。我們將使用0.25美分作為我們的參考對(duì)象,它的寬度為0.955英寸。
    的頭像 發(fā)表于 03-12 11:39 ?3835次閱讀

    如何用PythonOpenCV來(lái)測(cè)量相機(jī)目標(biāo)的距離

    和基于軌跡的跟蹤方法來(lái)確定或者估計(jì)小球在視頻幀中的位置。并且因?yàn)榘羟虻拇笮∈且阎?,所以我也能估?jì)出其本壘的距離。 那是個(gè)有趣的項(xiàng)目,
    的頭像 發(fā)表于 05-20 15:15 ?3914次閱讀
    如何用<b class='flag-5'>Python</b>和<b class='flag-5'>OpenCV</b>來(lái)測(cè)量<b class='flag-5'>相機(jī)</b><b class='flag-5'>到</b>目標(biāo)的<b class='flag-5'>距離</b>

    Linux Debian與Python、Flask和OpenCV識(shí)別面部

    電子發(fā)燒友網(wǎng)站提供《Linux Debian與Python、Flask和OpenCV識(shí)別面部.zip》資料免費(fèi)下載
    發(fā)表于 08-24 10:16 ?2次下載
    Linux Debian與<b class='flag-5'>Python</b>、Flask和<b class='flag-5'>OpenCV</b>識(shí)別面部

    使用opencvpython進(jìn)行智能火災(zāi)檢測(cè)

    電子發(fā)燒友網(wǎng)站提供《使用opencvpython進(jìn)行智能火災(zāi)檢測(cè).zip》資料免費(fèi)下載
    發(fā)表于 11-02 15:08 ?0次下載
    使用<b class='flag-5'>opencv</b>和<b class='flag-5'>python</b>進(jìn)行智能火災(zāi)檢測(cè)

    用于距離測(cè)量和物體檢測(cè)的飛行時(shí)間系統(tǒng)

    飛行時(shí)間(ToF)為此變得越來(lái)越重要。使用ToF技術(shù),光調(diào)制源(例如激光)發(fā)射,然后由傳感器或相機(jī)捕獲從一個(gè)或多個(gè)物體反射的光束。因此,可以通過(guò)發(fā)射光和接收反射光之間的時(shí)間延遲?來(lái)確定距離
    的頭像 發(fā)表于 11-22 14:17 ?708次閱讀
    用于<b class='flag-5'>距離</b>測(cè)量和<b class='flag-5'>物體</b>檢測(cè)的飛行時(shí)間系統(tǒng)

    使用OpenCV實(shí)現(xiàn)目標(biāo)物體相機(jī)距離測(cè)量

    假設(shè)物體的寬度為 W,將其放到離相機(jī)距離為 D 的位置,然后對(duì)物體進(jìn)行拍照。在照片上量出物體的像素寬度 P,于是可以得出計(jì)算
    的頭像 發(fā)表于 11-29 14:47 ?2252次閱讀

    用于距離測(cè)量和物體檢測(cè)的飛行時(shí)間系統(tǒng)

    飛行時(shí)間(ToF)為此變得越來(lái)越重要。使用ToF技術(shù),光調(diào)制源(例如激光)發(fā)射,然后由傳感器或相機(jī)捕獲從一個(gè)或多個(gè)物體反射的光束。因此,可以通過(guò)發(fā)射光和接收反射光之間的時(shí)間延遲?來(lái)確定距離
    的頭像 發(fā)表于 12-09 15:41 ?927次閱讀
    用于<b class='flag-5'>距離</b>測(cè)量和<b class='flag-5'>物體</b>檢測(cè)的飛行時(shí)間系統(tǒng)

    如何使用OpenCVPython圖像中提取感興趣區(qū)域

    今天我們將一起探究如何使用OpenCVPython圖像中提取感興趣區(qū)域(ROI)。 在之間的文章中,我們完成了圖像邊緣提取,例如從臺(tái)球桌中提取桌邊。使用了簡(jiǎn)單的OpenCV
    的頭像 發(fā)表于 02-07 14:42 ?1745次閱讀

    opencv-pythonopencv一樣嗎

    不一樣。OpenCV(Open Source Computer Vision Library)是一個(gè)開源的計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)軟件庫(kù),它提供了大量的圖像和視頻處理功能。OpenCV-Python
    的頭像 發(fā)表于 07-16 10:38 ?880次閱讀