OpenCV实现物体尺寸的测量

一 ,项目分析

物体尺寸测量的思路是找一个确定尺寸的物体作为参照物,根据已知的计算未知物体尺寸。

如下图所示,绿色的板子尺寸为220*300(单位:毫米),通过程序计算白色纸片的长度。

主要是通过图像处理技术,实现对一张图片中物体的尺寸测量,具体需求如下:

  1. 读入一张图片,该图片中包含需要进行测量的物体

  2. 对图片进行边缘检测,找到所有的轮廓

  3. 在所有的轮廓中选取面积最大的轮廓,即为所要测量的物体

  4. 对该物体进行透视变换,将其变成一个矩形

  5. 在矩形中,通过线段交叉点的方式,确定出物体的高度和宽度

  6. 将高度和宽度转换成实际尺寸,并在图片上标注出来

  7. 将结果显示在屏幕上。

二,实现流程

  1. 导入必要的库:cv2和numpy。

import cv2
import numpy as np

2.定义了一些参数:缩放比例、输出图片的宽度和高度。

scale = 2
wP = 220 * scale
hP = 300 * scale

3.定义了一个函数getContours,用于获取图像中的轮廓。该函数首先将图像转换为灰度图,然后进行高斯模糊,再进行Canny边缘检测,接着进行膨胀和腐蚀操作,最后使用findContours函数找到所有的外轮廓。根据面积和拐点个数的条件进行轮廓过滤,返回过滤后的轮廓列表。

def getContours(img, cThr=[100, 100], showCanny=False, minArea=1000, filter=0, draw=False):imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1)imgCanny = cv2.Canny(imgBlur, cThr[0], cThr[1])kernel = np.ones((5, 5))imgDial = cv2.dilate(imgCanny, kernel, iterations=3)imgThre = cv2.erode(imgDial, kernel, iterations=2)if showCanny: cv2.imshow('Canny', imgThre)# 寻找所有的外轮廓_, contours, _ = cv2.findContours(imgThre, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)finalCountours = []# 遍历找到的轮廓for i in contours:area = cv2.contourArea(i)  # 轮廓的面积if area > minArea:  # 如果大于设置的最小轮廓值,就往下走peri = cv2.arcLength(i, True)  # 封闭的轮廓的长度approx = cv2.approxPolyDP(i, 0.02 * peri, True)  # 封闭轮廓的拐点bbox = cv2.boundingRect(approx)  # 找到边界框if filter > 0:  # 需不需要根据拐点个数进行过滤轮廓if len(approx) == filter:  # 拐点个数,面积,拐点位置,边界框,轮廓finalCountours.append([len(approx), area, approx, bbox, i])else:finalCountours.append([len(approx), area, approx, bbox, i])finalCountours = sorted(finalCountours, key=lambda x: x[1], reverse=True)  # 根据轮廓大小进行从大到小的排序if draw:  # 是否要画出来轮廓for con in finalCountours:cv2.drawContours(img, con[4], -1, (0, 0, 255), 3)return img, finalCountours

4.   定义了一个函数reorder,用于重新排序四个点的顺序。根据四个点的和、差值的最大值和最小值进行排序,返回重新排序后的点。

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.    定义了一个函数warpImg,用于对图像进行透视变换。根据输入的四个点和输出图像的宽度和高度,使用getPerspectiveTransform函数计算透视变换矩阵,然后使用warpPerspective函数进行透视变换,并对变换后的图像进行裁剪。

def warpImg(img, points, w, h, pad=20):# print(points)points = reorder(points)pts1 = np.float32(points)pts2 = np.float32([[0, 0], [w, 0], [0, h], [w, h]])matrix = cv2.getPerspectiveTransform(pts1, pts2)imgWrap = cv2.warpPerspective(img, matrix, (w, h))imgWrap = imgWrap[pad:imgWrap.shape[0] - pad, pad:imgWrap.shape[1] - pad]return imgWrap

