一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

使用OpenCV測量圖像中物體的尺寸大小

 新用戶79878317 2020-01-18

首先,您需要知道類似于比例的概念稱為每度量比的像素pixels per metric ratio)。

近似含義是每個單位指標中包含的像素數(shù)。例如,圖表上的1厘米包含100張圖像。

實際上,相當于引用對象的作用,例如已知地圖上的引用材質(zhì),我們可以使用此引用對象將其轉(zhuǎn)換為地圖上其他對象的大小。

引用對象需要具有兩個重要屬性:

  • 屬性#1:我們應該以可測量的單位(例如毫米,英寸等)知道該對象的尺寸(在寬度或高度方面)。
  • 屬性#2:我們應該能夠在圖像中輕松找到這個參考對象,或者根據(jù)對象的 位置(例如參考對象總是放在圖像的左上角),或者通過外觀(如是獨特的顏色或形狀,獨特且與圖像中的所有其他物體不同)。在任何一種情況下,我們的參考應該 以某種方式唯一可識別。

我們應該能夠輕松地在圖像中找到參考對象,無論是基于對象的位置(例如,參考對象總是放置在圖像的左上角)還是通過外觀(例如,獨特的顏色或形狀,與圖像不同)其他物品)。在任何一種情況下,我們的參考應該以某種方式唯一可識別。

在下面的示例中,我們將使用美國硬幣作為參考對象。在所有示例中,確保它始終是圖像中最左側(cè)的對象。

我們將使用美國四分之一作為參考對象,并確保它始終作為圖像中最左側(cè)的對象放置,使我們可以通過基于其位置對輪廓進行排序來輕松提取它。

通過保證四分之一是最左邊的對象,我們可以從左到右對對象輪廓進行排序,抓住四分之一(它將始終是排序列表中的第一個輪廓),并使用它來定義 pixel_per_metric,我們定義為:

pixels_per_metric = object_width / know_width

美國四分之一的 已知寬度為0.955英寸?,F(xiàn)在,假設我們的 object_width(以像素為單位)計算為150像素寬(基于其關聯(lián)的邊界框)。

因此 pixels_per_metric是:

pixels_per_metric = 150px / 0.955in = 157px

因此暗示在我們的圖像中每0.955英寸大約有157個像素。使用此比率,我們可以計算圖像中對象的大小。

用計算機視覺測量物體的大小

現(xiàn)在我們了解“每度量像素數(shù)”比率,我們可以實現(xiàn)用于測量圖像中對象大小的Python驅(qū)動程序腳本。

打開一個新文件,將其命名為 object_size 。py ,并插入以下代碼:

# import the necessary packages

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)

# construct the argument parse and parse the arguments

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

第2-8行導入我們所需的Python包。我們將在此示例中大量使用imutils包,因此如果您沒有安裝它,請確保在繼續(xù)之前安裝它:

$ pip install imutils

請確保您擁有最新版本

pip install --upgrade imutils

第10行和第11行定義了一個稱為中點的輔助方法 ,顧名思義,它用于計算兩組(x,y)坐標之間 的中點。

然后我們在第14-19行解析命令行參數(shù) 。我們需要兩個參數(shù), - image ,它是包含我們想要測量的對象的輸入圖像的路徑,以及 - width ,它是我們的參考對象的寬度(以英寸為單位),被認為是最左邊的我們的形象 。

我們現(xiàn)在可以加載我們的圖像并預處理它:

# load the image, convert it to grayscale, and blur it slightly

image = cv2.imread(args['image'])

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

gray = cv2.GaussianBlur(gray, (7, 7), 0)

# perform edge detection, then perform a dilation + erosion to

# close gaps in between object edges

edged = cv2.Canny(gray, 50, 100)

edged = cv2.dilate(edged, None, iterations=1)

edged = cv2.erode(edged, None, iterations=1)

# find contours in the edge map

cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,

cv2.CHAIN_APPROX_SIMPLE)

cnts = imutils.grab_contours(cnts)

# sort the contours from left-to-right and initialize the

# 'pixels per metric' calibration variable

(cnts, _) = contours.sort_contours(cnts)

pixelsPerMetric = None

第22-24行從磁盤加載我們的圖像,將其轉(zhuǎn)換為灰度,然后使用高斯濾波器對其進行平滑處理。然后,我們進行邊緣檢測以及擴張+侵蝕,以封閉邊緣圖中邊緣之間的任何間隙(第28-30行)。

第33-35行找到與我們的邊緣圖中的對象相對應的輪廓(即輪廓)。

然后在第39行從左到右(允許我們提取參考對象)對這些輪廓進行排序 。我們還在第40行初始化 pixelPerMetric 值 。

下一步是檢查每個輪廓:

