点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达本文转自:opencv学堂

一:直方图交叉

OpenCV中直方图反向投影算法实现来自一篇论文《Indexing Via Color Histograms》其作者有两位、是Michael.J.Swain与Dana H. Ballard。论文分为两个部分,前面一部分详细描述了颜色直方图以及通过颜色直方图交叉来实现对象鉴别。可以实现对象背景区分、复杂场景中查找对象、不同光照条件影响等。假设M表示模型直方图数据、I表示图像直方图数据、直方图交叉匹配可以被描述为如下:

其中J表示直方图的范围,即bin的个数。最终得到结果是表示多少个模型颜色像素与图像中的像素相同或者相似,值越大,表示越相似。归一化表示如下:

这种方法对背景像素变换可以保持稳定性、同时对尺度变换也有一定抗干扰作用,但是无法做到尺度不变性特征。基于上述理论,两位作者发现通过该方法可以定位图像中已知物体的位置,它们把这个方法叫做直方图反向投影(Back Projection)。

二:直方图反向投影

直方图反向投影可以通过如下步骤完成

  1. 对每个直方图BIN J

  2. 对图像的每个像素点I(x,y)根据像素值获得对应的直方图分布概率

  3. 对得到分布概率图像做卷积

  4. 求取局部最大值,即得到已知物体位置信息

正是因为直方图反向投影有这样能力,所以在经典的MeanShift与CAMeanShift跟踪算法中一直是通过直方图反向投影来实现已知对象物体的定位。

三:基于OpenCV算法代码实现 

算法实现基于OpenCV的数据结构Mat来实现数据转换与存储,其它的地方基本都是自己写,上次有同学说我的代码都是Java的,这次全部改为C++啦,所以请大家继续关注本公众号!

第一步:直方图计算

OpenCV自己实现通过对直方图插值实现LUT查找,不做RGB颜色降维,本人的实现反其道而行之,对图像颜色做降维得到直方图,不再对直方图计算使用LUT插值查找。

void calculate_histogram(Mat &image, Mat &hist) {int width = image.cols;int height = image.rows;int r = 0, g = 0, b = 0;int index = 0;int level = 256 / bins;for (int row = 0; row < height; row++) {uchar* current = image.ptr<uchar>(row);for (int col = 0; col < width; col++) {if (image.channels() == 3) {b = *current++;g = *current++;r = *current++;index = (r / level) + (g / level)*bins + (b / level)*bins*bins;}if (image.channels() == 1) {r = *current++;index = (r / level);}hist.at<int>(index, 0)++;}}
}

计算输入图像与模型的直方图代码如下

Mat mHist = Mat::zeros(total, 1, CV_32SC1);
Mat iHist = Mat::zeros(total, 1, CV_32SC1);
calculate_histogram(model, mHist);
calculate_histogram(src, iHist);

第二步:计算R

Mat rhist = Mat::zeros(total, 1, CV_32FC1);
float m = 0, t = 0;
for (int i = 0; i < total; i++) {m = mHist.at<int>(i, 0);t = iHist.at<int>(i, 0);rhist.at<float>(i, 0) = m / t;
}

第三步:计算概率分布图像

// 查找权重概率分布
int r = 0, g = 0, b = 0;
int level = 256 / bins;
int index = 0;
Mat w = Mat::zeros(src.size(), CV_32FC1);
for (int row = 0; row < src.rows; row++) {uchar* current = src.ptr<uchar>(row);for (int col = 0; col < src.cols; col++) {if (src.channels() == 3) {b = *current++;g = *current++;r = *current++;index = (r / level) + (g / level)*bins + (b / level)*bins*bins;w.at<float>(row, col) = rhist.at<float>(index, 0);} else {r = *current++;index = (r / level);w.at<float>(row, col) = rhist.at<float>(index, 0);}}
}

第四步:卷积计算

Mat dst;
Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1,1, 1, 1,1, 1, 1);
filter2D(w, dst, -1, kernel);

第五步:归一化与显示反向投影结果

Mat result;
normalize(dst, result, 0, 255, NORM_MINMAX);
imshow("BackProjection Demo", result);

四:运行演示

已知目标图像

反向投影结果

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

