opencv-python实战---物体长度尺寸测量

该文章介绍了一种基于OpenCV的算法,通过寻找最小面积的矩形来估计其他物体的长度。首先,对图像进行预处理,包括灰度化、高斯模糊和边缘检测。接着,找到所有轮廓并过滤掉面积小于设定阈值的。然后,确定最小矩形的四个顶点并计算其长宽比例。最后,利用这个比例对其他物体的边长进行像素到实际长度的转换,并在图像上标出测量结果。
摘要由CSDN通过智能技术生成

本文的主要算法实现思路:找一个最小面积的矩形提供长宽由此推算出其他物体的长度

博主只写了测量物体最左最右的长度,只能测量矩形。

如图

 最左边的为参照物,然后测量上下两个物体的最左和最右长度。

1,相关库

opencv-python  == 4.7.0.72

numpy == 1.24.2

 2,参数设置

if __name__ == '__main__':
    minArea = 200
    img = cv2.imread(r'D:\1\tp\7.jpg')
    img = cv2.resize(img, (0, 0), None, 0.5, 0.5)
    findDis1(img,W=50,H=50)

minArea为图片中最小的识别面积,小于这个面积将不会给识别

findDis1里面的W,H修改为自己的参照物长,宽

3,提取物体轮廓信息

def getContours(img):
    imgG = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    imgBlur = cv2.GaussianBlur(imgG, (5, 5), 1)
    imgCanny = cv2.Canny(imgBlur, 100, 100)
    img2 = img.copy()
    # kernel = np.ones((5, 5))
    contours, hiearchy = cv2.findContours(imgCanny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    finalCountours = []
    for i in contours:
        area = cv2.contourArea(i)
        if area > minArea:
            # 计算轮廓的周长,true表示轮廓为封闭
            peri = cv2.arcLength(i, True)
            appprox = cv2.approxPolyDP(i, 0.02 * peri, True)
            bbox = cv2.boundingRect(appprox)
            if filter > 0:
                # if (len(appprox)) == filter:
                finalCountours.append([len(appprox), area, appprox, bbox, i])
            else:
                finalCountours.append([len(appprox), area, appprox, bbox, i])
    # 对第二个数值面积进行排序,为升序,找出轮廓的最大值
    finalCountours = sorted(finalCountours, key=lambda x: x[1], reverse=True)
    for con in finalCountours:
        cv2.drawContours(img, con[4], -1, (0, 0, 255), 4)
    return img, finalCountours, img2

前面先对img进行预处理(对输入的图像进行灰度化、高斯模糊和边缘检测操作)

contours,hiearchy=cv2.findContours(imgCanny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

 这个方法适用于opencv4版本的,如过这里报错的话可能是你的版本跟我不一样,如果是opencv3版本的话需要在前面加个参数

4,找到最小面积的轮廓并定位四个点


def reorder(myPoints):
    myPointsNew = np.zeros_like(myPoints)
    myPoints = myPoints.reshape((4, 2))
    add = myPoints.sum(1)
    myPointsNew[0] = myPoints[np.argmin(add)]
    myPointsNew[3] = myPoints[np.argmax(add)]
    diff = np.diff(myPoints, axis=1)
    myPointsNew[1] = myPoints[np.argmin(diff)]
    myPointsNew[2] = myPoints[np.argmax(diff)]
    return myPointsNew

这段代码是返回四个顶点

5,主要计算长度代码解释

 for i in cons3:
            # print(i[1])
            List.append(i[1])
        Min = min(List)
        Min = int(Min)
        inde = List.index(Min)
        nPoints = reorder(cons3[inde][2])
        xw = nPoints[1][0][0] - nPoints[0][0][0]
        xh = nPoints[2][0][1] - nPoints[0][0][1]
        a = xw / W
        a1 = xh / H
        for i in cons3:
            List = []
            for i1 in i[2]:
                List.append([i1[0][0], i1[0][1]])
            Bubbl(List)
            seat = int(len(List) - 2)
            cv2.arrowedLine(img2,List[0], List[1],(255, 0, 255), 2, 8, 0, 0.05)
            cv2.arrowedLine(img2, List[seat], List[seat + 1],(255, 0, 255), 2, 8, 0, 0.05)
            xscd = findDis(List[0],List[1])
            CD = xscd / a
            CD = round(CD,1)
            x, y, w, h = i[3]
            cv2.putText(img2, '{}cm'.format(CD), (x + w, y), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,
                        (255, 0, 255), 1)
            xscd1 = findDis(List[seat], List[seat+1])
            CD1 = xscd1 /a
            CD1 =round(CD1,1)
            cv2.putText(img2, '{}cm'.format(CD1), (x , y + h // 2), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,
                        (255, 0, 255), 1)
        cv2.imshow('img2', img2)
        cv2.waitKey(0)

第一个for是找出最小矩形对应的长度像素值,与我们给出的实际长度做出一个参数a

第二个for是便利每一个矩形图像,并获得最左,最右两个边的长度以及位置信息,并用opencv打印上去主要信息

6,实际效果如图:

7,完整代码可在github上获取

github:https://github.com/weizhi8/opencv.git

地址失效可邮件私聊:2275716724@qq.com

  • 5
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值