# loop over the contours individually

for c in cnts:

# if the contour is not sufficiently large, ignore it

if cv2.contourArea(c) < 100:

continue

# compute the rotated bounding box of the contour

orig = image.copy()

box = cv2.minAreaRect(c)

box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)

box = np.array(box, dtype='int')

# order the points in the contour such that they appear

# in top-left, top-right, bottom-right, and bottom-left

# order, then draw the outline of the rotated bounding

# box

box = perspective.order_points(box)

cv2.drawContours(orig, [box.astype('int')], -1, (0, 255, 0), 2)

# loop over the original points and draw them

for (x, y) in box:

cv2.circle(orig, (int(x), int(y)), 5, (0, 0, 255), -1)

在 第43行,我們開始在每個輪廓上循環(huán)。如果輪廓不夠大,我們丟棄該區(qū)域,假設它是邊緣檢測過程遺留的噪聲(第45和46行)。

如果輪廓區(qū)域足夠大,我們計算第50-52行上圖像的旋轉(zhuǎn)邊界框 ,特別注意使用 cv2 。cv 。BoxPoints 功能適用于OpenCV 2.4和 cv2 。openCV 3的boxPoints方法。

然后,我們將旋轉(zhuǎn)的邊界框 坐標排列 在左上角,右上角,右下角和左下角,如上周的博文 (第58行)所述。

最后, 第59-63行以綠色繪制對象 的輪廓,然后以小的紅色圓圈繪制邊界框矩形的頂點。

現(xiàn)在我們已經(jīng)訂購了邊界框,我們可以計算出一系列中點:

# unpack the ordered bounding box, then compute the midpoint

# between the top-left and top-right coordinates, followed by

# the midpoint between bottom-left and bottom-right coordinates

(tl, tr, br, bl) = box

(tltrX, tltrY) = midpoint(tl, tr)

(blbrX, blbrY) = midpoint(bl, br)

# compute the midpoint between the top-left and top-right points,

# followed by the midpoint between the top-righ and bottom-right

(tlblX, tlblY) = midpoint(tl, bl)

(trbrX, trbrY) = midpoint(tr, br)

# draw the midpoints on the image

cv2.circle(orig, (int(tltrX), int(tltrY)), 5, (255, 0, 0), -1)

cv2.circle(orig, (int(blbrX), int(blbrY)), 5, (255, 0, 0), -1)

cv2.circle(orig, (int(tlblX), int(tlblY)), 5, (255, 0, 0), -1)

cv2.circle(orig, (int(trbrX), int(trbrY)), 5, (255, 0, 0), -1)

# draw lines between the midpoints

cv2.line(orig, (int(tltrX), int(tltrY)), (int(blbrX), int(blbrY)),

(255, 0, 255), 2)

cv2.line(orig, (int(tlblX), int(tlblY)), (int(trbrX), int(trbrY)),

(255, 0, 255), 2)

第68-70行打開我們訂購的邊界框,然后計算左上角和右上角之間的中點,然后是右下角之間的中點。

我們還將分別計算左上角+左下角和右上角+右下角之間的中點(第74和75行)。

第78-81行在我們的圖像上繪制 藍色中點 ,然后用紫色線連接中點 。

接下來,我們需要 通過調(diào)查我們的引用對象來初始化 pixelPerMetric變量:

# compute the Euclidean distance between the midpoints

dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))

dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))

# if the pixels per metric has not been initialized, then

# compute it as the ratio of pixels to supplied metric

# (in this case, inches)

if pixelsPerMetric is None:

pixelsPerMetric = dB / args['width']

首先,我們計算我們的中點集之間的歐幾里德距離(第90和91行)。該 DA 變量將包含 高度距離(以像素為單位),而 分貝 將保存我們的 寬度的距離。

然后,我們就檢查 96號線,看看我們的 pixelsPerMetric 變量已經(jīng)初始化,如果沒有,我們把 分貝 由我們提供 - 寬度 ,從而使我們每英寸我們的(近似)的像素。

現(xiàn)在我們 已經(jīng)定義了 pixelPerMetric變量,我們可以測量圖像中對象的大?。?/p>

# compute the size of the object

dimA = dA / pixelsPerMetric

dimB = dB / pixelsPerMetric

# draw the object sizes on the image

cv2.putText(orig, '{:.1f}in'.format(dimA),

(int(tltrX - 15), int(tltrY - 10)), cv2.FONT_HERSHEY_SIMPLEX,

0.65, (255, 255, 255), 2)

