#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】使用直方图统计像素
共20个文件
jpg:7个
cpp:6个
log:2个
4星 · 超过85%的资源 需积分: 47 44 下载量 107 浏览量
2016-10-01
22:52:33
上传
评论 1
收藏 3.71MB RAR 举报
温馨提示
爱分享、爱极客的编程怪兽--DaveBobo 博文 《【OpenCV学习笔记 007】使用直方图统计像素》 博文链接: http://blog.csdn.net/davebobo/article/details/52554968 OpenCV版本:2.4.9
资源推荐
资源详情
资源评论
收起资源包目录
【OpenCV学习笔记 007】使用直方图统计像素.rar (20个子文件)
【OpenCV学习笔记 007】使用直方图统计像素
Debug
【OpenCV学习笔记 007】使用直方图统计像素.sln 1KB
【OpenCV学习笔记 007】使用直方图统计像素
4.5反投影直方图以检测特定的图像内容.cpp 2KB
lol.jpg 63KB
Debug
【OpenCV学习笔记 007】使用直方图统计像素.log 95B
【OpenCV学习笔记 007】使用直方图统计像素.Build.CppClean.log 3KB
【OpenCV学.778E15FA.tlog
4.6使用均值漂移(Mean Shift)算法查找物体.cpp 5KB
4.3使用查找表修改图像外观.cpp 1KB
4.2计算图像的直方图.cpp 3KB
cloud.jpg 53KB
Baboon.jpg 138KB
【OpenCV学习笔记 007】使用直方图统计像素.vcxproj 5KB
grayHorse.jpg 113KB
horse.jpg 119KB
【OpenCV学习笔记 007】使用直方图统计像素.vcxproj.filters 1KB
4.7通过比较直方图检索相似图片.cpp 2KB
picture.jpg 19KB
Baboon2.jpg 138KB
4.4直方图均衡化.cpp 1KB
【OpenCV学习笔记 007】使用直方图统计像素.v12.suo 43KB
【OpenCV学习笔记 007】使用直方图统计像素.sdf 15.75MB
共 20 条
- 1
资源评论
- M_Kingsun2017-11-01可以用,谢谢分享
DaveBobo
- 粉丝: 741
- 资源: 52
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功