6.    定义了一个函数findDis,用于计算两个点之间的距离。

def findDis(pts1, pts2):return ((pts2[0] - pts1[0]) ** 2 + (pts2[1] - pts1[1]) ** 2) ** 0.5

7.   读取输入的图像,并将其缩放到指定的尺寸。

path = 'E:\All_in\opencv\chicun.png'
img = cv2.imread(path)
img = cv2.resize(img, (0, 0), None, 0.18, 0.18)

8.    使用getContours函数获取图像中的轮廓,设定最小轮廓面积为8000,拐点个数为4,返回过滤后的轮廓列表。

img, conts = getContours(img, minArea=8000, filter=4)

9.   判断是否存在轮廓,若存在,则找到最大轮廓的拐点位置,使用warpImg函数对图像进行透视变换,并返回变换后的图像。

if len(conts) != 0:biggest = conts[0][2]  # 最大轮廓的拐点位置# print(biggest)imgWrap = warpImg(img, biggest, wP, hP)

10.    对变换后的图像再次使用getContours函数获取轮廓,设定最小轮廓面积为2000,拐点个数为4,返回过滤后的轮廓列表。

    imgContours2, conts2 = getContours(imgWrap, minArea=2000, filter=4, cThr=[50, 50])

11.    遍历过滤后的轮廓列表,对每个轮廓绘制多边形和箭头,并计算出两个方向的长度,然后在图像上标注长度信息。

   if len(conts) != 0:for obj in conts2:cv2.polylines(imgContours2, [obj[2]], True, (0, 255, 0), 2)nPoints = reorder(obj[2])nW = round((findDis(nPoints[0][0] // scale, nPoints[1][0] // scale) / 10), 1)nH = round((findDis(nPoints[0][0] // scale, nPoints[2][0] // scale) / 10), 1)# 创建箭头cv2.arrowedLine(imgContours2, (nPoints[0][0][0], nPoints[0][0][1]), (nPoints[1][0][0], nPoints[1][0][1]),(255, 0, 255), 3, 8, 0, 0.05)cv2.arrowedLine(imgContours2, (nPoints[0][0][0], nPoints[0][0][1]), (nPoints[2][0][0], nPoints[2][0][1]),(255, 0, 255), 3, 8, 0, 0.05)x, y, w, h = obj[3]cv2.putText(imgContours2, '{}cm'.format(nW), (x + 30, y - 10), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,(255, 0, 255), 2)cv2.putText(imgContours2, '{}cm'.format(nH), (x - 70, y + h // 2), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,(255, 0, 255), 2)

12 . 显示结果图像和原始图像,并等待按下任意键关闭窗口。

​
cv2.imshow('background', imgContours2)cv2.imshow('Original', img)
cv2.waitKey(0)​

三 ,结果展示

四 ,应用前景

  1. 工业测量:在工业领域中,Opencv测尺寸可以用于检测零件尺寸是否符合规格要求。比如,在生产线上,可以通过拍摄零件图片,利用Opencv测量零件的长度、宽度、直径等参数,以确保产品质量。

  2. 医学影像:Opencv测尺寸可以应用于医学影像领域中,例如在CT、MRI等医学影像中,测量肿瘤大小、血管直径等。这对于医生来说是非常重要的,可以帮助他们做出准确的诊断和治疗方案。

  3. 建筑测量:在建筑和房地产领域中,Opencv测尺寸可以用于测量建筑物的尺寸、房间面积等。通过拍摄建筑物的照片,利用Opencv进行测量,可以帮助建筑师、设计师和房地产开发商进行规划和设计。

  4. 车辆测量:Opencv测尺寸可以应用于交通领域,例如测量车辆的长度、宽度、高度等。这对于道路设计、桥梁设计、停车场规划等方面是非常重要的。

  5. 教育培训:Opencv测尺寸可以用于教育培训领域中,例如在物理实验中测量物体的大小、重量等。通过利用Opencv进行测量,可以帮助学生更直观地理解和掌握物理概念。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/118074.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C盘满了怎么清理文件?

电脑的C盘是我们电脑存储系统文件和应用程序的一个重要盘符,很多人经常会遇到C盘空间不足的问题;虽然我们可以通过卸载程序或者删除文件来释放空间,但是在这个过程中往往会误删掉一些重要的文件,造成部分程序可能无法正常使用。 因…

【EI会议征稿】第五届大数据与信息化教育国际学术会议(ICBDIE 2024)

【有往届检索记录】第五届大数据与信息化教育国际学术会议(ICBDIE 2024) 2023 5th International Conference on Big Data and Informatization Education 第五届大数据与信息化教育国际学术会议(ICBDIE 2024)定于2024年01月19-…

怒刷LeetCode的第28天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一:动态规划 方法二:迭代 方法三:斐波那契数列公式 第二题 题目来源 题目内容 解决方法 方法一:栈 方法二:路径处理类 方法三:正则表达式 方法…

机器学习(新手入门)-线性回归 #房价预测

题目:给定数据集dataSet,每一行代表一组数据记录,每组数据记录中,第一个值为房屋面积(单位:平方英尺),第二个值为房屋中的房间数,第三个值为房价(单位:千美元…

RTL SDR的PYTHON开发环境搭建

不得不说RTL SDR真是神器,直接把SDR的入门门槛拉低到了几十块钱。对于RTL SDR的学习开发,有大佬写的《Software_Defined_Radio_using_MATLAB_Simulink_and_the_RTL-SDR》,另外,除了MATLAB,近些年爆火的PYTHON当然也是可…

系统集成测试(SIT)/系统测试(ST)/用户验收测试(UAT)

文章目录 单元测试集成测试系统测试用户验收测试黑盒测试白盒测试压力测试性能测试容量测试安全测试SIT和UAT的区别 单元测试 英文 unit testing,缩写 UT。测试粒度最小,一般由开发小组采用白盒方式来测试,主要测试单元是否符合“设计”。 …

智能振弦传感器:参数智能识别技术的重要科技创新

智能振弦传感器:参数智能识别技术的重要科技创新 智能振弦传感器是一种能够自动识别传感器参数的高科技产品。它的研发得益于河北稳控科技的不断创新和努力,其电子标签专用读数模块模块TR01将传感器生产和标定过程实现了自动化。该模块将温度电阻两芯线…

Mysql第四篇---数据库索引优化与查询优化

文章目录 数据库索引优化与查询优化索引失效案例数据准备1. 全值匹配2 最佳左前缀法则(联合索引)主键插入顺序4 计算、函数导致索引失效5 类型转换(自动或手动)导致索引失效6 范围条件右边的列索引失效7 不等于(!或者<>)索引失效8 is null可以使用索引, is not null无法使…

【Mongo】数据删了磁盘空间但没有减少

Author:skate Time:2023/10/22 一、问题描述 产线用户反馈&#xff0c;一个华为云的mongo实例磁盘空间告警&#xff0c;使用率超过90%&#xff08;使用状况 1630.9/1800GB&#xff09;&#xff0c;让其通过数据库运维平台找到占用大空间的表&#xff0c;然后清理历史数据&…

爱创科技携手洽洽食品,探索渠道数字化最优解!

坚果的下半场&#xff0c;是从吃到喝。 消费升级大潮下&#xff0c;健康养生理念逐渐深入人心。以“天然健康”为核心的食品新消费潮流正加速形成&#xff0c;一个个打着“美味与营养”黄金设定的品类风口正被不断创建&#xff0c;其中人气有增无减的当属植物基饮品。据相关报告…

Anaconda/minAnaconda下配置虚拟环境并安装pytorch相关

Anaconda/minAnaconda下配置虚拟环境并安装pytorch相关 官网下载对应版本anaconda/minAnaconda进入Anaconda Prompt创建虚拟环境 conda create -n 虚拟环境名 python版本 -c https://mirrors.bfsu.edu.cn/anaconda/pkgs/main查看当前环境&#xff0c;如果之前anaconda3文件夹…

docker和k8s之间的关系

一句话总结&#xff1a;Docker只是容器的一种&#xff0c;它面向的是单体&#xff0c;K8S可以管理多种容器&#xff0c;它面向的是集群&#xff0c;Docker可以作为一种容器方案被K8S管理。 https://baijiahao.baidu.com/s?id1763716289717819767&wfrspider&forpc 背…

【idea】使用教程:idea 打开项目、配置、项目打包详细教程

目录 一、配套软件安装 二、打开已有项目 三、配置 jdk 四、项目打包 五、服务器首次创建目录 &#xff08;1&#xff09;后端代码目录 &#xff08;2&#xff09;前端代码目录 &#xff08;3&#xff09; 打包后的代码包上传到服务器上 一、配套软件安装 【idea】wi…

计算机算法分析与设计(20)---回溯法(0-1背包问题)

文章目录 1. 题目描述2. 算法思路3. 例题分析4. 代码编写 1. 题目描述 对于给定的 n n n 个物品&#xff0c;第 i i i 个物品的重量为 W i W_i Wi​&#xff0c;价值为 V i V_i Vi​&#xff0c;对于一个最多能装重量 c c c 的背包&#xff0c;应该如何选择放入包中的物品…

Git报错解决

本篇主要汇总在使用 Git 进行提交和拉取文件时&#xff0c;遇到的问题的解决方案&#xff0c;以便下次查找。 1 关于使用Git出现“git Failed to connect to 127.0.0.1 port xxxx: Connection refused”的问题解决方案 1. 问题描述 在使用 git 拉取、提交代码的时候&#xff…

一款集成了主流大语言模型以及绘图模型的 APP, 采用 Flutter 开发,代码完全开源!!

一款集成了主流大语言模型以及绘图模型的 APP&#xff0c; 采用 Flutter 开发&#xff0c;代码完全开源&#xff0c;支持以下功能&#xff1a; 支持 OpenAI 的 GPT-3.5&#xff0c;GPT-4 大语言模型支持 Anthropic 的 Claude instant&#xff0c;Claude 2.0 大语言模型支持国产…

【React】编程式路由,push 与 replace,withRouter,BrowserRouter 和 HashRouter 的区别

push 与 replace 模式 默认情况下&#xff0c;开启的是 push 模式&#xff0c;也就是说&#xff0c;每次点击跳转&#xff0c;都会向栈中压入一个新的地址&#xff0c;在点击返回时&#xff0c;可以返回到上一个打开的地址 有时候页面不需要这么繁琐的跳转&#xff0c;我们可以…

uniapp map polygons 区域填充色(fillColor)在ios显示正常,但在安卓手机显示是黑色的,怎么解决?

uniapp map polygons 区域填充色&#xff08;fillColor&#xff09;在ios显示正常&#xff0c;但在安卓手机显示是黑色的,怎么解决&#xff1f; <MapPage :longitude"item.centerCoord[0]" :latitude"item.centerCoord[1]":polygons"[{ points: it…

Word docx转html和markdown

Pypandoc使用pandoc来进行各种文本格式的转换。 安装 # 不带pandoc执行库 pip install pypandoc# 自带pandoc pip install pypandoc_binary使用 import pypandoc# convert all markdown files in a chapters/ subdirectory. pypandoc.convert_file(chapters/*.md, docx, out…

1.初识MySQL

初识 MySQL 1.服务器处理客户端请求2.常用存储引擎3.关于存储引擎的一些操作3.1 查看当前服务器程序支持的存储引擎3.2 设置表的存储引擎3.2.1 创建表时指定存储引擎3.2.2 修改表的存储引擎 4.总结 MySQL 默认采用 TCP/IP 的方式来处理客户端与服务器连接过程。 1.服务器处理客…