OpenCV开发笔记(五十八):红胖子8分钟带你深入了解图像的矩(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106257036
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
OpenCV开发专栏(点击传送门)
上一篇:《OpenCV开发笔记(五十七):红胖子8分钟带你深入了解直方图反向投影(图文并茂+浅显易懂+程序源码)》
下一篇:持续补充中…
前言
红胖子,来也!
做识别,有时候需求要识别面积、距离能,若双瞳之间的距离,手机的宽高等等,图像的矩就是为这些需要识别具体标量的基础之一。
Demo
图像的矩
概述
矩函数在图像分析中是必备的方法之一,应用广泛,如模式识别、目标分类、目标识别与方位估计、图像编码与重构等。一天个从一副数字图形中计算出来的矩集,通常描述了该图形形状的全局特征,并提供了大量的关于该图像不同类型的集合特性信息,比如大小、方向及形状等。
- 一阶矩:与形状有关;
- 二阶矩:显示曲线围绕直线平均值的扩展程度;
- 三阶矩:关于平均值的对称性的测量;
寻找轮廓
计算图像所有的矩(最高到三阶)
计算多边形和光山形状的最高达三阶的所有矩,可用来计算形状的中心、面积、主轴和其他形状特征。
Moments moments( InputArray array, bool binaryImage = false );
- 参数一:InputArray类型的array,输入参数可以是光栅图像(单通道、8位或浮点的二维数组)或二维数组(lN或NI);
- 参数二:bool类型的binaryImage,默认值false。若此参数取true,则所有非零像素为1。此参数仅对于图像使用;
注意:此参数的返回值是返回运行后的结果。
计算轮廓面积函数原型
用于计算部分轮廓的面积或者整个轮廓。
doube contourArea (InputArray contour , bool oriented=false );
- 参数一:InputArray类型的contour,输入的向量,二维点(轮廓顶点),可以为std::vector或Mat类型;
- 参数二:bool类型的oriented,面向区域标识符。若其为true,该函数返回一个带符号的面积值,其正负取决于轮廓的方向(顺时针还是逆时针)。根据这个特性我们可以根据面积的符号来确定轮廓的位置。需要注意的是,这个参数有默认值false,表示以绝对值返回,不带符号;
用于计算封闭轮廓的周长或曲线的长度。
double arcLength (InputArray curve , boo1 c1osed);
- 参数一:InputArray类型的curve,输入的二维点集,可以为std::vector或Mat类型;
- 参数二:bool类型的closed,一个用于指示曲线是否封闭的标识符,有默认值closed,表示曲线封闭;
Demo源码
void OpenCVManager::testMoments()
{
QString fileName1 =
"E:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/15.jpg";
int width = 400;
int height = 300;
cv::Mat srcMat = cv::imread(fileName1.toStdString());
cv::resize(srcMat, srcMat, cv::Size(width, height));
cv::String windowName = _windowTitle.toStdString();
cvui::init(windowName);
cv::Mat windowMat = cv::Mat(cv::Size(srcMat.cols * 2, srcMat.rows * 3),
srcMat.type());
int threshold1 = 200;
int threshold2 = 100;
while(true)
{
windowMat = cv::Scalar(0, 0, 0);
cv::Mat mat;
cv::Mat dstMat;
cv::Mat grayMat;
cv::Mat tempMat;
cv::Mat hullMat;
hullMat = srcMat.clone();
// 原图先copy到左边
mat = windowMat(cv::Range(srcMat.rows * 0, srcMat.rows * 1),
cv::Range(srcMat.cols * 0, srcMat.cols * 1));
cv::addWeighted(mat, 0.0f, srcMat, 1.0f, 0.0f, mat);
{
// 灰度图
cv::cvtColor(srcMat, grayMat, CV_BGR2GRAY);
cv::cvtColor(grayMat, tempMat, CV_GRAY2BGR);
// copy
mat = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2),
cv::Range(srcMat.cols * 0, srcMat.cols * 1));
cv::addWeighted(mat, 0.0f, tempMat, 1.0f, 0.0f, mat);
cvui::printf(windowMat,
srcMat.rows * 1 + 100,
srcMat.cols * 0 + 20,
"threshold1");
cvui::trackbar(windowMat,
srcMat.rows * 1 + 100,
srcMat.cols * 0 + 50,
200,
&threshold1,
0,
255);
cvui::printf(windowMat,
srcMat.rows * 1 + 100,
srcMat.cols * 0 + 100, "threshold2");
cvui::trackbar(windowMat,
srcMat.rows * 1 + 100,
srcMat.cols * 0 + 130,
200,
&threshold2,
0,
255);
// 使用边缘检测
cv::Canny(grayMat, dstMat, threshold1, threshold2, 3);
// copy
mat = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2),
cv::Range(srcMat.cols * 1, srcMat.cols * 2));
cv::Mat rgbMat;
cv::cvtColor(dstMat, rgbMat, CV_GRAY2BGR);
cv::addWeighted(mat, 0.0f, rgbMat, 1.0f, 0.0f, mat);
// 寻找轮廓
std::vector<std::vector<cv::Point>> contours;
cv::findContours(dstMat, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
// 绘制轮廓
for(int index = 0; index < contours.size(); index++)
{
cv::drawContours(hullMat, contours, index, cv::Scalar(0, 0, 255), 2);
}
// copy
mat = windowMat(cv::Range(srcMat.rows * 2, srcMat.rows * 3),
cv::Range(srcMat.cols * 0, srcMat.cols * 1));
cv::addWeighted(mat, 0.0f, hullMat, 1.0f, 0.0f, mat);
// 计算图像所有的矩
std::vector<cv::Moments> mu(contours.size());
for(int index = 0; index < contours.size(); index++)
{
mu[index] = cv::moments(contours[index], false);
}
// 计算轮廓的面积
for(int index = 0; index < contours.size(); index++)
{
double area = cv::contourArea(contours[index]);
cvui::printf(windowMat,
srcMat.cols * 1,
srcMat.rows * 2 + 15 * index,
"%d/%d: contorsArea = %f",
index,
contours.size(),
area);
double length = cv::arcLength(contours[index], true);
cvui::printf(windowMat,
srcMat.cols * 1 + width / 2 + 30,
srcMat.rows * 2 + 15 * index,
"arcLength = %f",
length);
}
}
// 更新
cvui::update();
// 显示
cv::imshow(windowName, windowMat);
// esc键退出
if(cv::waitKey(25) == 27)
{
break;
}
}
}
工程模板:对应版本号v1.52.0
对应版本号v1.52.0
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106257036
OpenCV开发笔记(五十八):红胖子8分钟带你深入了解图像的矩(图文并茂+浅显易懂+程序源码)的更多相关文章
- OpenCV开发笔记(五十六):红胖子8分钟带你深入了解多种图形拟合逼近轮廓(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(六十五):红胖子8分钟带你深入了解ORB特征点(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(五十五):红胖子8分钟带你深入了解Haar、LBP特征以及级联分类器识别过程(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(六十九):红胖子8分钟带你使用传统方法识别已知物体(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(六十四):红胖子8分钟带你深入了解SURF特征点(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(七十一):红胖子8分钟带你深入级联分类器训练
前言 红胖子,来也! 做图像处理,经常头痛的是明明分离出来了(非颜色的),分为几块区域,那怎么知道这几块区域到底哪一块是我们需要的,那么这部分就涉及到需要识别了. 识别可以自己写模板匹配.特征 ...
- OpenCV开发笔记(七十二):红胖子8分钟带你使用opencv+dnn+tensorFlow识别物体
前言 级联分类器的效果并不是很好,准确度相对深度学习较低,本章使用opencv通过tensorflow深度学习,检测已有模型的分类. Demo 可以猜测,1其实是人,18序号类是狗 ...
- OpenCV开发笔记(七十三):红胖子8分钟带你使用opencv+dnn+yolov3识别物体
前言 级联分类器的效果并不是很好,准确度相对深度学习较低,上一章节使用了dnn中的tensorflow,本章使用yolov3模型,识别出具体的分类. Demo 320x320,置信度0 ...
- [第十八篇]——Docker 安装 Node.js之Spring Cloud大型企业分布式微服务云架构源码
Docker 安装 Node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,是一个让 JavaScript 运行在服务端的开发平台. 1.查看可用的 N ...
- 安卓开发笔记(十八):实现button按钮事件的三种方法
Android开发中有三种主要的方式用于设置View的点击事件,1.创建内部类:2.主类中实现OnClickListener接口:3.使用匿名内部类.这三种方式都用到了OnClickListener接 ...
随机推荐
- [转帖]一、Kafka Tool使用
一.Kafka Tool使用 1.添加cluster 2.开启SASL_PLAINTEXT 如果kafka 开启SASL_PLAINTEXT认证(用户名和密码认证) 3.高级设置 如果设置的是SASL ...
- [转帖]Linux命令学习手册-readelf
https://www.jianshu.com/p/405844abefae readelf elf-file(s) 功能 用于显示 elf 格式文件的信息. 描述 readelf 用来显示一个或者多 ...
- 我们开源了一个 Ant Design 的单元测试工具库
我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 本文作者:佳岚 欢迎大家点一个小小的 Star ant-design ...
- 巧用GenericObjectPool创建自定义对象池
作者:京东物流 高圆庆 1 前言 通常一个对象创建.销毁非常耗时的时候,我们不会频繁的创建和销毁它,而是考虑复用.复用对象的一种做法就是对象池,将创建好的对象放入池中维护起来,下次再用的时候直接拿池中 ...
- uni-app 计算属性 computed
功能:=>大于1000用kg表示 小于1000,用g表示 计算属性 计算属性必须是有一个返回值的哦 在html写被计算的值 在computed中去直接调用哈 <view> <t ...
- 你不知道的Promise状态变化机制
1.Promise中PromiseStatus的三种状态 var p = new Promise((resolve, reject) => { // resolve 既是函数也是参数,它用于处理 ...
- 【验证码逆向专栏】最新某验三代滑块逆向分析,干掉所有的 w 参数!
声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容.敏感网址.数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未经许 ...
- MySQL 中使用变量实现排名名次
title: MySQL 中使用变量实现排名名次 date: 2023-7-16 19:45:26 tags: - SQL 高级查询 一. 数据准备: CREATE TABLE sql_rank ( ...
- 【主流技术】15 分钟掌握 Redis 的安装部署和基本特性
目录 前言 一.Redis 概述 1.1Redis 是什么? 1.2Redis 能做什么? 1.3基础知识 二.Redis 安装与基本命令 2.1Windows 安装 方式一 方式二 2.2Linux ...
- 数据挖掘机器学习[五]---汽车交易价格预测详细版本{模型融合(Stacking、Blending、Bagging和Boosting)}
题目出自阿里天池赛题链接:零基础入门数据挖掘 - 二手车交易价格预测-天池大赛-阿里云天池 相关文章: 特征工程详解及实战项目[参考] 数据挖掘---汽车车交易价格预测[一](测评指标:EDA) 数据 ...