OpenCV入门(二十二)-- 陆地移动距离

2024-04-02 10:18

本文主要是介绍OpenCV入门(二十二)-- 陆地移动距离,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

光线的变化能引起图像颜色值的漂移,尽管这些漂移没有改变颜色直方图的形状,但是这些漂移引起了颜色值位置的变化,从而导致匹配策略失效。

陆地移动距离是一种度量准则,它实际上市度量怎样将一个直方图转变为另一个直方图的形状,包括移动直方图的部分(或全部)到一个新的位置,可以在任何维的直方图上进行这种度量。

CalcEMD2

两个加权点集之间计算最小工作距离

float cvCalcEMD2( const CvArr* signature1, const CvArr* signature2, int distance_type,CvDistanceFunction distance_func=NULL, const CvArr* cost_matrix=NULL,CvArr* flow=NULL, float* lower_bound=NULL, void* userdata=NULL );
typedef float (*CvDistanceFunction)(const float* f1, const float* f2, void* userdata);
signature1
第一个签名,大小为 size1×(dims+1) 的浮点数矩阵,每一行依次存储点的权重和点的坐标。矩阵允许只有一列(即仅有权重),如果使用用户自定义的代价矩阵。
signature2
第二个签名,与 signature1 的格式一样size2×(dims+1),尽管行数可以不同(列数要相同)。当一个额外的虚拟点加入 signature1 或 signature2 中的时候,权重也可不同。
distance_type
使用的准则, CV_DIST_L1, CV_DIST_L2, 和 CV_DIST_C 分别为标准的准则。 CV_DIST_USER 意味着使用用户自定义函数 distance_func 或预先计算好的代价矩阵 cost_matrix 。
distance_func
用户自定义的距离函数。用两个点的坐标计算两点之间的距离。
cost_matrix
自定义大小为 size1×size2 的代价矩阵。 cost_matrix 和 distance_func 两者至少有一个必须为 NULL. 而且,如果使用代价函数,下边界无法计算,因为它需要准则函数。
flow
产生的大小为 size1×size2 流矩阵(flow matrix): flowij 是从 signature1 的第 i 个点到 signature2 的第 j 个点的流(flow)。
lower_bound
可选的输入/输出参数:两个签名之间的距离下边界,是两个质心之间的距离。如果使用自定义代价矩阵,点集的所有权重不等,或者有签名只包含权重(即该签名矩阵只有单独一列),则下边界也许不会计算。用户必须初始化 *lower_bound. 如果质心之间的距离大于获等于 *lower_bound (这意味着签名之间足够远), 函数则不计算 EMD. 任何情况下,函数返回时 *lower_bound 都被设置为计算出来的质心距离。因此如果用户想同时计算质心距离和T EMD, *lower_bound 应该被设置为 0.
userdata
传输到自定义距离函数的可选数据指针

函数 cvCalcEMD2 计算两个加权点集之间的移动距离或距离下界。在 [RubnerSept98] 中所描述的其中一个应用就是图像提取得多维直方图比较。 EMD 是一个使用某种单纯形算法(simplex algorithm)来解决的交通问题。其计算复杂度在最坏情况下是指数形式的,但是平均而言它的速度相当快。对实的准则,下边界的计算可以更快(使用线性时间算法),且它可用来粗略确定两个点集是否足够远以至无法联系到同一个目标上。


