功能是:打开摄像头,鼠标选定一个框,框内图像作为标准图像,计算出其直方图并显示出来;然后继续鼠标选定框,该框内的图像的直方图与标准图像的进行相似度计算,计算结果在终端输出,数值越大表示相似度越大。

opencv代码:

// hist_test.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>using namespace cv;
using namespace std;int nFrame_num=0;
bool pause=false;
bool tracking=false;
Rect preselectROI,selectROI;//用于存放手选的矩形
bool comp=true;Mat rhist,ghist,bhist;
int channels[]={0,1,2};
//const int histsize[]={256,256,256};
const int histsize[]={16,16,16};
const int histsize1=16;
float rranges[]={0,255};
float granges[]={0,255};
float branges[]={0,255};
float range[]={0,255};
const float *ranges1={range};//这里的ranges就相当于一个双指针了
const float *ranges[]={rranges,granges,branges};//ranges是个双指针,且前面一定要用const,即不可改变常量,提高程序的可读性和稳健性
//const float *ranges[]={{0,255},{0,255},{0,255}};void onMouse(int event,int x,int y,int,void *)
{if(event==CV_EVENT_LBUTTONDOWN){selectROI.x=x;selectROI.y=y;tracking=false;}else if(event==CV_EVENT_LBUTTONUP){selectROI.width=x-selectROI.x;selectROI.height=y-selectROI.y;tracking=true;comp=true;nFrame_num++;//选定后才算真正意义上的第一帧if(nFrame_num>=10)nFrame_num=10;//防止nFrame_num溢出}
}int  main(int argc, const char* argv[])
{Mat frame,img;Mat staRoiHist;MatND RoiHist;int DRAW_H=400,DRAW_W=400;Mat draw(DRAW_W,DRAW_H,CV_8UC3,Scalar(0,0,0));//建立一个显示直方图的图片,背景为纯黑色int DRAW_BIN_W=cvRound(DRAW_W/histsize1);/****打开摄像头****/VideoCapture cam(0);if(!cam.isOpened())return -1;/****鼠标捕捉****/namedWindow("camera",1);namedWindow("rgb_hist",1);setMouseCallback("camera",onMouse,0);//这里用的是面向对象的思想,只要有鼠标动作就会调用鼠标响应函数while(1){if(!pause)//暂停按钮只需控制视频的读取{        cam>>frame;if(frame.empty())break;//break此处跳出的是while语句,一般是跳出for或while语句,不要理解为跳出if语句}/*    if(1==nFrame_num){}*/if(tracking){Mat RoiImage(frame,selectROI);/*************************************************************************************************************************//****                                    calcHist():计算图像块的直方图矩阵                                                ****//****calcHist(),第1个参数为原数组区域列表;第二个参数为有计算几个原数组;参数3为需要统计的通道索引数;参数4为操作掩码****//****第5个参数为存放目标直方图矩阵;参数6为需要计算的直方图的维数;参数7为每一维的bin的个数;参数8为每一维数值的取值范围****//****参数10为每个bin的大小是否相同的标志,默认为1,即bin的大小都相同;参数11为直方图建立时清除内存痕迹标志,默认为0,即清除****//*************************************************************************************************************************/calcHist(&RoiImage,1,channels,Mat(),RoiHist,3,histsize,ranges);//原数组区域RoiImage,1个源,需要统计的通道索引为{0,1,2},//目标直方图RoiHist,3维,每一维的bin数histsize,取值范围为//ranges,实际上计算出的目标矩阵类似一维矩阵。/*************************************************************************************************************************//****                                normalize():根据某种范数或者数值范围归一化数组                                     ****//**** normalize(),参数1表示需要归一化的数组;参数2为归一化后的目的数组;参数3表示输出数值的最小值/最大值或者输出数值的范数;****//****  参数4表示输出数值的最小值/最大值;参数5表示归一化数组使用的归一化类型,默认值为使用L2范数;参数6为对应元素的掩膜矩阵 ****//****                                              默认值为空,即不采用掩膜操作                                            ****//*************************************************************************************************************************/normalize(RoiHist,RoiHist);//使用L2范数将RoiHist直方图原地归一化vector<Mat> rgb_planes;//这里的vector为向量,向量的数据类型为Mat结构体,向量的长度为3split(RoiImage,rgb_planes);//将rgb图分解到rgb_planes各个分量中calcHist(&rgb_planes[0],1,0,Mat(),rhist,1,&histsize1,&ranges1);normalize(rhist,rhist,0,DRAW_H,NORM_MINMAX);//进行最大最小值归一化calcHist(&rgb_planes[1],1,0,Mat(),ghist,1,&histsize1,&ranges1);normalize(ghist,ghist,0,DRAW_H,NORM_MINMAX);calcHist(&rgb_planes[2],1,0,Mat(),bhist,1,&histsize1,&ranges1);normalize(bhist,bhist,0,DRAW_H,NORM_MINMAX);if(nFrame_num==1){
//                preselectROI=selectROI;preselectROI.x=selectROI.x;preselectROI.y=selectROI.y;preselectROI.width=selectROI.width;preselectROI.height=selectROI.height;staRoiHist=RoiHist.clone();//第一次选定目标,作为标准模板目标}else if(nFrame_num>1&&comp==true){/*************************************************************************************************************************//****                                        compareHist():比较2个直方图的相似度                                         ****//****        compareHist(),参数1为比较相似度的直方图1;参数2为比较相似度的直方图2;参数3为相似度的计算方式。有四种,         ****//****                  分别为CV_COMP_CORREL,CV_COMP_CHISQR,CV_COMP_INTERSECT,CV_COMP_BHATTACHARYYA                     ****//*************************************************************************************************************************/double distence=compareHist(staRoiHist,RoiHist,CV_COMP_INTERSECT);//计算后面选定的与这次选定的相似度,使用INTERSECT,值越大越相似printf("与第1次选定的图像区域相似度为:%f\n",distence);//数组越大,相似度越大//显示直方图for(int i=1;i<histsize1;i++){//画直线中要注意2点,因为图片的原点在左上角,而直方图坐标系的原点在左下角,所以高度值都需要被直方图图纸高度减掉,另外取一维直方图时只能用at运算符line(draw,Point(DRAW_BIN_W*(i-1),DRAW_H-cvRound(rhist.at<float>((i-1)))),Point(DRAW_BIN_W*(i),DRAW_H-cvRound(rhist.at<float>(i))),Scalar(255,0,0),2,8,0);line(draw,Point(DRAW_BIN_W*(i-1),DRAW_H-cvRound(ghist.at<float>((i-1)))),Point(DRAW_BIN_W*(i),DRAW_H-cvRound(ghist.at<float>(i))),Scalar(0,255,0),2,8,0);line(draw,Point(DRAW_BIN_W*(i-1),DRAW_H-cvRound(bhist.at<float>((i-1)))),Point(DRAW_BIN_W*(i),DRAW_H-cvRound(bhist.at<float>(i))),Scalar(0,0,255),2,8,0);}imshow("rgb_hist",draw);draw=Mat::zeros(DRAW_W,DRAW_H,CV_8UC3);//每画完一次直方图后都进行一次清0操作comp=false;}rectangle(frame,selectROI,Scalar(0,255,0),2,8);//手动选定一次就显示一次}//end trackingrectangle(frame,preselectROI,Scalar(0,0,255),5,8);//初始的选定目标一直不变imshow("camera",frame);//键盘响应char c = (char)waitKey(10);if( c == 27 )break;switch(c){case 'p'://暂停键pause = !pause;break;default:;}}//end while;return 0;
}

compareHist函数 例子相关推荐

  1. 利用OpenCV的compareHist函数作直方图的相似度对比的源程序

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 OpenCV的compareHist函数用来计算 ...

  2. 【Matlab 控制】Simulink仿真+S函数例子

    Simulink 仿真+S函数例子 S 函数代码如下: function [sys,x0,str,ts,simStateCompliance] = Eg3_7_SFunction(t,x,u,flag ...

  3. OpenCV3学习(8.2)直方图相似度比较compareHist函数与EMD距离

    对输入的两张图像进行直方图均衡化及直方图计算步骤后,可以对两个图像的直方图进行对比,两张图像的直方图反映了该图像像素的分布情况,可以利用图像的直方图,来分析两张图像的关系. 如果我们有两张图像,并且这 ...

  4. compareHist函数

    直方图对比 目标 本文档尝试解答如下问题: 如何使用OpenCV函数 compareHist 产生一个表达两个直方图的相似度的数值. 如何使用不同的对比标准来对直方图进行比较. 原理 要比较两个直方图 ...

  5. sql decimal函数例子_leetcode题库-sql练习精讲系列--三、经典排名问题

    这是一个系列文章,这个系列的理念是通过一道题,搞懂一类题.涵盖了SQL面试最常考的知识点.搞懂这些题,面试时工作中sql不可能有问题. 文章分为引入问题-完整解析-答案-leetcode题和答案-知识 ...

  6. delphi 回调函数例子 用函数过程作为参数

    今天有个朋友问我怎么用函数或者过程作为函数的参数呢,我说网上有挺多的,然而他告诉我很多例子运行不起来,我搜了几个测试了下,不知道是不是我自己的软件版本的问题,运行不了,所以自己研究了下,把自己能运行的 ...

  7. Sqlserver常用函数例子说明

    在操作SQLServer的时候, 很多时候记不住具体的函数如何使用, 查找联机帮助还是嫌麻烦, 且有很多时候例子也不好懂, 下面对每个常用的函数用用例子说明,一目了然,你自己在数据库中执行一下,结果就 ...

  8. c语言自定义double函数例子,C语言的那些事——sqrt()函数 跟 double型数据的“%lf”...

    C语言的那些事--sqrt()函数 和 double型数据的"%lf" 计算函数y=2*x^2中的x的值.计算x的值. 原本这是一道很简单的编程题目,但是对sqrt()函数以及do ...

  9. 回调函数例子_Linux C - C基础篇八(函数)

    概念 函数可以被看作是一个由用户定义的一系列操作的集合.一般来说,函数用一个名字来表示.函数的操作数,称为参数,由一个位于括号中,并且用逗号分隔的参数列表指定,如果该函数没有参数需要传入,则这个列表为 ...

最新文章

  1. [云炬创业基础笔记]第六章商业模式测试13
  2. idea使用dababase tools时导出db2建表语句,索引显示错误
  3. javascript获取asp.net后台代码的方法
  4. WebApi项目创建CURD
  5. Taro+react开发(53) Taro提示操作
  6. Anaconda 安装 ml_metrics package
  7. Linux文件系统:编写一个内核文件系统
  8. 智能DBA呼声高、仅20%开发者懂操作系统、芯片人才匮乏,揭晓中国基础软件开发者现状
  9. 随机数生成器 java_Java中的随机数生成器
  10. Javascript 使用Qunit单元测试
  11. java最长同值路径_力扣——最长同值路径
  12. Dimensional 将 290 亿美元的共同基金转换为 ETF
  13. 爱普生R230打印机故障大全
  14. 基于javaweb+springboot的企业员工绩效工资管理系统(java+SpringBoot+FreeMarker+Mysql)
  15. (5)将一个数组中的值按逆序重新存放。例如原来顺序为8,6,5,4,1。要求改为1,4,5,6,8
  16. ACL国际计算机语言协会2019,干货 | 2019 AI 国际顶级学术会议一览表
  17. 129页4万字某智慧能源集团数字化管控平台项目 建设方案
  18. 阿里P9手写的Java核心开发手册(2022版)覆盖P5到P8所有技术栈
  19. 查找Windows和MacBook序列号
  20. Redis简介与基本使用

热门文章

  1. Android预优化那些事
  2. 14条建议,使你的IT职业生涯更上一层楼
  3. WINCE下创建多个文件分区
  4. Makefile 使用总结【转】
  5. 主从同步出现一下错误:Slave_IO_Running: Connecting
  6. 多线程之:用户态和内核态的区别
  7. 记录自定义的代码片段位置
  8. 同事反馈环:为什么度量和会议还不够充分
  9. 10分钟部署一个数据中心
  10. Linux系统状态检测及进程控制--2