cv2.putText(orig, '{:.1f}in'.format(dimB),

(int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX,

0.65, (255, 255, 255), 2)

# show the output image

cv2.imshow('Image', orig)

cv2.waitKey(0)

第100行和第101行通過將相應的歐幾里德距離除以pixelsPerMetric 值來計算對象的尺寸(以英寸為單位) (有關此比率的工作原理的詳細信息,請參閱上面的 “每公制像素數(shù)”部分)。

第104-109行在圖像上繪制對象的尺寸 ,而 第112和113行顯示輸出結果。

物體尺寸測量結果

測試我們的 object_size 。py 腳本,只需發(fā)出以下命令:

$ python object_size.py --image images/example_01.png --width 0.955

輸出應如下所示:

圖2:使用OpenCV,Python和計算機視覺+圖像處理技術測量圖像中對象的大小。

如您所見,我們已成功計算出圖像中每個對象的大小 - 我們的名片正確報告為 3.5in x 2in。同樣,我們的鎳被準確地描述為 0.8英寸x 0.8英寸。

然而,并非我們所有的結果都是 完美的。

據(jù)報道,Game Boy墨盒的尺寸略有不同(即使尺寸相同)。兩個季度的高度也 減去了0.1英寸。

那么為什么呢?為什么物體測量不是100%準確?

原因有兩方面:

首先,我匆匆用iPhone拍了這張照片。角度肯定 不是物體上“俯視”(如鳥瞰圖)的完美90度角。如果沒有完美的90度視圖(或盡可能接近它),對象的尺寸可能會出現(xiàn)扭曲。

其次,我沒有使用相機的內(nèi)在和外在參數(shù)來校準我的iPhone。在不確定這些參數(shù)的情況下,照片可能容易發(fā)生徑向和切向鏡頭失真。執(zhí)行額外的校準步驟來查找這些參數(shù)可以“扭曲”我們的圖像并導致更好的對象大小近似(但我將討論失真校正作為未來博客文章的主題)。

同時,在拍攝物體照片時盡量獲得盡可能接近90度的視角 - 這有助于提高物體尺寸估計的準確性。

那就是說,讓我們看一下測量物體尺寸的第二個例子,這次測量藥丸的尺寸:

在美國,所有20,000多種處方藥中有近50%是圓形和/或白色,因此如果我們可以根據(jù)它們的測量值來過濾藥丸,我們就有更好的機會準確識別藥物。

最后,我們有一個最后的例子,這次使用 3.5英寸x 2英寸名片來測量兩個乙烯基EP和一個信封的大小:

$ python object_size.py --image images/example_03.png --width 3.5

同樣,結果不是很完美,但這是由于(1)視角和(2)透鏡畸變,如上所述。

總結

在本文中,我們學習了如何通過使用python和OpenCV來測量圖片中的物體的大小。

我們需要確定pixels per metric比率(單位尺寸像素數(shù)),即在給定的度量(如英寸、毫米、米等)下,像素的數(shù)量。

為了計算這個比率,我們需要一個參考物體,它需要兩點重要的性質(zhì):

1、參考物體需要有含測量單位(英寸、毫米等等)的尺寸

2、無論從物體的位置還是形狀,參考物體都需要容易被找到。

加入上面的性質(zhì)都能滿足,你可以使用參考物體計算pixels per metric比率,并根據(jù)這個計算圖片中物體的大小。

相關資源關注微信公眾號:“圖像算法”或者微信搜索imalg_cn 獲取

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日本不卡视频在线观看| 九九热精品视频在线观看| 欧美日韩免费黄片观看| 九九热九九热九九热九九热| 久久91精品国产亚洲| 日本淫片一区二区三区| 老司机精品国产在线视频| 中文字幕精品一区二区三| 精品一区二区三区免费看| 国产成人精品综合久久久看| 夜夜嗨激情五月天精品| 欧美六区视频在线观看| 99久久精品午夜一区| 国产成人午夜福利片片| 国产乱久久亚洲国产精品| 91精品视频免费播放| 日本熟女中文字幕一区| 精品国产品国语在线不卡| 91欧美日韩中在线视频| 99久久精品午夜一区二区| 好吊日视频这里都是精品| 色一情一乱一区二区三区码| 亚洲国产性感美女视频| 暴力性生活在线免费视频| 精品偷拍一区二区三区| 东京热男人的天堂久久综合| 在线视频三区日本精品| 亚洲另类欧美综合日韩精品| 九九久久精品久久久精品| 国产内射一级一片内射高清| 清纯少妇被捅到高潮免费观看| 殴美女美女大码性淫生活在线播放| 九九热在线免费在线观看| 国产伦精品一一区二区三区高清版| 91人人妻人人爽人人狠狠| 日韩免费国产91在线| 91国自产精品中文字幕亚洲| 亚洲一区二区三区免费的视频| 亚洲免费观看一区二区三区| 女生更色还是男生更色| 久久99青青精品免费|