#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cv.h>
using namespace std;
class ColorHistogram{
private:
int histSize[3];
float hranges[2];
const float* ranges[3];
int channels[3];
public:
ColorHistogram(){
//准备彩色直方图的参数
histSize[0] = histSize[1] = histSize[2] = 256;
hranges[0] = 0.0; //BGR的范围
hranges[1] = 255.0;
ranges[0] = hranges; //所有通道拥有相同的范围
ranges[1] = hranges;
ranges[2] = hranges;
channels[0] = 0;
channels[1] = 1;
channels[2] = 2;
}
cv::SparseMat getHistogram(const cv::Mat &image);
cv::MatND getHueHistogram(const cv::Mat &image, int);
};
cv::SparseMat ColorHistogram::getHistogram(const cv::Mat &image){
cv::SparseMat hist(3, histSize, CV_32F);
//计算直方图
cv::calcHist(&image,
1, //仅计算一张图
channels, //通道数量
cv::Mat(), //不使用掩码图像
hist, //返回的直方图
3, //这是三维直方图
histSize, //项的数量
ranges //像素值的范围
);
return hist;
}
//1.使用掩码计算1D色调直方图 2.BGR图像转换为HSV色彩空间并去除低饱和度的像素
cv::MatND ColorHistogram::getHueHistogram(const cv::Mat &image, int minSaturation = 0){
cv::MatND hist;
//转换为HSV色彩空间
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);
}
//1D色调直方图的参数
hranges[0] = 0.0;
hranges[1] = 180.0;
channels[0] = 0; //色调通道
//计算直方图
cv::calcHist(
&hsv,
1, //仅计算一幅图
channels, //通道数量
mask, //二值掩码
hist, //返回的直方图
1, //这是1D的直方图
histSize, //项的数量
ranges //像素值的范围
);
return hist;
}
class ContentFinder{
private:
float hranges[2];
const float *ranges[3];
int channels[3];
float threshold;
cv::MatND histogram;
public:
ContentFinder() :threshold(-1.0f){
ranges[0] = hranges; //所有通道的值相同
ranges[1] = hranges;
ranges[2] = hranges;
}
void setThreshold(float t);
float getThreshold();
void setHistogram(const cv::MatND&h);
cv::Mat find(const cv::Mat &image, float minValue, float maxValue, int *channels, int dim);
};
//设置直方图的阈值[0,1]
void ContentFinder::setThreshold(float t){
threshold = t;
}
//获取阈值
float ContentFinder::getThreshold(){
return threshold;
}
//设置参考直方图
void ContentFinder::setHistogram(const cv::MatND&h){
histogram = h;
cv::normalize(histogram, histogram, 1.0);
}
//为了反投影直方图,我们需要指定图像、范围及所用范围通道的列表
cv::Mat ContentFinder::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];
cv::calcBackProject(&image,
1, //输入图像
channels, //所用通道的列表
histogram, //直方图
result, //反投影的结果
ranges, //值域
255.0 //缩放因子
);
//进行阈值化以得到二值图像
if (threshold > 0.0)
cv::threshold(result, result, 255 * threshold, 255, cv::THRESH_BINARY);
return result;
}
int main461(){
//读取第一张参考图像
cv::Mat srcImage = cv::imread("Baboon.jpg");
if (!srcImage.data) return 0;
//狒狒脸部的ROI
cv::Mat imageROI = srcImage(cv::Rect(200, 60, 80, 80));
//获取色调通道的直方图
int minSat = 65;
ColorHistogram hc;
cv::MatND colorhist = hc.getHueHistogram(imageROI, minSat);
//读取需要跟踪的图片
cv::Mat srcImage2 = cv::imread("Baboon2.jpg");
cv::Mat hsvColor;
//转到HSV空间
cv::cvtColor(srcImage2, hsvColor, CV_BGR2HSV);
//分割三通道为三幅图像
std::vector<cv::Mat>hsv;
cv::split(srcImage2, hsv);
//产生的直方图作为 ContentFinder实例
ContentFinder finder;
finder.setHistogram(colorhist);
//得到目标图像的反投影直方图
cv::Mat result;
int ch[255] = { 0 };
result = finder.find(hsvColor, 0.0f, 180.0f, ch, 1);
//识别低饱和度的像素
cv::threshold(hsv[1], hsv[1], minSat, 255, cv::THRESH_BINARY);
//去除低饱和度的像素
cv::bitwise_and(result, hsv[1], result);
cv::Rect rect(200, 60, 80, 80);
cv::rectangle(srcImage, rect, cv::Scalar(0, 0, 255));
cv::rectangle(srcImage2, rect, cv::Scalar(0, 0, 255));
//定义迭代的次数以及迭代的精度
cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER, 10, 0.01);
//meanShift算法 跟踪目标 并且得到新目标的位置rect
cv::meanShift(result, rect, criteria);
cv::rectangle(srcImage2, rect, cv::Scalar(0, 0, 255));
//显示图像
cv::namedWindow("result");
cv::imshow("result", result);
cv::namedWindow("srcImage2");
cv::imshow("srcImage2", srcImage2);
cv::waitKey(0);
return 0;
}
【OpenCV学习笔记 007】使用直方图统计像素
4星 · 超过85%的资源 需积分: 47 192 浏览量
2016-10-01
22:52:33
上传
评论 1
收藏 3.71MB RAR 举报
DaveBobo
- 粉丝: 739
- 资源: 52
最新资源
- NetOps-py通过sftp替换网络设备启动文件
- STM32单片机FPGA毕设电路原理论文报告任务驱动教学法在单片机课程教学中的应用
- STM32单片机FPGA毕设电路原理论文报告任务驱动法在单片机教学中的应用
- STM32单片机FPGA毕设电路原理论文报告人造金刚石压机智能化压力测控系统设计
- 以某列为依据匹配多项(Excel版)
- STM32单片机FPGA毕设电路原理论文报告人体短臂离心机实验台的显示控制系统
- STM32单片机FPGA毕设电路原理论文报告人工气候室监控系统的环境控制器研究
- STM32单片机FPGA毕设电路原理论文报告染整自动线张力控制系统的设计
- 数据挖掘与机器学习-实验
- 基于Linux系统Nginx的动态网站的LNMP环境源码包
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