OpenCV图像测量:两种高效方法对比

发布时间:2026/7/21 19:37:54

OpenCV图像测量:两种高效方法对比
在计算机视觉领域图像测量是一项常见而重要的任务。本文将详细介绍两种基于OpenCV的图像测量方法并对它们的实现原理、优缺点及适用场景进行深入分析。方法一基于参考物体宽度的测量方法核心原理第一种方法通过设定已知宽度的参考物体通常放置在图像最左侧计算像素与实际尺寸的比例关系从而测量图像中其他物体的尺寸。代码实现分析# 导入必要的库 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) # 设置内部参数 args { image: rD:\data\05.bmp, width: 25.0 # 参考物体的实际宽度 }以上代码段首先导入了必要的库并定义了中点计算函数和参数设置。# 图像预处理 img cv2.imread(args[image]) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY_INV) # 膨胀操作增强轮廓 kernel np.ones((3, 3), np.uint8) thresh cv2.dilate(thresh, kernel, iterations1) # 填充图像四角以消除边缘干扰 height, width thresh.shape thresh[0:120, 0:160] 0 # 左上角 thresh[0:150, width - 180:] 0 # 右上角 thresh[height - 120:, 0:160] 0 # 左下角 thresh[height - 150:, width - 160:] 0 # 右下角预处理阶段包括读取图像、灰度转换、二值化和膨胀操作最后填充图像四角以消除边缘干扰。# 寻找物体轮廓并排序 cnts cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts imutils.grab_contours(cnts) (cnts, _) contours.sort_contours(cnts) # 初始化像素与实际尺寸的比例 pixelsPerMetric None # 遍历每个轮廓进行测量 for c in cnts: if cv2.contourArea(c) 10000: # 忽略面积过小的轮廓 continue # 计算最小外接矩形 box cv2.minAreaRect(c) box cv2.boxPoints(box) box np.array(box, dtypeint) box perspective.order_points(box) # 计算各边中点并绘制 (tl, tr, br, bl) box (tltrX, tltrY) midpoint(tl, tr) (blbrX, blbrY) midpoint(bl, br) (tlblX, tlblY) midpoint(tl, bl) (trbrX, trbrY) midpoint(tr, br) # 计算像素距离 dA dist.euclidean((tltrX, tltrY), (blbrX, blbrY)) dB dist.euclidean((tlblX, tlblY), (trbrX, trbrY)) # 设置比例使用最左侧物体的已知宽度 if pixelsPerMetric is None: pixelsPerMetric dB / args[width] # 计算实际尺寸 dimA dA / pixelsPerMetric * 0.98 # 0.98为修正系数 dimB dB / pixelsPerMetric * 0.98 # 绘制测量结果 cv2.putText(orig, {:.3f}mm.format(dimA), (int(tltrX - 15), int(tltrY - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (255, 255, 255), 1) cv2.putText(orig, {:.3f}mm.format(dimB), (int(trbrX 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (255, 255, 255), 1)测量阶段首先寻找并排序轮廓然后为每个轮廓计算最小外接矩形通过参考物体的宽度建立像素与实际尺寸的转换关系最后计算并显示实际尺寸。方法二基于硬币作为参考的测量方法核心原理第二种方法使用硬币作为参考物体已知实际直径通过检测图像中最大的圆形轮廓来识别硬币然后计算像素与实际尺寸的比例关系。代码实现分析import cv2 import numpy as np import matplotlib.pyplot as plt def find_and_measure_objects(image_path, coin_real_diameter_mm25.0): # 读取图像 img cv2.imread(image_path) if img is None: raise ValueError(图像加载失败请检查路径) # 转换为灰度图并二值化 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY_INV) # 填充四角消除干扰 height, width thresh.shape thresh[0:120, 0:160] 0 # 左上角 thresh[0:140, width - 180:] 0 # 右上角 thresh[height - 120:, 0:160] 0 # 左下角 thresh[height - 150:, width - 160:] 0 # 右下角该方法封装在一个函数中首先进行图像读取、灰度转换、二值化和边缘处理。# 查找轮廓并找到最大的轮廓假设是硬币 contours, _ cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) max_contour max(contours, keycv2.contourArea) # 获取硬币的最小外接圆 (x, y), radius cv2.minEnclosingCircle(max_contour) center (int(x), int(y)) radius int(radius) diameter_px 2 * radius # 计算像素到毫米的转换比例 px_to_mm coin_real_diameter_mm / coin_diameter_px这部分代码查找轮廓并找到最大的轮廓假设为硬币然后计算硬币的最小外接圆基于已知的硬币实际直径建立像素与毫米的转换关系。# 遍历所有轮廓并测量 measurements [] for i, contour in enumerate(contours): area cv2.contourArea(contour) if area 20000 or contour is max_contour: # 忽略小物体和硬币本身 continue # 获取最小外接矩形 rect cv2.minAreaRect(contour) box cv2.boxPoints(rect) box np.int0(box) # 计算尺寸 edge1 np.linalg.norm(box[0] - box[1]) edge2 np.linalg.norm(box[1] - box[2]) width_px, height_px max(edge1, edge2), min(edge1, edge2) # 转换为真实尺寸 width_mm width_px * px_to_mm height_mm height_px * px_to_mm # 存储测量结果 measurements.append({ id: i 1, width_px: width_px, height_px: height_px, width_mm: width_mm, height_mm: height_mm })测量阶段遍历所有轮廓计算每个物体的最小外接矩形并根据像素与毫米的转换关系计算实际尺寸。# 使用matplotlib显示结果 plt.figure(figsize(15, 5)) plt.subplot(131), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title(Original Image), plt.axis(off) plt.subplot(132), plt.imshow(thresh, cmapgray) plt.title(Threshold Image), plt.axis(off) plt.subplot(133), plt.imshow(cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)) plt.title(Measurement Results), plt.axis(off) plt.tight_layout() plt.show() # 打印测量结果表格 print(\n物体测量结果) print(f{ID:5}{宽度(mm):10}{高度(mm):10}{宽度(px):10}{高度(px):10}) print(- * 45) for m in measurements: print(f{m[id]:5}{m[width_mm]:10.3f}{m[height_mm]:10.13}{m[width_px]:10.3f}{m[height_px]:10.3f}) return result_img, measurements最后该方法使用matplotlib显示原始图像、二值化图像和测量结果并以表格形式打印测量数据。两种方法的对比分析1、相同点1. 都使用OpenCV进行图像处理和轮廓检测2. 都需要参考物体来建立像素与实际尺寸的转换关系3. 都采用二值化方法突出物体轮廓4. 都使用最小外接矩形来表示物体的尺寸5. 都填充图像四角以消除边缘干扰2、不同点对比项方法一方法二参考物体已知宽度的物体通常放在最左侧硬币已知直径代码结构线性执行结构函数封装结构轮廓排序从左到右排序无需排序通过面积识别参考物体显示方式使用 OpenCV 的 imshow使用 matplotlib 显示多图对比结果输出仅在图像上显示图像显示 表格数据输出适用场景有规则排列的物体测量包含圆形参考物的任意场景优缺点分析方法一优点实现简单直观对于规则排列的物体测量效率高无需复杂的轮廓识别算法方法一缺点依赖参考物体的位置必须在最左侧代码结构较为松散仅支持在图像上显示结果方法二优点封装性更好易于复用参考物体硬币放置位置更灵活结果可视化更丰富多图对比 表格数据代码结构更清晰方法二缺点依赖于硬币在图像中是最大的圆形物体当图像中有多个类似大小的圆形物体时可能误判实现相对复杂适用场景推荐方法一适用场景生产线检测中物体规则排列的场景需要快速实现简单测量的场景对代码封装要求不高的场景方法二适用场景通用物体测量场景需要美观结果展示的场景多次复用测量功能的场景有圆形参考物体如硬币的场景代码优化建议方法一优化建议1. 封装为函数def measure_objects_by_reference(image_path, ref_width_mm, min_area10000): # 将原代码封装为函数 # 返回测量结果和处理后的图像2. 增加异常处理try: img cv2.imread(image_path) if img is None: raise FileNotFoundError(f无法读取图像{image_path}) except Exception as e: print(f图像读取错误{e}) return None, None3. 增加参数可调性def measure_objects_by_reference(image_path, ref_width_mm, threshold_value120, min_area10000, correction_factor0.98): # 实现代码方法二优化建议1. 增加硬币检测的鲁棒性def find_coin_contour(contours): # 不仅仅依靠面积还可以结合圆形度等特征 coin_contour None max_circularity -1 for contour in contours: if cv2.contourArea(contour) 10000: # 忽略小轮廓 continue # 计算圆形度 (4π*面积/周长²) perimeter cv2.arcLength(contour, True) if perimeter 0: continue circularity 4 * np.pi * cv2.contourArea(contour) / (perimeter ** 2) # 选择圆形度最高且面积较大的轮廓作为硬币 if circularity max_circularity and circularity 0.8: # 圆形度阈值 max_circularity circularity coin_contour contour return coin_contour2. 增加图像预处理的灵活性def preprocess_image(img, threshold_value120, fill_cornersTrue, corner_fill_sizesNone): # 实现灵活的图像预处理3. 支持多种显示模式def display_results(img, thresh, result_img, display_modematplotlib): if display_mode opencv: cv2.imshow(Original, img) cv2.imshow(Threshold, thresh) cv2.imshow(Results, result_img) cv2.waitKey(0) else: # matplotlib显示代码总结本文详细介绍了两种基于OpenCV的图像测量方法它们各有优缺点和适用场景。方法一实现简单适合规则排列物体的测量方法二封装性更好结果展示更丰富适合更通用的测量场景。在实际应用中可以根据具体需求选择合适的方法或者结合两种方法的优点进行改进。例如可以使用方法二的封装结构同时允许用户选择不同类型的参考物体从而提高测量的灵活性和准确性。图像测量技术在工业检测、物体识别、机器人视觉等领域有着广泛的应用前景通过不断优化算法和提高测量精度可以进一步拓展其应用范围。

