opencv —— calcHistminMaxLoc 计算并绘制图像直方图寻找图像全局最大最小值
Posted bjxqmy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv —— calcHistminMaxLoc 计算并绘制图像直方图寻找图像全局最大最小值相关的知识,希望对你有一定的参考价值。
直方图概述
简单来说,直方图就是对数据进行统计的一种方法,这些数据可以是梯度、方向、色彩或任何其他特征。它的表现形式是一种二维统计表,横纵坐标分别是统计样本和该样本对应的某个属性的度量。
计算直方图:calcHist 函数
calcHist 函数用于计算一个或多个阵列的直方图。
void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumul = false);
- images,输入的数组(图像)或数组集(图像集),他们需为相同深度(CV_8U 或 CV_32F)和相同尺寸。
- nimages,第一个参数中存放了多少张图象。
- channels,图像索引,会按照索引顺序依次计算图像直方图(注意,第一张图片索引为 0,以此类推)。
- mask,可选的掩膜操作,非零掩码元素用于标记待统计元素,需要与输入图像集有相同尺寸。
- hist,输出的目标直方图,一个二维数组。
- dims,输出目标直方图的维度。一般设为 1(线)。
- histSize,每张直方图的尺寸,即 x 轴最大值。
- ranges,每张直方图的值域范围,即 y 轴范围。
- uniform,直方图是否归一化的标识符,默认为 true。
- accumulate,在计算直方图时是否清空传入的 hist。true 表示不清空,false 表示清空。默认为 false。只有在想要统计多个图像序列中的累加直方图时才会设置为 true。
寻找最值:minMaxLoc 函数
minMaxLoc 函数的作用是在数组中找到全局最小和最大值。
void minMaxLoc(InputArray src, double* minVal, double* maxVal = 0, Point* minLoc = 0, Point* maxLoc = 0, InputArray mask = noArray());
- src,输入的数组,若是图像,需为单通道图像。
- minVal,返回最小值的指针。若无需返回,此值设为 NULL。
- maxVal,返回最大值的指针。若无需返回,此值设为 NULL。
- minLoc,返回最小值位置的指针(二维情况下)。若无需返回,此值设为 NULL。
- maxVal,返回最大值位置的指针(二维情况下)。若无需返回,此值设为 NULL。
- mask,可选的掩膜操作,非零掩码元素用于标记待统计元素,需要与输入图像集有相同尺寸。
代码示例:
#include<opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main() {
Mat src = imread("C:/Users/齐明洋/Desktop/证件照/6.jpg");
imshow("src", src);
//计算 BGR 三通道各自直方图
vector<Mat>bgr(3);
int channels[] = { 0,1,2 };
int histsize[] = { 256,256,256 };
float r[] = { 0,255 };
const float* ranges[] = { r,r,r };
calcHist(&src, 3, &channels[0], Mat(), bgr[0], 1, &histsize[0], &ranges[0], true);
calcHist(&src, 3, &channels[1], Mat(), bgr[1], 1, &histsize[1], &ranges[1], true);
calcHist(&src, 3, &channels[2], Mat(), bgr[2], 1, &histsize[2], &ranges[2], true);
//直方图归一化
normalize(bgr[0], bgr[0], 600, 0, NORM_L1);
normalize(bgr[1], bgr[1], 600, 0, NORM_L1);
normalize(bgr[2], bgr[2], 600, 0, NORM_L1);
//确定绘制高度
double mx[3];
minMaxLoc(bgr[0], NULL, &mx[0]);
minMaxLoc(bgr[1], NULL, &mx[1]);
minMaxLoc(bgr[2], NULL, &mx[2]);
int h = mx[0];
for (int i = 1; i < 3; i++) {
if (h < mx[i]) {
h == mx[i];
}
}
//绘制直方图
string names[3] = { "b_img","g_img","r_img" };
int w = 256;
Mat dst[3];//绘在三张背景上
dst[0] = Mat(h, w, src.type(), Scalar(0, 0, 0));
dst[1] = dst[0].clone();
dst[2] = dst[0].clone();
double width = w / 256;
Scalar colors[] = { Scalar(255,0,0),Scalar(0,255,0) ,Scalar(0,0,255) };
for (int i = 0; i < 3; i++) {
for (int j = 1; j < 256; j++) {
Point pre = Point((j - 1)*width, h - bgr[i].at<float>(j - 1));
Point next = Point(j*width, h - bgr[i].at<float>(j));
line(dst[i], pre, next, colors[i], 1);
}
imshow(names[i], dst[i]);
}
waitKey(0);
}
效果演示:
借鉴博客:https://blog.csdn.net/zhu_hongji/article/details/81663161
以上是关于opencv —— calcHistminMaxLoc 计算并绘制图像直方图寻找图像全局最大最小值的主要内容,如果未能解决你的问题,请参考以下文章
cmake错误:opencv2/opencv.hpp:opencv2/opencv.hpp:没有这样的文件或目录