OPENCV C++(八)HOG的实现

hog适合做行人的识别和车辆识别 对一定区域的形状描述方法

可以表示较大的形状 把图像分成一个一个小的区域的直方图

用cell做单位做直方图 

计算各个像素的梯度强度和方向

用3*3的像素组成一个cell 3*3的cell组成一个block来归一化 提高亮度不变性

常用SVM分类器一起使用 进行行人分类

代码思路:

将图像分成cell为单位 例如把图像分成9*9像素的cell为单位。用sobel计算梯度大小和方向。

遍历每一个cell,一个cell可以分8类,用角度当作数组的下标,也就是分类的依据,数组的大小也就是分类的一个类的大小就是梯度的大小相加。

计算两个图的直方图的直方图距离的大小累加值


计算hog直方图函数:

int calcHOG(cv::Mat src, float* hist, int nAngle, int cellSize)
{int nX = src.cols / cellSize;int nY = src.rows / cellSize;int binAngle = 360 / nAngle;Mat gx, gy;Mat mag, angle;Sobel(src, gx, CV_32F, 1, 0, 1);Sobel(src, gy, CV_32F, 0, 1, 1);cartToPolar(gx, gy, mag, angle, true);Rect roi;roi.x = 0;roi.y = 0;roi.width = cellSize;roi.height = cellSize;for (int i = 0; i < nY; i++) {for (int j = 0; j < nX; j++) {Mat roiMat;Mat roiMag;Mat roiAgl;roi.x = j * cellSize;roi.y = i * cellSize;//赋值图像roiMat = src(roi);roiMag = mag(roi);roiAgl = angle(roi);//当前cell第一个元素在数组中的位置int head = (i * nX + j) * nAngle;for (int n = 0; n < roiMat.rows; n++) {for (int m = 0; m < roiMat.cols; m++) {//计算角度在哪个bin,通过int自动取整实现int pos = (int)(roiAgl.at<float>(n, m) / binAngle);//以像素点的值为权重hist[head + pos] += roiMag.at<float>(n, m);}}}}return 0;}

mag梯度大小强度  angle是角度的mat

传入的参数就是:图像,直方图数组,分成几个angle类型(一般是8个),cell的大小。

计算两个直方图的距离 

float normL2(float* Hist1, float* Hist2, int size)
{float sum = 0;for (int i = 0; i < size; i++) {sum += (Hist1[i] - Hist2[i]) * (Hist1[i] - Hist2[i]);}sum = sqrt(sum);return sum;
}

第一种是自己申明数组 然后做hog

	Mat temple = imread("hogTemplate.jpg",0);Mat img1 = imread("img1.jpg",0);Mat img2 = imread("img2.jpg",0);float his[3000] = { 0 };float his1[3000] = { 0 };float his2[3000] = { 0 };printf("%d %d\r\n",temple.cols,temple.rows);calcHOG(temple, his, 8, 9);calcHOG(img1, his1, 8, 9);calcHOG(img2, his2, 8, 9);float summ = normL2(his, his1, 3000);float summ2 = normL2(his, his2, 3000);cout << summ <<"\r\n" << endl;cout << "------" << endl;cout << summ2 <<"\r\n" << endl;

用动态开辟内存数组来进行hog

	int nX = refMat.cols / blockSize;int nY = refMat.rows / blockSize;int bins = nX * nY * nAngle;float* ref_hist = new float[bins];memset(ref_hist, 0, sizeof(float) * bins);float* pl_hist = new float[bins];memset(pl_hist, 0, sizeof(float) * bins);float* bg_hist = new float[bins];memset(bg_hist, 0, sizeof(float) * bins);

 这是比较关键的代码 就是动态开辟一个内存

	delete[] ref_hist;delete[] pl_hist;delete[] bg_hist;destroyAllWindows();

记得要释放内存!

完整代码:

	cv::Mat refMat = imread("hogTemplate.jpg");cv::Mat plMat = imread("img1.jpg");cv::Mat bgMat = imread("img2.jpg");int nAngle = 8;int blockSize = 9;int nX = refMat.cols / blockSize;int nY = refMat.rows / blockSize;int bins = nX * nY * nAngle;float* ref_hist = new float[bins];memset(ref_hist, 0, sizeof(float) * bins);float* pl_hist = new float[bins];memset(pl_hist, 0, sizeof(float) * bins);float* bg_hist = new float[bins];memset(bg_hist, 0, sizeof(float) * bins);int reCode = 0;reCode = calcHOG(refMat, ref_hist, nAngle, blockSize);reCode = calcHOG(plMat, pl_hist, nAngle, blockSize);reCode = calcHOG(bgMat, bg_hist, nAngle, blockSize);float dis1 = normL2(ref_hist, pl_hist, bins);float dis2 = normL2(ref_hist, bg_hist, bins);std::cout << "distance between reference and img1:" << dis1 << std::endl;std::cout << "distance between reference and img2:" << dis2 << std::endl;(dis1 <= dis2) ? (std::cout << "img1 is similar" << std::endl) : (std::cout << "img2 is similar" << std::endl);delete[] ref_hist;delete[] pl_hist;delete[] bg_hist;destroyAllWindows();return 0;
}

 

有没有很疑惑 为啥两种计算的方式 他们hog值不一样?

因为第一种我把他灰度化了 所以值偏低,我们现在把第二种方法的也灰度化

 ok 简直一摸一样 结束实验

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/27472.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows环境下Node.js二进制版安装教程

文章目录 前言一 下载Node.js二 设置环境变量三 配置全局安装和缓存路径四 设置仓库 前言 新版的Node.js已自带npm&#xff0c;就在Node.js下载完成解压后的文件内&#xff0c;的node_modules包中。 npm的作用&#xff1a;是对Node.js依赖的包进行管理&#xff0c;类似maven。…

如何构造一个安全的单例?

为什么要问这个问题&#xff1f; 我们知道&#xff0c;单例是一种很常用的设计模式&#xff0c;主要作用就是节省系统资源&#xff0c;让对象在服务器中只有一份。但是实际开发中可能有很多人压根没有写过单例这种模式&#xff0c;只是看过或者为了面试去写写demo熟悉一下。那…

C语言代码的x86-64汇编指令分析过程记录

先通过Xcode创建一个terminal APP&#xff0c;语言选择C。代码如下&#xff1a; #include <stdio.h>int main(int argc, const char * argv[]) {int a[7]{1,2,3,4,5,6,7};int *ptr (int*)(&a1);printf("%d\n",*(ptr));return 0; } 在return 0处打上断点&…

Linux usb设备固定端口号

Linux usb设备固定端口号 一:/sys/bus/usb/devices/二:设备信息三:固定usb设备名方法 一:/sys/bus/usb/devices/ 信息显示如下 1-0:1.0 1&#xff1a;表示 1 号总线&#xff0c;或者说 1 号 Root Hub0&#xff1a;表示端口号1&#xff1a;表示配置号0&#xff1a;表示接口号命…

错过NFT投资,你可能会后悔吗?

在过去的几年里&#xff0c;非同质化代币&#xff08;NFT&#xff09;以其独特性和创新性&#xff0c;迅速成为数字资产领域的热门话题。NFT代表了数字资产的所有权和独特性&#xff0c;为艺术、音乐、游戏和虚拟世界等领域提供了全新的可能性。然而&#xff0c;对于那些错过了…

冠达管理投资前瞻:三星加码机器人领域 大信创建设提速

上星期五&#xff0c;沪指高开高走&#xff0c;盘中一度涨超1%打破3300点&#xff0c;但随后涨幅收窄&#xff1b;深成指、创业板指亦强势震动。截至收盘&#xff0c;沪指涨0.23%报3288.08点&#xff0c;深成指涨0.67%报11238.06点&#xff0c;创业板指涨0.95%报2263.37点&…

gin框架学习

文章目录 配置go环境实现一个简单的web响应服务验证功能gin增加页面以及传递数据 配置go环境 去go官网下载对应的版本 go下载地址 tar -C /usr/local -xzf go1.4.linux-amd64.tar.gz 我们可以编辑 ~/.bash_profile 或者 /etc/profile&#xff0c;并将以下命令添加该文件的末…

【排序算法】python之冒泡,选择,插入,快速,归并

参考资料&#xff1a; 《Python实现5大排序算法》《六大排序算法&#xff1a;插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序》 --代码似乎是C语言 ———————— 本文介绍5种常见的排序算法和基于Python实现&#xff1a; 冒泡排序&#xff08;Bubble Sort&am…

pocky-request网络请求插件

插件下载地址&#xff1a;https://ext.dcloud.net.cn/plugin?id468 插件&#xff1a;https://www.yuque.com/pocky/aaeyux/irx7u0#Oosbz 使用教程&#xff1a; 下载插件main.js中配置&#xff1a; // 导入 import axiosRequest from ./js_sdk/pocky-request/pocky-request…

鉴源实验室丨SOME/IP协议安全攻击

作者 | 张昊晖 上海控安可信软件创新研究院工控网络安全组 来源 | 鉴源实验室 社群 | 添加微信号“TICPShanghai”加入“上海控安51fusa安全社区” 01 引 言 随着汽车行业对于数据通信的需求不断增加&#xff0c;SOME/IP作为支持汽车以太网进程和设备间通信的一种通信协议应…

【Git】Git切换地址

如何切换git代码地址&#xff1f; 1、查看当前远程 url git remote -v执行命令后&#xff0c;可以看见当前有2个URL。 远程 URL 在一般情况下有两个&#xff0c;分别是 fetch 和 push。 fetch URL 是用于从远程仓库获取最新版本的数据。当您运行 git fetch 命令时&#xf…

Oracle-ORA-00600:[ktspffbmb:objdchk_kcbnew_3]

问题背景: 应用执行存储过程报错ORA-00600: 内部错误代码, 参数: [ktspffbmb:objdchk_kcbnew_3], [0], [3303775], [4], [], [], [], [], [], [], [], []&#xff0c;导致过程无法正常执行 ORA-00600: 内部错误代码, 参数: [ktspffbmb:objdchk_kcbnew_3], [0], [3303775], [4]…

结构体和 Json 相互转换(序列化反序列化)

关于 JSON 数据 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也 易于机器解析和生成。RESTfull Api 接口中返回的数据都是 json 数据。 Json 的基本格式如下&#xff1a; { "a": "Hello", "b": "…

机器视觉赛道持续火热,深眸科技坚持工业AI视觉切入更多应用领域

随着深度学习等算法的突破、算力的不断提升以及海量数据的持续积累&#xff0c;人工智能逐渐从学术界向工业界落地。而机器视觉作为人工智能领域中一个正在快速发展的分支&#xff0c;广泛应用于工业制造的识别、检测、测量、定位等场景&#xff0c;相较于人眼&#xff0c;在精…

学习才是测试猿的永动力!超详细的 pytest 钩子函数 之初始钩子和引导钩子来啦

前 言 前几篇文章介绍了 pytest 点的基本使用&#xff0c;学完前面几篇的内容基本上就可以满足工作中编写用例和进行自动化测试的需求。从这篇文章开始会陆续给大家介绍 pytest 中的钩子函数&#xff0c;插件开发等等。仔细去看过 pytest 文档的小伙伴&#xff0c;应该都有发现…

Visual Studio 2022的MFC框架——应用程序向导

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来重新审视一下Visual Studio 2022开发工具下的MFC框架知识。 MFC(Microsoft Foundation Class&#xff0c;微软基础类库&#xff09;是微软为了简化程序员的开发工作所开发的一套C类的集合&#xf…

RabbitMQ的安装

RabbitMQ的安装 1、Windows环境下的RabbitMQ安装步骤 使用的版本&#xff1a;otp_win64_23.2 rabbitmq-server-3.8.16 版本说明&#xff1a;https://www.rabbitmq.com/which-erlang.html#compatibility-matrix 1.1 下载并安装erlang RabbitMQ 服务端代码是使用并发式语言…

【vim 学习系列文章 4 - vim与系统剪切板之间的交互】

文章目录 背景1.1.1 vim支持clipboard 检查1.1.2 vim的寄存器 上篇文章&#xff1a;【vim 学习系列文章 3 - vim 选中、删除、复制、修改引号或括号内的内容】 背景 从vim中拷贝些文字去其它地方粘贴&#xff0c;都需要用鼠标选中vim的文字后&#xff0c;Ctrlc、Ctrlv&#x…

怎么绘制汤姆索亚历险记思维导图?掌握这几个绘制步骤就可以

怎么绘制汤姆索亚历险记思维导图&#xff1f;如果你正在为学习汤姆索亚历险记而感到困惑&#xff0c;或者你想要更好地理解小说中的人物关系、情节和舞台背景&#xff0c;那么一个清晰的思维导图就可以帮助你梳理思路。那么下面就给大家介绍一下绘制步骤。 在进行思维导图绘制的…

docker容器监控:Cadvisor +Prometheus+Grafana的安装部署

目录 Cadvisor PrometheusGrafana的安装部署 一、安装docker&#xff1a; 1、安装docker-ce 2、阿里云镜像加速器 3、下载组件镜像 4、创建自定义网络 二、部署Cadvisor 1、被监控主机上部署Cadvisor容器 2、访问cAdvisor页面 三、安装prometheus 1、部署Prometheus…