相关新闻

终极招聘时间可视化插件:4大平台一键破解时间盲区

终极招聘时间可视化插件:4大平台一键破解时间盲区

2026/7/21 19:37:54

终极招聘时间可视化插件:4大平台一键破解时间盲区 【免费下载链接】boss-show-time 展示boss直聘岗位的发布时间 项目地址: https://gitcode.com/GitHub_Trending/bo/boss-show-time 还在为招聘平台隐藏发布时间而烦恼吗?Boss Show Time是一款专为…

AI搜索隐私保护失效的8个信号(技术负责人凌晨三点紧急叫停的预警清单)

AI搜索隐私保护失效的8个信号(技术负责人凌晨三点紧急叫停的预警清单)

2026/7/21 19:27:54

更多请点击: https://codechina.net 第一章:AI搜索隐私保护失效的典型征兆识别 当AI搜索服务的隐私保护机制出现退化或绕过时,用户往往在无感知状态下暴露敏感行为模式。识别这些失效征兆,是实施主动防御的第一道防线。 异常个性…

Ingress2Gateway 与 Gateway API 版本兼容性:从 v1.0 到 v1.5 的演进指南

Ingress2Gateway 与 Gateway API 版本兼容性:从 v1.0 到 v1.5 的演进指南

2026/7/21 19:27:54

