opecv2 MeanShift 使用均值漂移算法查找物体
#if !defined OFINDER
#define OFINDER #include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp> class ContentFinder { private: float hranges[2];
const float* ranges[3];
int channels[3]; float threshold;
cv::MatND histogram;
cv::SparseMat shistogram;
bool isSparse; public: ContentFinder() : threshold(0.1f), isSparse(false) { ranges[0]= hranges; // all channels have the same range
ranges[1]= hranges;
ranges[2]= hranges;
} // Sets the threshold on histogram values [0,1]
void setThreshold(float t) { threshold= t;
} // Gets the threshold
float getThreshold() { return threshold;
} // Sets the reference histogram
void setHistogram(const cv::MatND& h) { isSparse= false;
histogram= h;
cv::normalize(histogram,histogram,1.0);
} // Sets the reference histogram
void setHistogram(const cv::SparseMat& h) { isSparse= true;
shistogram= h;
cv::normalize(shistogram,shistogram,1.0,cv::NORM_L2);
} cv::Mat find(const cv::Mat& image) { cv::Mat result; hranges[0]= 0.0; // range [0,255]
hranges[1]= 255.0;
channels[0]= 0; // the three channels
channels[1]= 1;
channels[2]= 2; if (isSparse) { // call the right function based on histogram type cv::calcBackProject(&image,
1, // one image
channels, // vector specifying what histogram dimensions belong to what image channels
shistogram, // the histogram we are using
result, // the resulting back projection image
ranges, // the range of values, for each dimension
255.0 // the scaling factor is chosen such that a histogram value of 1 maps to 255
); } else { cv::calcBackProject(&image,
1, // one image
channels, // vector specifying what histogram dimensions belong to what image channels
histogram, // the histogram we are using
result, // the resulting back projection image
ranges, // the range of values, for each dimension
255.0 // the scaling factor is chosen such that a histogram value of 1 maps to 255
);
} // Threshold back projection to obtain a binary image
if (threshold>0.0)
cv::threshold(result, result, 255*threshold, 255, cv::THRESH_BINARY); return result;
} cv::Mat find(const cv::Mat& image, float minValue, float maxValue, int *channels, int dim) { cv::Mat result; hranges[0]= minValue;
hranges[1]= maxValue; for (int i=0; i<dim; i++)
this->channels[i]= channels[i]; if (isSparse) { // call the right function based on histogram type cv::calcBackProject(&image,
1, // we only use one image at a time
channels, // vector specifying what histogram dimensions belong to what image channels
shistogram, // the histogram we are using
result, // the resulting back projection image
ranges, // the range of values, for each dimension
255.0 // the scaling factor is chosen such that a histogram value of 1 maps to 255
); } else { cv::calcBackProject(&image,
1, // we only use one image at a time
channels, // vector specifying what histogram dimensions belong to what image channels
histogram, // the histogram we are using
result, // the resulting back projection image
ranges, // the range of values, for each dimension
255.0 // the scaling factor is chosen such that a histogram value of 1 maps to 255
);
} // Threshold back projection to obtain a binary image
if (threshold>0.0)
cv::threshold(result, result, 255*threshold, 255, cv::THRESH_BINARY); return result;
} }; #endif #if !defined COLHISTOGRAM
#define COLHISTOGRAM #include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
class ColorHistogram { private: int histSize[3];
float hranges[2];
const float* ranges[3];
int channels[3]; public: ColorHistogram() { // Prepare arguments for a color histogram
histSize[0]= histSize[1]= histSize[2]= 256;
hranges[0]= 0.0; // BRG range
hranges[1]= 255.0;
ranges[0]= hranges; // all channels have the same range
ranges[1]= hranges;
ranges[2]= hranges;
channels[0]= 0; // the three channels
channels[1]= 1;
channels[2]= 2;
} // Computes the histogram.
cv::MatND getHistogram(const cv::Mat &image) { cv::MatND hist; // BGR color histogram
hranges[0]= 0.0; // BRG range
hranges[1]= 255.0;
channels[0]= 0; // the three channels
channels[1]= 1;
channels[2]= 2; // Compute histogram
cv::calcHist(&image,
1, // histogram of 1 image only
channels, // the channel used
cv::Mat(), // no mask is used
hist, // the resulting histogram
3, // it is a 3D histogram
histSize, // number of bins
ranges // pixel value range
); return hist;
} // Computes the 1D Hue histogram with a mask.
// BGR source image is converted to HSV
cv::MatND getHueHistogram(const cv::Mat &image) { cv::MatND hist; // Convert to Lab color space
cv::Mat hue;
cv::cvtColor(image, hue, CV_BGR2HSV); // Prepare arguments for a 1D hue histogram
hranges[0]= 0.0;
hranges[1]= 180.0;
channels[0]= 0; // the hue channel // Compute histogram
cv::calcHist(&hue,
1, // histogram of 1 image only
channels, // the channel used
cv::Mat(), // no mask is used
hist, // the resulting histogram
1, // it is a 1D histogram
histSize, // number of bins
ranges // pixel value range
); return hist;
} cv::MatND getHueHistogram(const cv::Mat &image,int minSaturation)
{
cv::MatND hist;
cv::Mat hsv;
cv::cvtColor(image,hsv,CV_BGR2HSV);
cv::Mat mask;
if(minSaturation>0)
{
std::vector<cv::Mat>v;
cv::split(hsv,v);
cv::threshold(v[1],mask,minSaturation,255,cv::THRESH_BINARY);
}
hranges[0]=0.0;
hranges[1]=180.0;
channels[0]=0;
calcHist(&hsv,1,channels,mask,hist,1,histSize,ranges);
return hist;
} }; #endif #include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/video/video.hpp>
#include<iostream>
#include"colorhistogram.h"
#include"ContentFinder.h" using namespace std;
using namespace cv; int main()
{
Mat image=imread("d:/test/opencv/baboon1.jpg");
Mat imageROI=image(Rect(110,260,35,40));
int minSat=65;
ColorHistogram hc;
MatND colorhist=hc.getHueHistogram(imageROI,minSat); namedWindow("image 1");
imshow("image 1",image); ContentFinder finder;
finder.setHistogram(colorhist);
Mat hsv;
image=imread("d:/test/opencv/baboon3.jpg");
namedWindow("image 2");
imshow("image 2",image);
cvtColor(image,hsv,CV_BGR2HSV);
vector<Mat>v;
split(hsv,v);
threshold(v[1],v[1],minSat,255,THRESH_BINARY);
cv::namedWindow("Saturation");
cv::imshow("Saturation",v[1]);
int channel[1]={0};
Mat result=finder.find(hsv,0.0f,180.0f,channel,1); cv::namedWindow("Result Hue");
cv::imshow("Result Hue",result); cv::bitwise_and(result,v[1],result);
cv::namedWindow("Result Hue and");
cv::imshow("Result Hue and",result); finder.setThreshold(-1.0f);//
result= finder.find(hsv,0.0f,180.0f,channel,1);
cv::bitwise_and(result,v[1],result);
cv::namedWindow("Result Hue and raw");
cv::imshow("Result Hue and raw",result); cv::Rect rect(110,260,35,40);
cv::rectangle(image, rect, cv::Scalar(0,0,255)); cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER,10,0.01);
cout << "meanshift= " << cv::meanShift(result,rect,criteria) << endl;// cv::rectangle(image, rect, cv::Scalar(0,255,0));// // Display image
cv::namedWindow("Image 2 result");
cv::imshow("Image 2 result",image); cv::waitKey();
return 0; }
opecv2 MeanShift 使用均值漂移算法查找物体的更多相关文章
- opencv2对读书笔记——使用均值漂移算法查找物体
一些小概念 1.反投影直方图的结果是一个概率映射,体现了已知图像内容出如今图像中特定位置的概率. 2.概率映射能够找到最初的位置,从最初的位置開始而且迭代移动,便能够找到精确的位置,这就是均值漂移算法 ...
- Meanshift均值漂移算法
通俗理解Meanshift均值漂移算法 Meanshift车手?? 漂移?? 秋名山??? 不,不,他是一组算法, 今天我就带大家来了解一下机器学习中的Meanshift均值漂移. Mea ...
- 使用Opencv中均值漂移meanShift跟踪移动目标
Mean Shift均值漂移算法是无参密度估计理论的一种,无参密度估计不需要事先知道对象的任何先验知识,完全依靠训练数据进行估计,并且可以用于任意形状的密度估计,在某一连续点处的密度函数值可由该点邻域 ...
- 基于MeanShift的目标跟踪算法及实现
这次将介绍基于MeanShift的目标跟踪算法,首先谈谈简介,然后给出算法实现流程,最后实现了一个单目标跟踪的MeanShift算法[matlab/c两个版本] csdn贴公式比较烦,原谅我直接截图了 ...
- Opencv均值漂移pyrMeanShiftFiltering彩色图像分割流程剖析
meanShfit均值漂移算法是一种通用的聚类算法,它的基本原理是:对于给定的一定数量样本,任选其中一个样本,以该样本为中心点划定一个圆形区域,求取该圆形区域内样本的质心,即密度最大处的点,再以该点为 ...
- 机器学习实战---K均值聚类算法
一:一般K均值聚类算法实现 (一)导入数据 import numpy as np import matplotlib.pyplot as plt def loadDataSet(filename): ...
- Kosaraju 算法查找强连通分支
有向图 G = (V, E) 的一个强连通分支(SCC:Strongly Connected Components)是一个最大的顶点集合 C,C 是 V 的子集,对于 C 中的每一对顶点 u 和 v, ...
- 回朔法/KMP算法-查找字符串
回朔法:在字符串查找的时候最容易想到的是暴力查找,也就是回朔法.其思路是将要寻找的串的每个字符取出,然后按顺序在源串中查找,如果找到则返回true,否则源串索引向后移动一位,再重复查找,直到找到返回t ...
- 数据结构与算法--KMP算法查找子字符串
数据结构与算法--KMP算法查找子字符串 部分内容和图片来自这三篇文章: 这篇文章.这篇文章.还有这篇他们写得非常棒.结合他们的解释和自己的理解,完成了本文. 上一节介绍了暴力法查找子字符串,同时也发 ...
随机推荐
- 【codeforces 757E】Bash Plays with Functions
[题目链接]:http://codeforces.com/problemset/problem/757/E [题意] 给你q个询问; 每个询问包含r和n; 让你输出f[r][n]; 这里f[0][n] ...
- MVC设计模式与JavaWEB三层架构
一.MVC设计模式 MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controlle ...
- MyBatis学习总结(4)——解决字段名与实体类属性名不相同的冲突
一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), ...
- Java相关知识(一)
1. 作用域public.protected.private以及不写时的差别? public 表示公有.声明的为公共成员变量和函数成员.在整个类内类外都可使用,对全部用户开放,能够直接进行调用 pri ...
- iOS-UIImage imageWithContentsOfFile 和 imageName 对照
1.imageWithContentsOfFile NSString *imagePath = [NSString stringWithFormat:@"%@/%@",[[NSBu ...
- SQL学习之使用order by 依照指定顺序排序或自己定义顺序排序
我们通常须要依据客户需求对于查询出来的结果给客户提供自己定义的排序方式,那么我们通常sql须要实现方式都有哪些,參考很多其它资料总结例如以下(不完好的和错误望大家指出): 一.假设我们仅仅是对于在某个 ...
- 深搜解Riding the Fences
Riding the Fences Farmer John owns a large number of fences that must be repairedannually. He traver ...
- [luogu P4197] Peaks 解题报告(在线:kruskal重构树+主席树 离线:主席树+线段树合并)
题目链接: https://www.luogu.org/problemnew/show/P4197 题目: 在Bytemountains有N座山峰,每座山峰有他的高度$h_i$.有些山峰之间有双向道路 ...
- select … into outfile 备份恢复(load data)以及mysqldump时间对比
select … into outfile 'path' 备份 此种方式恢复速度非常快,比insert的插入速度要快的多,他跟有备份功能丰富的mysqldump不同的是,他只能备份表中的数据,并不能包 ...
- POJ 1950暴搜
思路: 暴力枚举好了..每回判断一下-- 用long long会超时 但是10^20会爆int... 不过仔细想一想 超过10^9的数肯定拼不回0啊-- 猥琐用int AC了 (当然可以打表 ) // ...