opencv2对读书笔记——反投影直方图以检测待定的图像内容

一些小概念

1.直方图是图像内容的一个重要特性。

2.如果一幅图像的区域中显示的是一种独特的纹理或是一个独特的物体,那么这个区域的直方图可以看作是一个概率函数,它给出的是某个像素属于该纹理或物体的概率。

3.反投影直方图的作用是在于替换一个输入图像中每一个像素值,使其变成归一化直方图中对应的概率值。

这是一个什么样的过程

名字听起来感觉很高端,其实这个一个很简单的过程。

1.首先我们截取一个区域,作为目标区域。

2.然后将目标区域取直方图,并将其直方图归一化,并得到这个区域的概率。

3.利用calcBackProject函数在图像中检索。其中函数会利用区域概率,对图像中的像素点经行映射,映射到[0,1]区间,所以要扩大255倍显示。

4.这样一来因为是负图像,所以越暗的地方相似概率越大。

calcBackProject函数

其结构

cv::calcBackProject(&image,//目标图像
				1,            // 图像个数
				channels,     // 通道数量
				histogram,   // 进行反投影的直方图
				result,       // 结果图像
				ranges,       // 每个维度的阈值
				255.0         // 放缩因子
				);

该过程的实例

我们举个例子来说明上面说到的过程,我两个小婴儿的图像中我们截取婴儿头部皮肤,来检测婴儿全身皮肤在图像中的位置。

代码

#include "cv.h"
#include "highgui.h"
#include "histogram.h"
#include <iostream>
using namespace std;

#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>

class ObjectFinder {

private:

	float hranges[2];
	const float* ranges[3];
	int channels[3];

	float threshold;
	cv::MatND histogram;
	cv::SparseMat shistogram;

public:

	ObjectFinder() : threshold(0.1f){

		ranges[0]= hranges;
		ranges[1]= hranges;
		ranges[2]= hranges;
	}

	// 设置阈值
	void setThreshold(float t) {

		threshold= t;
	}

	// 返回阈值
	float getThreshold() {

		return threshold;
	}

	// 设置目标直方图,进行归一化
	void setHistogram(const cv::MatND& h) {
		histogram= h;
		cv::normalize(histogram,histogram,1.0);
	}

