当前位置: 首页 > news >正文

使用OpenCV计算灰度图像的质心

在灰度图像中计算质心时,我们需要考虑像素的灰度值作为权重,这与二值图像不同。以下是使用OpenCV在C++中计算灰度图像质心的完整实现:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <cmath>int main() {// 1. 读取图像为灰度图cv::Mat grayImage = cv::imread("grayscale_image.jpg", cv::IMREAD_GRAYSCALE);if (grayImage.empty()) {std::cerr << "Error: 无法加载图像文件" << std::endl;return -1;}// 2. 计算图像矩 - 灰度值作为权重cv::Moments m = cv::moments(grayImage, true);  // true表示使用灰度值作为权重// 3. 检查有效像素权重if (std::fabs(m.m00) < 1e-5) {std::cerr << "Error: 图像不包含有效像素信息" << std::endl;return -1;}// 4. 计算质心坐标cv::Point2f centroid(static_cast<float>(m.m10 / m.m00),static_cast<float>(m.m01 / m.m00));// 5. 输出结果std::cout << "图像大小: " << grayImage.cols << "x" << grayImage.rows << std::endl;std::cout << "灰度质心坐标: (" << centroid.x << ", " << centroid.y << ")\n";// 6. 可视化结果 (可选)// 创建彩色图像用于可视化cv::Mat colorImage;cv::cvtColor(grayImage, colorImage, cv::COLOR_GRAY2BGR);// 绘制质心标记cv::circle(colorImage, centroid, 7, cv::Scalar(0, 0, 255), 2);  // 红色圆圈cv::drawMarker(colorImage, centroid, cv::Scalar(255, 0, 0), cv::MARKER_CROSS, 15, 2);  // 蓝色十字标记// 添加坐标文本std::string coordText = "(" + std::to_string(centroid.x) + ", " + std::to_string(centroid.y) + ")";cv::putText(colorImage, coordText, cv::Point(centroid.x + 20, centroid.y - 15), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2);// 7. 显示和保存结果cv::imshow("Gray Image with Centroid", colorImage);cv::imwrite("centroid_result.jpg", colorImage);cv::waitKey(0);return 0;
}

关键解释:

  1. ​灰度权重计算​​:

    • 与二值图像不同,灰度图像的质心计算考虑了每个像素的亮度值

    • 计算时权重:权重 = 像素值 / 255.0

  2. ​质心计算公式​​:

    • xc​=∑x,y​I(x,y)∑x,y​(x⋅I(x,y))​

    • yc​=∑x,y​I(x,y)∑x,y​(y⋅I(x,y))​

    • 其中 I(x,y)是像素点(x,y)的灰度值

  3. ​图像矩的属性​​:

    • m00:加权面积总和(所有像素值的总和)

    • m10:加权x坐标总和

    • m01:加权y坐标总和

  4. ​应用场景​​:

    • 光线不均匀的物体跟踪

    • 医学图像中器官的位置分析

    • 天文图像中星体或星系的定位

多物体质心计算:

如果灰度图像中有多个离散物体,可以配合连通区域分析计算各自的质心:

// 二值化图像(可选)
cv::Mat binary;
cv::threshold(grayImage, binary, 128, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);// 查找连通区域
std::vector<std::vector<cv::Point>> contours;
cv::findContours(binary, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);// 计算每个物体的质心
for (const auto& contour : contours) {// 计算区域像素值总和cv::Scalar area = cv::sum(grayImage & (cv::Mat(contour) != 0));// 计算加权质心cv::Moments m = cv::moments(contour);cv::Point2f centroid(static_cast<float>(m.m10 / m.m00),static_cast<float>(m.m01 / m.m00));// 处理每个物体的质心...
}

注意事项:

  1. 确保图像已正确加载为灰度格式

  2. 处理大图像时,建议使用double类型避免精度丢失

  3. 对于全黑图像(m00=0),需要处理除零错误

  4. 质心坐标可能为浮点数,使用cv::Point2f存储结果

这个实现可以直接应用于灰度图像处理任务,如特征定位、目标跟踪和图像分析等应用场景。

http://www.dtcms.com/a/339179.html

相关文章:

  • 云原生堡垒机渗透测试场景
  • 所有普通I/O口都支持中断的51单片机@Ai8051U, AiCube 图形化配置
  • 微服务架构的演进:从 Spring Cloud Netflix 到云原生新生态
  • 大模型微调RAG、LORA、强化学习
  • 如何使用VNC对openEuler系统进行远程图形化操作
  • Ubuntu Server 22.04 k8s部署服务较时,文件描述符超过限制的处理方法
  • RabbitMQ:SpringBoot+RabbitMQ 多消费者绑定同一队列
  • Node.js 在 Windows Server 上的离线部署方案
  • leetcode349. 两个数组的交集
  • 轻度娱乐浪潮下定制开发开源AI智能名片S2B2C商城小程序的机遇与策略
  • 厚板数控矫平机的“第三堂课”——把视角拉远,看看它如何重塑整条制造链
  • 供水设备智慧化管理物联网解决方案:远程监控与运维
  • 搭建最新--若依分布式spring cloudv3.6.6 前后端分离项目--步骤与记录常见的坑
  • BKP相关知识点
  • 从机器视觉到图像识别:计算机视觉的多维探索
  • LINUX819 shell:for for,shift ,{} ,array[0] array[s] ,declare -x -a
  • 服务注册与服务发现原理与实现
  • CentOS 8开发测试环境:直接安装还是Docker更优?
  • Docker核心---数据卷(堵门秘籍)
  • 应用控制技术、内容审计技术、AAA服务器技术
  • 深入理解Redis持久化:让你的数据永不丢失
  • 电子电气架构 ---SDV技术基础与传统E/E架构有何不同?
  • 利用图数据库高效解决 Text2sql 任务中表结构复杂时占用过多大模型上下文的问题
  • 智慧养老中IPTV融合对讲:重塑养老沟通新生态
  • t12 low power design: power plan脚本分享(4) power stripe
  • spring声明式事务,finally 中return对事务回滚的影响
  • 数据资产入表——图解《企业数据资源相关会计处理暂行规定》《数据资产评估指导意见》【附全文阅读】
  • 企业架构是什么?解读
  • 功能组状态的独立性以及 进程启动在状态管理中的设计意图
  • 用“新”突围,康师傅布局增量市场