OpenCV2马拉松第10圈——直方图反向投影(back project)
- 灰度图像的反向投影
- 彩色图像的反向投影
- 利用反向投影做object detect
- 依据模版图像,得到模版图像的灰度直方图.
- 对灰度直方图对归一化,归一化后是个概率分布,直方图的积分是1
- 依据概率分布的直方图,求输入图像的投影图,也就是对每个像素点,我们依据灰度值,能够得到其概率
- 得到的投影图是介于[0,1]之间的,为了方便显示,要作对应的扩大,一般以255最经常使用
最后,进行了一次二值化
-
C++: void calcBackProject(const
Mat* images, int nimages, const int* channels, InputArray hist, OutputArray backProject, const float** ranges, double scale=1, bool uniform=true ) -
- images – Source arrays. They all should have the same depth, CV_8U or CV_32F ,
and the same size. Each of them can have an arbitrary number of channels. - nimages – Number of source images.
- channels – The list of channels used to compute the back projection. The number of channels must match the histogram dimensionality. The first array channels are numerated from 0
to images[0].channels()-1 , the second array channels are counted from images[0].channels() to images[0].channels() + images[1].channels()-1,
and so on. - hist – Input histogram that can be dense or sparse.
- backProject – Destination back projection array that is a single-channel array of the same size and depth as images[0] .
- ranges – Array of arrays of the histogram bin boundaries in each dimension. See calcHist() .
- scale – Optional scale factor for the output back projection.
- uniform – Flag indicating whether the histogram is uniform or not (see above).
- images – Source arrays. They all should have the same depth, CV_8U or CV_32F ,
对于參数就不多作解释了,由于和计算直方图的參数差点儿一摸一样,scale是个扩大系数,常常取255.我们通过以下的样例来进一步巩固。
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std; class Histogram1D {
private:
int histSize[1]; // number of bins
float hranges[2]; // min and max pixel value
const float* ranges[1];
int channels[1]; // only 1 channel used here
public:
Histogram1D() {
histSize[0]= 256;
hranges[0]= 0.0;
hranges[1]= 255.0;
ranges[0]= hranges;
channels[0]= 0;
} Mat getHistogram(const cv::Mat &image) {
Mat hist;
calcHist(&image,1,channels,Mat(),hist,1,histSize,ranges);
return hist;
}
}; Mat applyLookUp(const cv::Mat& image,const cv::Mat& lookup) {
Mat result;
cv::LUT(image,lookup,result);
return result;
} int main( int, char** argv )
{
Mat image,gray,backproj;
image = imread( argv[1], 1 );
if( !image.data )
return -1;
cvtColor(image, gray, CV_BGR2GRAY); Mat imageROI;
imageROI= gray(cv::Rect(360,55,40,50)); // 模版图像 Histogram1D h;
Mat hist= h.getHistogram(imageROI);
normalize(hist,hist,1.0); //归一化,得到概率直方图
float range[] = { 0, 255 };
const float* ranges = { range };
calcBackProject( &gray, 1, 0, hist, backproj, &ranges, 255.0); //反向投影,最重要的一步 namedWindow("after project");
imshow("after project",backproj); Mat lut(1,256,CV_8U);
for (int i=0; i<256; i++) {
lut.at<uchar>(i)= 255-i; //reverse操作
}
Mat out = applyLookUp(backproj,lut);
namedWindow("after reverse");
imshow("after reverse",out); threshold(out, out, 240 ,255, THRESH_BINARY); // 以240为分界线,<240为0,否则为255
namedWindow("after threshold");
imshow("after threshold",out); waitKey(0);
return 0;
}
之前有提到过,灰度反向投影太不准确,非常多错误的点都被弄进来了,以下,我们实现彩色反向投影。
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.
Mat getHistogram(const Mat &image) {
Mat 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;
calcHist(&image, 1, channels,Mat(), hist,3,histSize,ranges);
return hist;
}
Mat colorReduce(const Mat &image, int div=64) {
int n= (int)(log((double)(div))/log(2.0));
// mask used to round the pixel value
uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
Mat_<Vec3b>::const_iterator it= image.begin<Vec3b>();
Mat_<Vec3b>::const_iterator itend= image.end<Vec3b>();
// Set output image (always 1-channel)
Mat result(image.rows,image.cols,image.type());
Mat_<Vec3b>::iterator itr= result.begin<Vec3b>();
for ( ; it!= itend; ++it, ++itr) {
(*itr)[0]= ((*it)[0]&mask) + div/2;
(*itr)[1]= ((*it)[1]&mask) + div/2;
(*itr)[2]= ((*it)[2]&mask) + div/2;
}
return result;
}
};
最须要注意的是colorReduce这种方法
class ContentFinder {
private:
float hranges[2];
const float* ranges[3];
int channels[3];
float threshold;
Mat histogram;
public:
ContentFinder() : threshold(-1.0f) {
hranges[0]= 0.0;
hranges[1]= 255.0;
channels[0]= 0;
channels[1]= 1;
channels[2]= 2;
ranges[0]= hranges;
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;
}
//设置了直方图,并归一化,生成概率直方图
void setHistogram(const Mat& h) {
histogram= h;
normalize(histogram,histogram,1.0);
}
Mat find(const Mat& image) {
Mat result;
//最重要的一步,产生反向投影图
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;
}
};
然后,看下我们的main函数
int main( int, char** argv )
{
Mat color;
color = imread( argv[1], 1 );
if( !color.data )
return -1; ColorHistogram hc; // reduce colors
color = hc.colorReduce(color,32);
// blue sky area
Mat imageROI = color(Rect(0,0,165,75));
Mat hist= hc.getHistogram(imageROI);
ContentFinder finder;
finder.setHistogram(hist);
finder.setThreshold(0.05f); Mat result= finder.find(color); namedWindow("sample");
imshow("sample",result); waitKey(0);
return 0;
}
我们来看一下效果,先看原图,我们选取了左上角的蓝天作模版图
OpenCV2马拉松第10圈——直方图反向投影(back project)的更多相关文章
- OpenCV2马拉松第12圈——直方图比較
收入囊中 使用4种不同的方法进行直方图比較 葵花宝典 要比較两个直方图, 首先必需要选择一个衡量直方图相似度的对照标准.也就是先说明要在哪个方面做对照. 我们能够想出非常多办法,OpenCV採用了下面 ...
- OpenCV2马拉松第17圈——边缘检測(Canny边缘检測)
计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g 收入囊中 利用OpenCV Canny函数进行边缘检測 掌握Canny算法基本理论 ...
- OpenCV2马拉松第15圈——边缘检測(Laplace算子,LOG算子)
收入囊中 拉普拉斯算子 LOG算子(高斯拉普拉斯算子) OpenCV Laplacian函数 构建自己的拉普拉斯算子 利用拉普拉斯算子进行图像的锐化 葵花宝典 在OpenCV2马拉松第14圈--边缘检 ...
- OpenCV2马拉松第13圈——模版匹配
收入囊中 在http://blog.csdn.net/abcd1992719g/article/details/25505315这里,我们已经学习了怎样利用反向投影和meanshift算法来在图像中查 ...
- OpenCV2马拉松第9圈——再谈对照度(对照度拉伸,直方图均衡化)
收入囊中 lookup table 对照度拉伸 直方图均衡化 葵花宝典 lookup table是什么东西呢? 举个样例,假设你想把图像颠倒一下,f[i] = 255-f[i],你会怎么做? for( ...
- OpenCV2马拉松第22圈——Hough变换直线检測原理与实现
计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g/article/details/27220445 收入囊中 Hough变换 概率Ho ...
- openCV2马拉松第18圈——坐标变换
计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g 收入囊中 仿射变换 坐标映射 利用坐标映射做一些效果,例如以下 watermark/ ...
- OpenCV2马拉松第14圈——边缘检測(Sobel,prewitt,roberts)
收入囊中 差分在边缘检測的角色 Sobel算子 OpenCV sobel函数 OpenCV Scharr函数 prewitt算子 Roberts算子 葵花宝典 差分在边缘检測究竟有什么用呢?先看以下的 ...
- OpenCV2马拉松第2圈——读写图片
收入囊中 用imread读取图片 用nameWindow和imshow展示图片 cvtColor彩色图像灰度化 imwrite写图像 Luv色彩空间转换 初识API 图像读取接口 image = im ...
随机推荐
- 设计模式之笔记--命令模式(Command)
命令模式(Command) 定义 命令模式(Command),将一个请求封闭为一个对象,从而使你可以用不同的请求对客户进行参数化:对请求排除或记录请求日志,以及支持可撤销的操作. 类图 描述 Comm ...
- go语言入门(三)
条件语句 go语言的条件语句结构如下: go语言的条件语句和其他语言类似.简单列举下: 1.if 语句,布尔表达式不需要括号 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } 2 ...
- Dubbo使用
[注:本文参考<Dubbo入门---搭建一个最简单的Demo框架>,感谢原创作者的知识探索与奉献] 一.Dubbo背景和简介 Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起. ...
- Linux 硬盘挂载方法
linux 硬盘分区,分区,删除分区,格式化,挂载,卸载笔记 硬盘挂载操作工作步骤: 1.先查看目前机器上有几块硬盘,查看命令有两种: 命令1:# fdisk –l 命令2:# dmesg | gre ...
- Asp.Net MVC4 之Url路由
先来看下面两个个url,对比一下: http://xxx.yyy.com/Admin/UserManager.aspx http://xxx.yyy.com/Admin/DeleteUser/1001 ...
- spring boot 使用不同的profile来加载不同的配置文件
在开发过程之中,经常需要在开发和测试环境中进行互相切换,当切换的同时需要加载相应的配置文件,因此要经常 性的对配置文件进行相应的修改,长此以往感到十分痛苦.如果能针对开发和测试环境分别建两个不同的配置 ...
- CentOS7.6使用flatpak安装软件
1.安装flatpak(CentOS 7已默认安装Flatpak) yum -y install flatpak 2.添加Flathub仓库 flatpak remote-add --if-not-e ...
- Gitlab基本管理<一>
一. 创建Gitlab中第一个项目 1. Gitlab项目的可见类型有三种级别. Private project: 该级别是只有项目拥有者或者已经得到授权的人可以访问该项目,或者这些人是该项目组的成员 ...
- HttpServletRequest继承字ServletRequest的常用方法
//获取请求的完整路径String origUrl = req.getRequestURL().toString(); //获取查询的参数String queryStr = req.getQueryS ...
- 二分+并查集【bzoj3007】[SDOI2012]拯救小云公主
Description 英雄又即将踏上拯救公主的道路-- 这次的拯救目标是--爱和正义的小云公主. 英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是上千只boss.当英雄意 ...