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);
}

猜你喜欢

转载自blog.csdn.net/qq_31647835/article/details/80933201
今日推荐