OpenCV: 测量物体大小

- 2 分钟前

要测量目标图片中的物体大小,必须要使用一个参考物体的尺寸,通过计算 参考物体/参考物体的像素数 得到一个比值。其他的物体只需要通过 **物体像素数 $\times$ 这个比值 **就可以得到物体的尺寸。将这个比值可以定义为 $R_{PM}$.

The Pixels per Metric Ratio

为了测量图片中的物体尺寸,我们首先需要标定一个参考物体,定义参考物体中的以下两个关键属性:

在本次实验的参考图像中是一枚美分硬币。确定了参考物体是最左侧的物体,就可以从左到右遍历每一个目标并计算每个物体的尺寸。通过参考物体计算 $R_{PM} = D_{img} / D_{obj}$ ,其中,分母为物体在图片中的长度,分子为物体的实际长度。

则物体的实际长度 $D_{obj} = D_{img} / R_{PM}$ 。

Code

对图像进行预处理,灰度化、边缘提取等操作。

# 读取输入图片
image = cv2.imread(args["image"])
# 输入图片灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 对灰度图片执行高斯滤波
gray = cv2.GaussianBlur(gray, (7, 7), 0)
showImage("gaussian blur", gray)

# 对滤波结果做边缘检测获取目标
edged = cv2.Canny(gray, 50, 100)
# 使用膨胀和腐蚀操作进行闭合对象边缘之间的间隙
edged = cv2.dilate(edged, None, iterations=1)
edged = cv2.erode(edged, None, iterations=1)
showImage("edged", edged)

在边缘计算过后的图像中寻找物体轮廓:

# 在边缘图像中寻找物体轮廓(即物体)
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
                        cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

# 对轮廓按照从左到右进行排序处理
(cnts, _) = contours.sort_contours(cnts)

循环遍历每一个轮廓,并根据物体的轮廓计算出外切矩形框并在图形中进行绘制。通过中点函数计算出各个中点的坐标,再通过计算中心店的欧式距离得到物体在图片中的距离$D_{img}$, 包括长度和宽度,由于我们的参考物体为正方形,所以根据长度或宽度计算均可。

    # 根据物体轮廓计算出外切矩形框
    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")

    # 按照top-left, top-right, bottom-right, bottom-left的顺序对轮廓点进行排序,并绘制外切的BB,用绿色的线来表示
    box = perspective.order_points(box)
    cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 2)

若当前物体为第一个物体,即参考物体,计算 $R_{PM}$ 的值:

    if pixelsPerMetric is None:
        pixelsPerMetric = dB / args["width"]

通过 $R_{PM}$ 计算每个物体的实际长度:

    # 计算目标的实际大小(宽和高),用英尺来表示
    dimA = dA / pixelsPerMetric
    dimB = dB / pixelsPerMetric

Results

python3 measure_oj_size.py --image ./pic/size_of_objects_reference.jpg --width 0.955

results

results


source code

Reference post

Inger Chao(赵琦)

Inger Chao(赵琦)

CS 研二在读

Inger Notes © 2020
rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora qq quora wechat