<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用Python和OpenCV查找從相機到物體/標記的距離

新機器視覺 ? 來源: 程序員阿德 ? 作者: 程序員阿德 ? 2022-11-29 17:44 ? 次閱讀

攝像頭測距就是計算照片中的目標物體到相機的距離??梢允褂孟嗨迫切危╰riangle similarity)方法實現,或者使用更復雜但更準確的相機模型的內參來實現這個功能。

使用相似三角形計算物體到相機的距離

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

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

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

此時移動相機離物體更近或者更遠,我們可以應用相似三角形得到計算物體到相機的距離的公式: dd1d3886-6d8f-11ed-8abf-dac502259ad0.svg

原理大概就是這樣,接下來使用 OpenCV 來實現。

獲取目標輪廓

# 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)

定義一個 find_marker 函數,接收一個參數 iamge,用來找到要計算距離的物體。這里我們用一張 8.5 x 11 英寸的紙作為目標物體。第一個任務是在圖片中找到目標物體。

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

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

做了這幾步后圖片看起來是這樣的:

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

現在已經可以清晰地看到這張紙的邊緣,接下來需要做的是找出這張紙的輪廓。

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 函數找到圖片中的眾多輪廓,然后獲取其中面積最大的輪廓,并假設這是目標物體的輪廓。

這種假設只適用于我們這個場景,在實際使用時,在圖片中找出目標物體的方法與應用場景有很大關系。

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

注意: 關于這個方法,詳情可以查看這篇文章,用于構建一個移動文本掃描工具。

我們也可以根據顏色特征在圖片中找到目標物體,因為目標物體和背景的顏色有著很明顯的不同。還可以應用關鍵點檢測(keypoint detection),局部不變性描述子(local invariant descriptors)和關鍵點匹配(keypoint matching)來尋找目標。但是這些方法不在本文的討論范圍內,而且高度依賴具體場景。

我們現在得到目標物體的輪廓了,find_marker 函數最后返回的是包含輪廓 (x, y) 坐標、像素長度和像素寬度的邊框,

計算距離

接下來該使用相似三角形計算目標到相機的距離。

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 函數傳入目標的實際寬度,計算得到的焦距和圖片上目標的像素寬度,就可以通過相似三角形公式計算目標到相機的距離了。

下面是調用 distance_to_camera 函數之前的準備:

# 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

首先是測量目標物體的寬度,和目標物體到相機的距離,并根據上面介紹的方法計算相機的焦距。其實這些并不是真正的攝像機標定。真正的攝像機標定包括攝像機的內參,相關知識可以可以查看這里。

使用 cv2.imread 函數從磁盤加載圖片,然后通過 find_marker 函數得到圖片中目標物體的坐標和長寬信息,最后根據相似三角形計算出相機的焦距。

現在有了相機的焦距,就可以計算目標物體到相機的距離了。

# 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 循環遍歷每個圖片,計算每張圖片中目標對象到相機的距離。在結果中,我們根據得到的輪廓信息將方框畫了出來,并顯示出了距離。下面是得到的幾個結果圖:

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

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

總結

通過這篇文章,我們學會了使用相似三角形計算圖片中一個已知物體到相機的距離。

需要先測量出目標物體的實際寬度和目標物體到相機的距離,然后使用圖像處理的方法自動計算圖片中目標物體的像素寬度,并使用相似三角形計算出相機的焦距。

根據相機的焦距就可以計算圖片中的目標物體到相機的距離。

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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 機器視覺
    +關注

    關注

    161

    文章

    4124

    瀏覽量

    118853
  • 函數
    +關注

    關注

    3

    文章

    4117

    瀏覽量

    61507
  • OpenCV
    +關注

    關注

    29

    文章

    612

    瀏覽量

    40890
  • python
    +關注

    關注

    52

    文章

    4700

    瀏覽量

    83643

原文標題:使用OpenCV實現攝像頭測距