/*
用EMD度量两个分布的相似性
这里,用lena和lena直方图均衡化的结果度量。
*/#include "highgui.h"
#include "cv.h"
#include<iostream>
using namespace std;void doEMD2(IplImage* img)
{/*对输入的图像做直方图均衡化处理,生成img2*/IplImage* pImageChannel[4] = {0, 0, 0, 0};IplImage* img2 = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);for(int i = 0; i < img->nChannels; i++){pImageChannel[i] = cvCreateImage(cvGetSize(img), img->depth,1);}//信道分离cvSplit(img, pImageChannel[0], pImageChannel[1], pImageChannel[2],pImageChannel[3]);for(int i = 0; i < img2->nChannels; i++){//直方图均衡化cvEqualizeHist(pImageChannel[i], pImageChannel[i]);}//信道组合cvMerge(pImageChannel[0],pImageChannel[1], pImageChannel[2],pImageChannel[3], img2);//绘制直方图int h_bins = 16, s_bins = 8;int hist_size[] = {h_bins, s_bins};//H 分量的变化范围float h_ranges[] = {0,180};//S 分量的变化范围float s_ranges[] = {0,255};float* ranges[] = {h_ranges,s_ranges};IplImage* hsv = cvCreateImage(cvGetSize(img), 8, 3);IplImage* hsv2 = cvCreateImage(cvGetSize(img2), 8, 3);IplImage* h_plane = cvCreateImage(cvGetSize(img), 8, 1);IplImage* s_plane = cvCreateImage(cvGetSize(img), 8, 1);IplImage* v_plane = cvCreateImage(cvGetSize(img), 8, 1);IplImage* planes[] = {h_plane, s_plane};IplImage* h_plane2 = cvCreateImage(cvGetSize(img2), 8, 1);IplImage* s_plane2 = cvCreateImage(cvGetSize(img2), 8, 1);IplImage* v_plane2 = cvCreateImage(cvGetSize(img2), 8, 1);IplImage* planes2[] = {h_plane2, s_plane2};// 将两幅图像转换到HSV颜色空间cvCvtColor(img, hsv, CV_BGR2HSV);cvCvtPixToPlane(hsv, h_plane, s_plane, v_plane, 0);cvCvtColor(img2, hsv2, CV_BGR2HSV);cvCvtPixToPlane(hsv2, h_plane2, s_plane2, v_plane2, 0);// 创建直方图CvHistogram* hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);CvHistogram* hist2 = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);// 根据H,S两个平面数据统计直方图cvCalcHist(planes, hist, 0, 0);cvCalcHist(planes2, hist2, 0, 0);//获取直方图统计///float max_value;//float max_value2;//cvGetMinMaxHistValue(hist, 0, &max_value, 0,0);//cvGetMinMaxHistValue(hist2, 0, &max_value2, 0, 0);//设置直方图显示图像int height = 240;int width = (h_bins * s_bins * 6);IplImage* hist_img = cvCreateImage(cvSize(width, height), 8, 3);IplImage* hist_img2 = cvCreateImage(cvSize(width, height), 8, 3);cvZero(hist_img);cvZero(hist_img2);//用来进行HSV到RGB颜色转换的临时图像//IplImage* hsv_color = cvCreateImage(cvSize(1,1), 8, 3);//IplImage* rgb_color = cvCreateImage(cvSize(1,1), 8, 3);//int bin_w = width/(h_bins * s_bins);//CvMat* sig1, *sig2;int numrows = h_bins*s_bins;sig1 = cvCreateMat(numrows, 3, CV_32FC1);sig2 = cvCreateMat(numrows, 3, CV_32FC1);for(int h = 0; h < h_bins; h++){for(int s = 0; s < s_bins; s++){//int i = h * s_bins + s;// 获得直方图中的统计次数, 计算显示在图中的高度float bin_val = cvQueryHistValue_2D(hist, h,s);cvSet2D(sig1, h*s_bins + s, 0, cvScalar(bin_val));cvSet2D(sig1, h*s_bins + s, 1, cvScalar(h));cvSet2D(sig1, h*s_bins + s, 2, cvScalar(s));bin_val = cvQueryHistValue_2D(hist2,h,s);cvSet2D(sig2, h*s_bins + s, 0, cvScalar(bin_val));cvSet2D(sig2, h*s_bins + s, 1, cvScalar(h));cvSet2D(sig2, h*s_bins + s, 2, cvScalar(s));}}float emd = cvCalcEMD2(sig1,sig2,CV_DIST_L2);cout<< emd<<endl;}

结果


这篇关于OpenCV入门(二十二)-- 陆地移动距离的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/869713

相关文章

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

从入门到精通MySQL联合查询

《从入门到精通MySQL联合查询》:本文主要介绍从入门到精通MySQL联合查询,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下... 目录摘要1. 多表联合查询时mysql内部原理2. 内连接3. 外连接4. 自连接5. 子查询6. 合并查询7. 插入查询结果摘要前面我们学习了数据库设计时要满

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

Redis 配置文件使用建议redis.conf 从入门到实战

《Redis配置文件使用建议redis.conf从入门到实战》Redis配置方式包括配置文件、命令行参数、运行时CONFIG命令,支持动态修改参数及持久化,常用项涉及端口、绑定、内存策略等,版本8... 目录一、Redis.conf 是什么?二、命令行方式传参(适用于测试)三、运行时动态修改配置(不重启服务

Python如何将OpenCV摄像头视频流通过浏览器播放

《Python如何将OpenCV摄像头视频流通过浏览器播放》:本文主要介绍Python如何将OpenCV摄像头视频流通过浏览器播放的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完... 目录方法1:使用Flask + MJPEG流实现代码使用方法优点缺点方法2:使用WebSocket传输视

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

MySQL DQL从入门到精通

《MySQLDQL从入门到精通》通过DQL,我们可以从数据库中检索出所需的数据,进行各种复杂的数据分析和处理,本文将深入探讨MySQLDQL的各个方面,帮助你全面掌握这一重要技能,感兴趣的朋友跟随小... 目录一、DQL 基础:SELECT 语句入门二、数据过滤:WHERE 子句的使用三、结果排序:ORDE

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解