当前位置: 首页 > 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.lryc.cn/news/625389.html

相关文章:

  • 前端面试核心技术30问
  • Springboot使用Selenium+ChormeDriver在服务器(Linux)端将网页保存为图片或PDF
  • 【完整源码+数据集+部署教程】太阳能板表面损伤检测图像分割系统源码和数据集:改进yolo11-DynamicHGNetV2
  • Linux------《操作系统全景速览:Windows·macOS·Linux·Unix 对比及 Linux 发行版实战指南》
  • C#项目集成海康SDK指南:从搭建环境到实现视频预览、录制、截屏
  • 什么是AKSK?
  • F003疫情传染病数据可视化vue+flask+mysql
  • 100202Title和Input组件_编辑器-react-仿低代码平台项目
  • 全平台轻量浏览器推荐|支持Win/macOS/Linux,极速加载+隐私保护+扩展插件,告别广告与数据追踪!
  • 私有化部署全攻略:开源大模型本地化改造的性能与安全深度评测
  • 在 IntelliJ IDEA 中修改 Git Commit 描述
  • Linux的ALSA音频框架学习笔记
  • Voice Agents:下一代语音交互智能体的架构革命与产业落地
  • 项目一系列-第5章 前后端快速开发
  • 【qml-5】qml与c++交互(类型单例)
  • 如何计算 PCM 音频与 YUV/RGB 原始视频文件大小?
  • 【Git Submodules 与微前端架构技术指南】
  • 指针的应用学习日记
  • Hive 存储管理测试用例设计指南
  • CSDN 创始人蒋涛:以开源驱动技术创新,拥抱黄金十年
  • 【SpringBoot】15 核心功能 - Web开发原理 - 请求处理 - 常用请求参数注解
  • 如何安全删除GitHub中的敏感文件?git-filter-repo操作全解析
  • 玳瑁的嵌入式日记D20-08019(数据结构)
  • Hive常用命令参考
  • 开源游戏引擎Bevy 和 Godot
  • 分布式搜索(Elasticsearch)深入用法
  • Leetcode 3652. Best Time to Buy and Sell Stock using Strategy
  • 【Rust嵌入式键值对数据库redb】第一课 第一次写入
  • 极品飞车21:热度(NFS Heat)
  • React native Navigation 详解