1、效果展示

我们将以两种方式来展示我们这个项目的效果。

下面这是视频的实时检测,我分别用了盒子和盖子来检测,按理来说效果不应该怎么差的,但我实在没有找到合适的背景与物体。且我的摄像头使用的是外设,我不得不手持,所以存在一点点的抖动,但我可以保证,它是缺少了适合检测物体与背景。

我使用手机拍了一张照片并经过了ps修改了背景,效果不错。

2、项目介绍

本项目中,我将选用A4纸张为背景,找到放在该区域中对象的长、宽。打印出相关的数值。

3、项目搭建

所有的资源,你都可以在我的GitHub上找到,我将在末尾附上链接

4、utils.py文件代码展示与讲解

在项目当中,我将引入utils,而utils是适用于在我们项目中所写的的文件。有了对它的理解能帮助我们更好的理解本项目,所以我觉得有必要在此叙述一番。

import cv2
import numpy as npdef 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, hiearchy = 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, finalCountoursdef reorder(myPoints):# print(myPoints.shape)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 myPointsNewdef 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)imgWarp = cv2.warpPerspective(img, matrix, (w, h))imgWarp = imgWarp[pad:imgWarp.shape[0] - pad, pad:imgWarp.shape[1] - pad]return imgWarpdef findDis(pts1, pts2):return ((pts2[0] - pts1[0]) ** 2 + (pts2[1] - pts1[1]) ** 2) ** 0.5

接下来,我将按照惯例讲解,我们就以每个函数的意义来讲。

  1. getContours()函数,曾在我以前的博客中出现过。正如它的命名,我们是为了得到轮廓。将原始图像依次经过这些转化:灰度图像、高斯模糊、canny检测边缘、膨胀、侵蚀等。 cv2.findContours()从图像ROI中提取轮廓,然后在整个图像上下文中分析轮廓,参数cv2.RETR_EXTERNAL将会获取外部边缘;                                                      cv2.contourArea()计算轮廓面积;                                                                cv2.contourArea()计算轮廓周长或曲线长度;                                                    cv2.approxPolyDP()以指定精度近似多边形曲线;                                            cv2.boundingRect()函数计算并返回指定点集或灰度图像非零像素的最小右上边界矩形;       之后用finalCountours这个空列表来接受我们需要用到的信息,再对其轮廓的大小进行排序,因为我们需要的是最大的边界框。                                                              cv2.drawContours()绘制轮廓轮廓或填充轮廓,最后返回img, finalCountours。
  2. reorder函数,myPointsNew = np.zeros_like(myPoints),返回与myPoints具有相同形状和类型的零数组,在打印了myPoints.shape,它所返回的值是(4,1,2),不难理解,4指的是四个点,2指的是x,y,我们不需要中间的1,所以要对其进行重塑。np.argmin返回沿轴的最小值的索引,np.argmax返回沿轴的最大值的索引。所以此函数的作用是将顺序改为最下面的顺序。

      4.warpImg()函数,其实就是透视变换,详细的函数可以回头复习一下Opencv的文档,我在此不做多的讲述。

5.findDis()函数我们用一张图来解释,个人手绘:

4、项目代码展示与讲解

import cv2
import utils###################################
webcam = False
path = '1.png'
cap = cv2.VideoCapture(1)
cap.set(10, 160)
cap.set(3, 1920)
cap.set(4, 1080)
scale = 3
wP = 210 * scale
hP = 297 * scale
###################################while True:if webcam:success, img = cap.read()else:img = cv2.imread(path)imgContours, conts = utils.getContours(img, minArea=50000, filter=4)if len(conts) != 0:biggest = conts[0][2]# print(biggest)imgWarp = utils.warpImg(img, biggest, wP, hP)imgContours2, conts2 = utils.getContours(imgWarp,minArea=2000, filter=4,cThr=[50, 50], draw=False)if len(conts) != 0:for obj in conts2:cv2.polylines(imgContours2, [obj[2]], True, (0, 255, 0), 2)nPoints = utils.reorder(obj[2])nW = round((utils.findDis(nPoints[0][0] // scale, nPoints[1][0] // scale) / 10), 1)nH = round((utils.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.5,(255, 0, 255), 2)cv2.putText(imgContours2, '{}cm'.format(nH), (x - 70, y + h // 2), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1.5,(255, 0, 255), 2)cv2.imshow('A4', imgContours2)img = cv2.resize(img, (0, 0), None, 0.5, 0.5)cv2.imshow('Original', img)if cv2.waitKey(1) & 0xFF ==27:break

那么,本项目的代码我看了一下,将utils.py文件看懂之后,不难理解,所以本项目我就不仔细讲解了。

5、项目资源

GitHub:https://github.com/Auorui/Opencv-project-training/tree/main/Opencv%20project%20training/09%20Object%20Size%20Measurement

6、项目总结

本项目主要是运用了之前扫描文档的思想,以A4纸为背景,检测其中区域的物体长和宽。我的摄像头无法固定,所以是手持的,且由于我在寝室里面是真的没有找到合适的测量物体以及背景色(全是米色或原木色的)。所以效果有所欠缺,但经过ps修改的图片,检测的效果还是很不错的。