	// 查找属于目标直方图概率的像素
	cv::Mat find(const cv::Mat& image) {

		cv::Mat result;

		hranges[0]= 0.0;
		hranges[1]= 255.0;
		channels[0]= 0;
		channels[1]= 1;
		channels[2]= 2; 

		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 main()
{
	//读取圆图像
	cv::Mat initimage= cv::imread("../2.jpg");
	if (!initimage.data)
		return 0; 

	//显示原图像
	cv::namedWindow("原图像");
	cv::imshow("原图像",initimage);

	//读取灰度图像
	cv::Mat image= cv::imread("../2.jpg",0);
	if (!image.data)
		return 0; 

	//设置目标区域
	cv::Mat imageROI;
	imageROI= image(cv::Rect(262,151,113,150)); // 区域为小孩的脸部区域

	//显示目标区域
	cv::namedWindow("目标区域图像");
	cv::imshow("目标区域图像",imageROI);

	//计算目标区域直方图
	Histogram1D h;
	cv::MatND hist= h.getHistogram(imageROI);
	cv::namedWindow("目标区域直方图");
	cv::imshow("目标区域直方图",h.getHistogramImage(imageROI));

	//创建检查类
	ObjectFinder finder;
	//将目标区域直方图传入检测类
	finder.setHistogram(hist);

	//初始化阈值
	finder.setThreshold(-1.0f);

	//进行反投影
	cv::Mat result1;
	result1= finder.find(image);

	//创建负图像并显示概率结果
	cv::Mat tmp;
	result1.convertTo(tmp,CV_8U,-1.0,255.0);
	cv::namedWindow("负图像概率结果图像越暗概率越大");
	cv::imshow("负图像概率结果图像越暗概率越大",tmp);

	//得到二值反投影图像
	finder.setThreshold(0.01f);
	result1= finder.find(image);

	//在图像中绘制选中区域
	cv::rectangle(image,cv::Rect(262,151,113,150),cv::Scalar(0,0,0));

	//显示原图像
	cv::namedWindow("原图像的灰度图");
	cv::imshow("原图像的灰度图",image);

	//二值结果图
	cv::namedWindow("二值结果图");
	cv::imshow("二值结果图",result1);

	cv::waitKey();
	return 0;
}

输出结果

               -END-

opencv2对读书笔记——反投影直方图以检测待定的图像内容,布布扣,bubuko.com

时间: 2024-11-05 16:54:00

opencv2对读书笔记——反投影直方图以检测待定的图像内容的相关文章

opencv2对读书笔记——图像二值化——thresholded函数

opencv中的图像二值化函数threshold函数 其结构 double cv::threshold( //二值化函数 const CvArr* src, //原始图像 CvArr* dst, //输出图像 double threshold, //阈值 double max_value, //最大值 int threshold_type//阈值类型 ); 实例代码 #include "cv.h" #include "highgui.h" int main() {

opencv2对读书笔记——使用均值漂移算法查找物体

一些小概念 1.反投影直方图的结果是一个概率映射,体现了已知图像内容出如今图像中特定位置的概率. 2.概率映射能够找到最初的位置,从最初的位置開始而且迭代移动,便能够找到精确的位置,这就是均值漂移算法做的事情. 3.均值漂移算法是以迭代的方式锁定函数的局部最大值的. 关于均值漂移算法的过程(opencv) 事实上均值漂移算法就是寻找提前定义寻找区域中数据点的重心,或者说加权平均值.将寻找区域中心移动到数据点的重心处,并反复这个过程直到寻找区域重心收敛到一个稳定点. OpenCV中定义了两种终止条

《Github入门与实践》读书笔记 蟲咋先生的追求之旅(上)

<Github入门与实践>作者: [日] 大塚弘记 译者:支鹏浩/刘斌 简介 本书从Git的基本知识和操作方法入手,详细介绍了GitHub的各种功能,GitHub与其他工具或服务的协作,使用GitHub的开发流程以及如何将GitHub引入到企业中.在讲解GitHub的代表功能Pull Request时,本书专门搭建了供各位读者实践的仓库,邀请各位读者进行Pull Request并共同维护. 豆瓣地址:https://book.douban.com/subject/26462816/ 本以为对于

《Mastering Opencv ...读书笔记系列》车牌识别(I)

http://blog.csdn.net/jinshengtao/article/details/17883075/  <Mastering Opencv ...读书笔记系列>车牌识别(I) http://blog.csdn.net/jinshengtao/article/details/17954427   <Mastering Opencv ...读书笔记系列>车牌识别(II) Mastering Opencv ...读书笔记系列>车牌识别(I) 标签: 车牌分割svm西

【计算机视觉】借助图像直方图来检测特定物(MeanShift、CamShift算法)

直方图引入 直方图是一个简单的表,它给出了一幅图像或一组图像中拥有给定数值的像素数量.因此,灰度图像的直方图有256个条目(或称为容器).0号容器给出值为0的像素数目,1号容器给出值为1的像素个数,以此类推. 直方图反投影 直方图是图像内容的一个重要特性.如果一幅图像的区域中显示的是一种独特的纹理或是一个独特的物体,那么这个区域的直方图可以看做一个概率函数,它给出的是某个像素属于该纹理或物体的概率.这使得我们可以借助图像的直方图来检测特定的内容. 反投影直方图的方法是一种把目标概率分布映射到观测

《Effective C++》读书笔记汇总

我之前边读<Effective C++>边写下每个条款的读书笔记,这一版是C++11之前的版本.这里我将每个条款令我印象深刻的点小结一下. 1.C++包括:Plain C(面向过程).OOP(面向对象).模板(泛型和模板元编程).STL(C++标准库). 2.用inline.enum.const代替#define.#define定义的宏,一旦复杂起来,高手都很难掌控.不要带入C的习惯. 3.灵活使用const前缀.不需要进行改变的数据加上const前缀.指针的const前缀有两种形式,cons

【转】《windows核心编程》读书笔记

这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入,但应该是合理的.开头几章由于我追求简洁,往往是很多单独的字句,后面的内容更为连贯. 海量细节. 第1章    错误处理 1.         GetLastError返回的是最后的错误码,即更早的错误码可能被覆盖. 2.         GetLastError可能用于描述成功的原因(CreatEvent)

Linux内核架构读书笔记 - 2.5.3 处理优先级

1 优先级的内核表示 内核使用 0 - 139 表示内部优先级,值越低,优先级越高.0 -99 实时进程使用 nice 值 [-20,19]映射到范围100 - 139,如下图 内核定义了一系列宏来辅助优先级之间的转换 sched.h 1 /* 2 * Priority of a process goes from 0..MAX_PRIO-1, valid RT 3 * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH 4 *

Linux内核架构读书笔记 - 2.5.2 数据结构

调度系统各个组建关系如下 激活调度器两种方法:进程睡眠或其他原因放弃CPU,周期性检测 上述两个组件统称为通用调度器或核心调度器. 调度器用于判断接下来运行那个进程,内核支持不同的调度策略( 完全公平调度 实时调度 无事可做的空闲调度进程) 调度器被调用时候 需要执行体系相关的进程上下文切换 每个进程属于某个调度器类,各个调度器负责管理所属进程,通用调度器不涉及进程管理,都由调度器来 下面分别讲述: task_struct 成员 sched.h 1 struct task_struct { 2