opencv笔记二十五(直方图计算,图像归一化,HSV空间)**

直方图概念:

HSV空间:

HSV六棱锥

H参数表示色彩信息,即所处的光谱颜色的位置。该参数用一角度量来表示,红、绿、蓝分别纯度S为一比例值,范围从0到1,它表示成所选颜色的纯度和该颜色最大的纯度之间的比率。S=0时,只有灰度。相隔120度。互补色分别相差180度。

V表示色彩的明亮程度,范围从0到1。有一点要注意:它和光强度之间并没有直接的联系。

 

取值范围:

H色调:  0 — 180

S饱和度:  0 — 255

V亮度:  0 — 255

 

API:

split(// 把多通道图像分为多个单通道图像 

const Mat &src, //输入图像 

Mat* mvbegin)// 输出的通道图像数组

 

calcHist( //获取直方图数据

const Mat* images,//输入图像指针,

                   //可以是多幅图像,所有的图像必须有同样的深度(CV_8U or CV_32F)

                   //同时一副图像可以有多个channes

int nimage,//有几幅图

const int* channels,// 用哪几个通道

InputArray mask,// 输入mask,可选,不用 

OutputArray hist,//输出的直方图数据 

int dims,// 计算出来的直方图的维数。

const int* histsize,// 在每一维上直方图的个数。

                        //简单把直方图看作一个一个的竖条的话,就是每一维上竖条的个数。

const float** ranges,// 值域范围

bool uniform,// true by default 

bool accumulate// false by defaut )

 

normalize(

InputArry src,// 输入数组;

InputOutputArray dst,//输出数组,数组的大小和原数组一致;

double alpha=1,//用来规范围最小值

double beta=0,//规范范围最大值

int norm_type,//归一化选择的数学公式类型;NORM_MINMAX

int dtype=-1,//当为负,输出在大小深度通道数都等于输入,

                 //当为正,输出只在深度与输入不同,不同的地方由dtype决定;

InputArray mark)//掩码。选择感兴趣区域,选定后只能对该区域进行操作。

 

 

函数cvRound,cvFloor,cvCeil 都是用一种舍入的方法将输入浮点数转换成整数:

cvRound 返回跟参数最接近的整数值(四舍五入);

cvFloor 返回不大于参数的最大整数值;

cvCeil 返回不小于参数的最小整数值。

 

代码注意点:

 

1,const int hsize = 256;//是const int

2,normalize过后得到的数据类型为float

3,Mat histImage(rows,cols, CV_8UC3,Scalar(0,0,0));//先列数后行数(先宽后长

4,至于为什么400 - cvRound(t2.at<float>(i))要用400-,我还不太懂,但是400-是对的如果没有这个减法,得出来的图总点数远超过图像最大像素值;


 

附上代码:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
int main(int agrc, char** agrv) {
	Mat t1, t2, t3, t4,t5;
	t1 = imread("test.png");
	if (!t1.data) {
		cout << "WRONG";
		return -1;
	}
	imshow("T1", t1);
	vector<Mat> b;
	split(t1, b);
	const int hsize = 256;
	float range[] = { 0,256 };
	const float *ranges = { range };
	calcHist(&b[0], 1, 0, Mat(), t2, 1, &hsize, &ranges, true,false);
	calcHist(&b[1], 1, 0, Mat(), t3, 1, &hsize, &ranges, true, false);
	calcHist(&b[2], 1, 0, Mat(), t4, 1, &hsize, &ranges, true, false);
	int hw = 512, binw = hw / hsize, histh=400;
	normalize(t2, t2, 0, 400, NORM_MINMAX, -1, Mat());
	normalize(t3, t3, 0, 400, NORM_MINMAX, -1, Mat());
	normalize(t4, t4, 0, 400, NORM_MINMAX, -1, Mat());
	namedWindow("TRY", 0);
	Mat histImage(400, 256, CV_8UC3,Scalar(0,0,0));//400是高度,256是宽度
	for (int i = 1; i < hsize; i++) {
		line(histImage, Point(i - 1, 400 - cvRound(t2.at<float>(i-1))), 
			Point(i, 400 - cvRound(t2.at<float>(i))), Scalar(0, 255, 255), 1, 8);
		line(histImage, Point(i - 1, 400 - cvRound(t3.at<float>(i - 1))), 
			Point(i, 400 - cvRound(t3.at<float>(i))), Scalar(255,0, 255), 1, 8);
		line(histImage, Point(i - 1, 400 - cvRound(t4.at<float>(i - 1))), 
			Point(i, 400 - cvRound(t4.at<float>(i))), Scalar(255, 255,0), 1, 8);
	}
	imshow("TRY", histImage);


	waitKey(0);
}
	Mat t1, t2, t3, t4,t5;
	t1 = imread("test.png");
	if (!t1.data) {
		cout << "WRONG";
		return -1;
	}
	imshow("T1", t1);
	vector<Mat> b;
	split(t1, b);
	const int hsize = 256;
	float range[] = { 0,256 };
	const float *ranges = { range };
	calcHist(&b[0], 1, 0, Mat(), t2, 1, &hsize, &ranges, true,false);
	calcHist(&b[1], 1, 0, Mat(), t3, 1, &hsize, &ranges, true, false);
	calcHist(&b[2], 1, 0, Mat(), t4, 1, &hsize, &ranges, true, false);
	int hw = 512, binw = hw / hsize, histh=400;
	normalize(t2, t2, 0, 400, NORM_MINMAX, -1, Mat());
	normalize(t3, t3, 0, 400, NORM_MINMAX, -1, Mat());
	normalize(t4, t4, 0, 400, NORM_MINMAX, -1, Mat());
	namedWindow("TRY", 0);
	Mat histImage(400, 256, CV_8UC3,Scalar(0,0,0));//400是高度,256是宽度
	for (int i = 1; i < hsize; i++) {
		line(histImage, Point(i - 1, 400 - cvRound(t2.at<float>(i-1))), 
			Point(i, 400 - cvRound(t2.at<float>(i))), Scalar(0, 255, 255), 1, 8);
		line(histImage, Point(i - 1, 400 - cvRound(t3.at<float>(i - 1))), 
			Point(i, 400 - cvRound(t3.at<float>(i))), Scalar(255,0, 255), 1, 8);
		line(histImage, Point(i - 1, 400 - cvRound(t4.at<float>(i - 1))), 
			Point(i, 400 - cvRound(t4.at<float>(i))), Scalar(255, 255,0), 1, 8);
	}
	imshow("TRY", histImage);


	waitKey(0);
}

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值