那么祝你在本项目中玩的开心,否则我会在下一次项目中见到你!!!

Opencv项目实战:09 物体尺寸测量相关推荐

  1. opencv实战---物体尺寸测量

    物体尺寸测量的思路是找一个确定尺寸的物体作为参照物,根据已知的计算未知物体尺寸. 如下图所示,绿色的板子尺寸为220*300(单位:毫米),通过程序计算白色纸片的长度. 目录 1.相关库 2.读图+图 ...

  2. Opencv项目实战-信用卡数字识别

    Opencv项目实战:信用卡数字识别 导入库,定义展示函数 import cv2 import numpy as np from imutils import contours import myut ...

  3. 基于C++的OpenCV项目实战——文档照片转换成扫描文件

    基于C++的OpenCV项目实战--文档照片转换成扫描文件 一.背景 前段时间都是基于Python的OpecCV进行一些学习和实践,但小的知识点并没有应用到实际的项目中:并且基于Python的版本的移 ...

  4. 【Opencv项目实战】背景替换:动态背景移除与替换(cvzone+MediaPipe)

    文章目录 一.项目思路 二.环境布置 2.1.cvzone安装 2.2.MediaPipe安装 2.3.常见问题 2.4.注意事项 三.算法详解 3.1.segmentor.removeBG():去除 ...

  5. python编程实现图片内多个物体尺寸测量

    要实现图片内多个物体尺寸测量,你可以使用计算机视觉库,如 OpenCV 来实现. 首先,你需要读取图片,然后对图像进行预处理,以便更容易地检测到图像中的物体.例如,你可以使用边缘检测算法来提取边缘,或 ...

  6. Opencv项目实战:14 手势控制音量

    目录 0.项目介绍 1.项目展示 2.项目搭建 3.项目的代码与讲解 4.项目资源 5.项目总结 0.项目介绍 本篇与上一篇有很多联系,大家可以看看这篇Opencv项目实战:13 手部追踪,我们将根据 ...

  7. C#实现物体尺寸测量(利用坐标转换)

    由于需要实现一个物体的测量,但是已有QT程序,最后的整体功能需要在C#集成实现. 首先有两个方案:(1)利用已有的QT程序以及界面,直接在C#中调用QT,或者C++程序,但是经过尝试,发现两者之间进行 ...

  8. 【Opencv项目实战】目标追踪:实时追踪人工标注的多个目标

    文章目录 一.项目思路 二.问题清单 三.算法详解 3.1.定义目标追踪算法 3.2.初始化追踪器 3.3.更新目标追踪器 3.4.绘制目标矩形框 3.5.人工标注感兴趣目标 3.5.1.标注ROI区 ...

  9. 【计算机视觉OpenCV基础】实验四 尺寸测量

    实验四 尺寸测量 计算机视觉OpenCV基础实验合辑(实验1234+扩展) 资源下载地址: https://download.csdn.net/download/weixin_53403301 合辑: ...

  10. Opencv项目实战:基于dlib的疲劳检测

    文章目录 一.项目简介 二.算法原理 三.环境配置 3.1.dlib人脸检测器:dlib.get_frontal_face_detector() 3.2.dlib关键点定位工具:shape_predi ...

最新文章

  1. 【Linux】Ubuntu的一些高(sao)效(cao)率(zuo)工具
  2. linux symbol文件,LINUX EXPORT_SYMBOL_GPL及EXPORT_SYMBOL导出函数
  3. 字节跳动只剩下小米这一个朋友了
  4. 【Spring】Spring 依赖注入之手动注入
  5. python基础教程菜鸟教程-终于懂得python入门菜鸟教程
  6. PHP动态网页设计与制作案例教程pdf
  7. 最常用的5个Python第三方库,你知道几个?第三个97%的程序员都在用!
  8. AutoVue使用教程:如何在64位Linux上安装AutoVue
  9. Kindle使用的一些方法
  10. 带你Git从入门到精通
  11. 【第 001 期 · 文献领读】——MRI专题
  12. oracle数据库怎么进行树查询,oracle树查询的实现
  13. 软件开发测试的5个部分
  14. 机器学习笔记 - 使用TensorFlow进行音乐生成
  15. static_cast 剖析
  16. 将两个实数矩阵合并为一个复数矩阵
  17. ONES Talk | 我们为什么选择最难走的软件之路
  18. 力扣-518题 零钱变换 II(C++)- 动态规划、完全背包问题
  19. 为什么英文里的单词vanilla有“普通”的意思?
  20. 免费的音频编辑器为Mac用户

热门文章

  1. 薄胶(S18xx,SPR955,BCI-3511,NRD6015)光刻胶
  2. 大象不会跳舞了吗?营收下滑的IBM在干什么
  3. 【Verilog基础】数字电路-逻辑式化简公式(附吸收律推导过程)
  4. python简化逻辑式
  5. nginx使用limit_req_zone限制ip访问频率
  6. 实时网速怎么看快慢_怎么测试下载速度(教你安全检测网速快慢)
  7. Shell脚本之正则表达式详解
  8. 老李分享:六度分隔理论 1
  9. min-height和height的区别
  10. 搜索引擎优化核心关键词策略