文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    【芯靈思A83T試用申請】嵌入式視覺--遠距離物體跟蹤與定位

    OpenCV環境,連接工業相機3)物體跟蹤與定位算法的實現4)結項與項目演示具體描述:本方案擬以嵌入式開發為基礎,基于CMOS相機和數字圖像處理技術的遠
    發表于 04-27 14:18

    LabVIEW+Python+openCV

    的,動態鏈接庫也需要配置,還需要知道各個參數含義和類型,這里提供另外一種方法,那就是PythonopenCV工具包,絕對開源和免費,LabVIEW可以利用Python節點調用Python
    發表于 12-07 20:59

    如何使用Python中的OpenCV模塊檢測顏色

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

    OpenCV-Python-Toturial-中文版

    python編寫opencv的入門資料,介紹了python的各個函數的應用
    發表于 03-23 14:55 ?0次下載

    輪廓查找基礎_《OpenCV3編程入門》書本配套源代碼

    OpenCV3編程入門》書本配套源代碼:輪廓查找基礎
    發表于 06-06 15:39 ?4次下載

    Python下使用OpenCV的技巧教程與典型應用案例

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

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

    越來越覺得python是一強大的工具,處理樣本確實不錯。最近因項目需要涉及到圖片處理,所以開始用python調用opencv,再次覺得python真乃神器也!
    發表于 12-04 15:29 ?4272次閱讀

    使用opencvpython進行智能火災檢測

    電子發燒友網站提供《使用opencvpython進行智能火災檢測.zip》資料免費下載
    發表于 11-02 15:08 ?0次下載
    使用<b class='flag-5'>opencv</b>和<b class='flag-5'>python</b>進行智能火災檢測

    OpenCV如何幫助相機自動化視覺跟蹤

    OpenCV對學術用途和商業用途都免費。它有C++、C、Python和Java的接口,并且支持Windows、Linux、MacOS、iOS和Android系統。在我的OpenCV教程系列中,我們將專注于使用樹莓派(當然,操作系
    發表于 11-29 10:36 ?668次閱讀

    使用OpenCV實現目標物體相機距離測量

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

    OpenCV常用的 7 個示例(Python版)1

    OpenCV是計算機視覺領域最流行的庫之一。它最初是用 C 和 C++ 編寫的?,F在也可以在 Python 中使用。它最初是由英特爾開發的。該庫是一個跨平臺的開源庫。免費使用。OpenCV 庫是一個高度優化的庫,其主要重點是實時
    的頭像 發表于 02-07 16:23 ?1016次閱讀

    OpenCV常用的 7 個示例(Python版)2

    OpenCV是計算機視覺領域最流行的庫之一。它最初是用 C 和 C++ 編寫的?,F在也可以在 Python 中使用。它最初是由英特爾開發的。該庫是一個跨平臺的開源庫。免費使用。OpenCV 庫是一個高度優化的庫,其主要重點是實時
    的頭像 發表于 02-07 16:23 ?877次閱讀

    OpenCV常用的 7 個示例(Python版)3

    OpenCV是計算機視覺領域最流行的庫之一。它最初是用 C 和 C++ 編寫的?,F在也可以在 Python 中使用。它最初是由英特爾開發的。該庫是一個跨平臺的開源庫。免費使用。OpenCV 庫是一個高度優化的庫,其主要重點是實時
    的頭像 發表于 02-07 16:23 ?835次閱讀

    Python實現OpenCV的安裝與使用

      本文實例講述了 Python 實現 OpenCV 的安裝與使用。分享給大家供 大家參考,具體如下:  由于下一步要開始研究下深度學習,而深度學習領域很多的算法和應 用都是用 Python 來實現
    發表于 07-20 11:46 ?7次下載

    Vulture 可在Python程序中查找未使用的代碼

    Vulture 可以在Python程序中查找未使用的代碼。這對于清理和查找大型項目(代碼庫)中的錯誤非常有用。 不過由于Python的動態特性,像 Vulture 這樣的靜態代碼分析器
    的頭像 發表于 10-21 10:28 ?281次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>