Ingress2Gateway 与 Gateway API 版本兼容性:从 v1.0 到 v1.5 的演进指南 【免费下载链接】ingress2gateway Convert Ingress resources to Gateway API resources 项目地址: https://gitcode.com/gh_mirrors/in/ingress2gateway Ingress2Gateway 是一个强大…

AI 辅助的代码迁移:jQuery 到 React 的自动化重构策略与风险评估

AI 辅助的代码迁移:jQuery 到 React 的自动化重构策略与风险评估

2026/7/21 23:38:07

AI 辅助的代码迁移:jQuery 到 React 的自动化重构策略与风险评估 将老旧的 jQuery 项目迁移到 React,是前端团队最头疼的工作之一。这类项目通常代码量大(10 万行起)、业务逻辑隐式(散落在 DOM 操作和事件绑定中&#…

Qwen3.6-27B模型在5060Ti与V100显卡上的推理性能对比

Qwen3.6-27B模型在5060Ti与V100显卡上的推理性能对比

2026/7/21 23:38:07

1. 项目背景与测试目标最近在本地大模型推理领域,Qwen3.6-27B这款开源模型因其优秀的性能表现获得了广泛关注。作为一名长期关注AI推理硬件选型的从业者,我决定对两款主流显卡——NVIDIA 5060Ti 16G和V100 32G进行实测对比,看看在Qwen3.6-27B…

在线教育平台的 AI 代码生成实践:课件页面模板化与质量保障体系

在线教育平台的 AI 代码生成实践:课件页面模板化与质量保障体系

2026/7/21 23:38:07

在线教育平台的 AI 代码生成实践:课件页面模板化与质量保障体系 在线教育平台的课件页面开发,长期面临两个核心矛盾:一是课件数量大、迭代快,手工编写页面效率不足;二是课件质量参差不齐,缺少统一的代码规范…

workflows/,Claude Code 把多智能体协作写成可复跑脚本的地方

workflows/,Claude Code 把多智能体协作写成可复跑脚本的地方

2026/7/21 23:38:07

我最近看 Claude Code 的 .claude 目录时,最容易被低估的其实不是 CLAUDE.md,也不是 settings.json,而是 workflows/。前两者更像项目说明书和运行边界,workflows/ 更像一间调度室。我们的复杂任务不再只靠一个 Claude 在一个上下文窗口里边想边做,而是把任务拆成一段 Jav…

我用阿里 AgentScope 复刻了一个 WorkBuddy

我用阿里 AgentScope 复刻了一个 WorkBuddy

2026/7/21 23:38:07

最近在研究一个阿里的开源框架 AgentScope,一般来说,学习框架做好的方法就是实践了,我就想要不要用这个框架整一个agent出来。 之前我用python开发了一个Agent,有基础的模型配置,工具管理,技能配置&#x…

如何快速搭建个人漫画库:免费开源哔咔漫画下载器终极指南

如何快速搭建个人漫画库:免费开源哔咔漫画下载器终极指南

2026/7/21 23:28:07

如何快速搭建个人漫画库:免费开源哔咔漫画下载器终极指南 还在为网络不稳定无法畅快阅读哔咔漫画而烦恼吗?picacomic-downloader 是一款专为哔咔漫画设计的专业级下载工具,通过现代化的图形界面和智能多线程技术,帮助你轻松下载收…

微服务进阶:服务网格与Istio

微服务进阶:服务网格与Istio

2026/7/21 5:45:57

541|微服务进阶:服务网格与Istio 上篇文章我们聊了微服务的基本概念和拆分方法。 但微服务多了,问题也多了: 服务之间怎么通信? 怎么监控每个服务的调用链路? 熔断、限流、重试怎么做? 安全认证怎么统一? 以前这些都靠SDK库(比如Hystrix、Feign),每个服务都要集成…

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

2026/7/21 9:56:14

一、零售门店全域协同业务背景与行业痛点 1.1 门店超级终端设备矩阵(连锁便利店/商超标准配置) 自助收银Kiosk一体机:顾客结算、自助核销优惠券、商品素材预览;运营折叠平板:店长后台商品上新、图片录入、活动配置、…

噗叽短视频界面分析

噗叽短视频界面分析

2026/7/21 3:09:32

1 和小红书类似,可以采用类似判断方法------------其实他比小红书好判断,因为他没有图片,控件位置几乎是固定的,都不用判断------------2 因为他没有点赞按钮------------而且几乎所有控件位置都是完全一样的,所以我就…

GraphRAG Local + Ollama:微软知识图谱本地化

GraphRAG Local + Ollama:微软知识图谱本地化

2026/7/21 0:06:35

普通 RAG 有个老毛病:你问它「这堆文档整体在讲什么」,它答不上来。因为它只会把问题切成向量,去几十个文本块里捞最相似的几段拼给模型看。可「整体讲什么」这种问题,答案根本不在任何单独一段里——它散在全篇的联系里。 微软的…

AI 数据产品化思考:让分析能力变成可售卖的数据服务

AI 数据产品化思考:让分析能力变成可售卖的数据服务

2026/7/21 0:06:35

AI 数据产品化思考:让分析能力变成可售卖的数据服务 大家好,我是朱大喜。这周一直在复盘具体的项目和技术,最后一篇聊点不一样的东西——数据产品化。做了这么多年数据分析,我发现一个规律:能卖出去的从来不是"分…

基于人机协作的 AI 研发新体系架构:从 Harness 工程到 Loop 工程实践

基于人机协作的 AI 研发新体系架构:从 Harness 工程到 Loop 工程实践

2026/7/21 0:06:35

本文完整呈现了企业级 AI Coding 落地的核心方法论:从 Harness 工程的微观/宏观定义,到 Loop 工程的六大构建模块,再到基于 SDD(规范驱动开发)的工程化落地路径。干货较多,建议收藏细读。 我从 22 年开始就…