OpenCV中直方图反向投影算法详解与实现相关推荐

  1. 聚类 python_python中实现k-means聚类算法详解

    算法优缺点: 优点:容易实现 缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢 使用数据类型:数值型数据 算法思想 k-means算法实际上就是通过计算不同样本间的距离来判断他们的相近关系的,相近 ...

  2. Python+OpenCV:直方图反向投影(Histogram Backprojection)

    Python+OpenCV:直方图反向投影(Histogram Backprojection) Algorithm in Numpy 1. First we need to calculate the ...

  3. opencv python 直方图反向投影_python OpenCV学习笔记直方图反向投影的实现

    本文介绍了python OpenCV学习笔记直方图反向投影的实现,分享给大家,具体如下: 它用于图像分割或寻找图像中感兴趣的对象.简单地说,它创建一个与我们的输入图像相同大小(但单通道)的图像,其中每 ...

  4. 干货 | OpenCV中KLT光流跟踪原理详解与代码演示

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:opencv学堂 稀疏光流跟踪(KLT)详解 在视频移动 ...

  5. 反向算法_10分钟带你了解神经网络基础:反向传播算法详解

    作者:Great Learning Team deephub.ai 翻译组 1.神经网络 2.什么是反向传播? 3.反向传播是如何工作的? 4.损失函数 5.为什么我们需要反向传播? 6.前馈网络 7 ...

  6. 机器学习、深度学习中常用的优化算法详解——梯度下降法、牛顿法、共轭梯度法

    一.梯度下降法 1.总述: 在机器学习中,基于基本的梯度下降法发展了三种梯度下降方法,分别为随机梯度下降法,批量梯度下降法以及小批量梯度下降法. (1)批量梯度下降法(Batch Gradient D ...

  7. C语言中数组的排序算法详解——选择法、冒泡法、交换法、插入法、折半法

    选择法排序 选择法排序是指:如果要把一个数组从小到大排列,那么就从该数组中依次选择最小的数字来排序.从第一个数字开始,将第一个数字与数组中剩下数字中最小的那一个交换位置,然后将第二个数字与剩下数字中最 ...

  8. 深度学习中的Adam优化算法详解

    Adam论文:https://arxiv.org/pdf/1412.6980.pdf (一).什么是Adam算法? Adam(Adaptive momentum)是一种自适应动量的随机优化方法(A m ...

  9. OpenCV中的鱼眼相机模型详解

    针孔相机.鱼眼相机模型推导: 一.针孔相机模型 空间的三维物体要成像到相机的 CMOS/CCD 上面,形成了图像.图像上的每个点对应空间上的一个点. 将世界坐标系上的一点 (x,y,z)映射到CMOS ...

最新文章

  1. Redis Sentinel--运维管理
  2. Python-基于flask的接口框架
  3. 程序员法律考试(3)-依法治国的基本原则和法制体系具体任务
  4. 存储树形数据_数据结构篇之顺序表的创建以及实现
  5. UIImagePickerController
  6. azure blob_Azure Blob存储–名义上是混合数据库部署
  7. Altium Designer——AD画PCB图步骤总结
  8. 【Tomcat】修改密码
  9. 图谱笔记(概念梳理)
  10. 【SpringBoot】自定义starter实现详解
  11. GooglePlay应用上架流程
  12. std::cout彩色输出
  13. 2022新版PMP考试有哪些变化?
  14. 华为路由器BGP联邦综合实验
  15. 龙芯笔记本走出国门的困惑
  16. CSS的两种盒子模型
  17. 【运筹学】产销平衡下的运输问题概念理解(4月9日学习笔记)
  18. rust服务器配置文件,使用Rust编写一个简单的Socket服务器(1):Rust下的配置载入...
  19. 字符串的模式匹配(精准匹配)
  20. 数字冰雹入选2020爱分析·数据智能厂商全景报告

热门文章

  1. 算力觉醒后,智慧距离勃发就只差一个想法
  2. 百度发布智能小程序:“开放+AI”是最大特色
  3. 从YOLOv1到YOLOv3,目标检测的进化之路
  4. Logback 配置文件这样优化,TPS提高 10 倍
  5. 第 3 次读 Effective Java,这 58 个技巧最值!
  6. SpringBoot 操作 ElasticSearch 详解(万字长文)
  7. 牛逼哄哄的 Lambda 表达式,简洁优雅就是生产力!
  8. Spring中的18个注解,你会几个?
  9. 史上最详细 Linux 用户与用户组知识
  10. Sharding-jdbc教程:Springboot整合sharding-jdbc实现读写分离