Python+Opencv测量物体之间的距离
目錄
- 一、場景需求解讀
- 二、算法原理簡介
- 三、算法實現步驟
- 四、算法代碼實現
- 五、算法效果展示與分析
- 參考資料
- 注意事項
一、場景需求解讀
??在現實場景中,我們可能會遇到這個問題,即需要自動的測量圖像中的不同目標之間的距離。通過這個測量,我們可以明確的知道圖像中各個目標的位置以及各個目標之間的距離,便于我們做出合理的規劃。本文是在該博客的基礎上面進行拓展而來的。下圖展示了一個樣例圖片,即圖中最左邊的是我們的參考目標,我們需要做的就是自動的確定當前的參考目標和其它對象之間的距離。
二、算法原理簡介
?? 整個算法的核心是根據參考目標的實際距離和歐式距離計算出相應的像素比。首先需要進行一系列的像素預處理操作,包括灰度變換,高斯濾波,邊緣檢測等;然后使用輪廓檢測算法獲取到圖中的參考目標和其它目標;最后將像素比分別應用在參考目標和其它目標之間的4個頂點和中心點上面。
三、算法實現步驟
步驟1-讀取輸入圖片;
步驟2-執行灰度變換;
步驟3-進行高斯濾波去除一部分噪聲;
步驟4-執行Canny邊緣檢測來獲取目標的邊緣映射,并使用膨脹和腐蝕操作來進行后處理;
步驟5-在邊緣映射中尋找合適的輪廓;
步驟6-計算輪廓的外接矩形,并對輪廓進行排序;
步驟7-根據參考目標和實際距離的大小來計算出像素比;
步驟8-根據參考目標和其它目標之間的坐標信息計算并顯示結果。
四、算法代碼實現
# coding=utf-8 # 導入相應的pthon包 from scipy.spatial import distance as dist from imutils import perspective from imutils import contours import numpy as np import argparse import imutils import cv2# 計算中心點函數 def midpoint(ptA, ptB):return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)# 進行參數配置和解析 ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required=True, help="path to the input image") ap.add_argument("-w", "--width", type=float, required=True, help="width of the left-most object in the image (in inches)") args = vars(ap.parse_args())# 讀取圖片 image = cv2.imread(args["image"]) # 執行灰度變換 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 執行高斯濾波 gray = cv2.GaussianBlur(gray, (7, 7), 0)# 執行Canny邊緣檢測 edged = cv2.Canny(gray, 50, 100) # 執行腐蝕和膨脹后處理 edged = cv2.dilate(edged, None, iterations=1) edged = cv2.erode(edged, None, iterations=1)# 在邊緣映射中尋找輪廓 cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts)# 對輪廓點進行排序 (cnts, _) = contours.sort_contours(cnts) # 設置顯示顏色 colors = ((0, 0, 255), (240, 0, 159), (0, 165, 255), (255, 255, 0), (255, 0, 255)) refObj = None# 循環遍歷每一個輪廓點 for c in cnts:# 過濾點太小的輪廓點if cv2.contourArea(c) < 100:continue# 計算最小的外接矩形box = cv2.minAreaRect(c)box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)box = np.array(box, dtype="int")# 對輪廓點進行排序box = perspective.order_points(box)# 計算BB的中心點cX = np.average(box[:, 0])cY = np.average(box[:, 1])if refObj is None:# 獲取4個坐標點并計算中心點坐標(tl, tr, br, bl) = box(tlblX, tlblY) = midpoint(tl, bl)(trbrX, trbrY) = midpoint(tr, br)# 計算中心點之間的歐式距離D = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))# 獲取計算結果refObj = (box, (cX, cY), D / args["width"])continue# 繪制輪廓orig = image.copy()cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 2)cv2.drawContours(orig, [refObj[0].astype("int")], -1, (0, 255, 0), 2)# 進行坐標堆疊refCoords = np.vstack([refObj[0], refObj[1]])objCoords = np.vstack([box, (cX, cY)])# 遍歷所有的坐標點for ((xA, yA), (xB, yB), color) in zip(refCoords, objCoords, colors):# 繪制點并連接為直線cv2.circle(orig, (int(xA), int(yA)), 5, color, -1)cv2.circle(orig, (int(xB), int(yB)), 5, color, -1)cv2.line(orig, (int(xA), int(yA)), (int(xB), int(yB)), color, 2)# 計算坐標之間的歐式距離并及進行距離轉換D = dist.euclidean((xA, yA), (xB, yB)) / refObj[2](mX, mY) = midpoint((xA, yA), (xB, yB))cv2.putText(orig, "{:.1f}in".format(D), (int(mX), int(mY - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.55, color, 2)# 顯示結果cv2.imshow("Image", orig)cv2.waitKey(0)五、算法效果展示與分析
python distance_between.py --image images/example_01.png --width 0.955
python distance_between.py --image images/example_02.png --width 0.955
python distance_between.py --image images/example_03.png --width 3.5
??上圖展示了不同圖片的測試結果。通過上面的觀察,我們可以獲得一些有用的信息,即該算法可以準確的檢測到不同的目標,并計算出參考目標和其它目標之間的距離,具體包括4個頂點和中心點之間的距離。通過以上的操作,我們就可以明確的知道圖中各個目標之間的相對距離。
參考資料
[1] 參考鏈接
注意事項
[1] 該博客是本人原創博客,如果您對該博客感興趣,想要轉載該博客,請與我聯系(qq郵箱:1575262785@qq.com),我會在第一時間回復大家,謝謝大家的關注.
[2] 由于個人能力有限,該博客可能存在很多的問題,希望大家能夠提出改進意見。
[3] 如果您在閱讀本博客時遇到不理解的地方,希望您可以聯系我,我會及時的回復您,和您交流想法和意見,謝謝。
[4] 本文測試的圖片可以通過該鏈接進行下載。網盤鏈接- 提取碼:vd2t 。
[5] 本人業余時間承接各種本科畢設設計和各種小項目,包括圖像處理(數據挖掘、機器學習、深度學習等)、matlab仿真、python算法及仿真等,有需要的請加QQ:1575262785詳聊,備注“項目”!!!
總結
以上是生活随笔為你收集整理的Python+Opencv测量物体之间的距离的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html启动本地.exe文件
- 下一篇: 垃圾分类资料汇总