直方图
汇总通道绘制
三个通道混合绘制和把图像转换成灰度再绘制单通道生成的直方图是一样的
f1 = Mat::ones(frame.rows, frame.cols, CV_8U)*255;
//创建
MatND hist;
int channels[] = {0, 1, 2};
int histSize = 255;
float ranges[] = { 0, 255 };
const float* histRange = { ranges };
calcHist(&frame, 1, channels, Mat(), hist, 1, &histSize, &histRange);
normalize(hist, hist, frame.rows-10,0, NORM_INF);
//绘制
float unitDistance = f5.cols/(float)hist.rows;
for( int i = 0; i < hist.rows; i++ ){
line( f5, cv::Point( i*unitDistance, f5.rows) , cv::Point( i*unitDistance, hist.at(i)), Scalar(0), unitDistance*1.5);
}
上面创建的是单通道直方图,以及绘制方法,MatND是可以创建n维矩阵,这里用的只有一维,得到的数组是 [0,rows]的一长条数据, 在这里还对数值进行了标准化,标准化中的参数在这里简单讲一下,将整体数据压缩到一个范围内。
分别绘制三个通道
f2 = Mat::zeros(frame.rows, frame.cols, CV_8UC3);
for (int j=0; j<3; j++) {
int channels1[] = {j};
MatND hist1;
int histSize1 = 255;
float ranges1[] = { 0, 255 };
const float* histRange1 = { ranges1 };
calcHist(&frame, 1, channels1, Mat(), hist1, 1, &histSize1, &histRange1);
normalize(hist1, hist1, frame.rows-10,0, NORM_MINMAX);
float unitDistance1 = frame.cols/(float)hist1.rows;
Scalar colorRan(arc4random()%255,arc4random()%255,arc4random()%255);
for( int i = 0; i < hist1.rows-1; i++ ){
line( f2, cv::Point( i*unitDistance, hist1.at(i)) , cv::Point( (i+1)*unitDistance, hist1.at(i+1)), colorRan, 5);
}
}
只计算部分区域(遮罩区域直方图)
//遮罩
Mat mask = Mat::zeros(frame.rows, frame.cols, CV_8U);
mask({int(frame.cols*.3),int(frame.rows*.1),int(frame.cols*.4),int(frame.rows*.4)}) = 255;
//放置位置
calcHist(&f3, 1, channels, mask, hist, 1, &histSize, &histRange);
//图像的裁剪在图像处理的位操作中有提到,记住不要在原图上显示,否则没区别
bitwise_and(f3, f3, f5, mask);
直方图均值化
equalizeHist(poolColor[0], fEq);
输入和输出都是单通道,不能对彩色处理。。。
CLAHE 保留细节的调整方式
分成小块来处理
cvtColor(f3, f3, CV_BGR2GRAY);
Ptr clahe = createCLAHE(2,{8,8});
clahe->apply(f3, f5);
类型 | 说明 | 最低值 | 最高值 |
---|---|---|---|
NORM_INF | 高值设置最高,最低值为0 | 按高值和0的比例 | 最高值 |
NORM_L1 | 每个数➗总和的比例 | 低比例 | 高比例(永远不会是100%,除非只有一个值 |
NORM_L2 | 未知 | ||
NORM_MINMAX | 每个数占最高数的比例 | 低比例 | 1 |
直方图反向投影
略