C++ 计算C+中的平均值和标准偏差+;对于单通道直方图
我想计算HSV图像直方图的平均值和标准偏差,但我只想对V通道进行直方图和计算 我一直在阅读关于如何对一组通道执行此操作的示例,并尝试了这些方法,但我对最初创建直方图的方法是否正确感到困惑,因为当我尝试执行它时,程序不断崩溃 这是我目前拥有的(变量test是一个cv::Mat图像,它可以是您希望用于重新创建问题的任何图像)。我可能已经错过了一些明显的,for循环可能在值范围上是不正确的,但是我以前没有在C++中这样做过。C++ 计算C+中的平均值和标准偏差+;对于单通道直方图,c++,image,opencv,image-processing,histogram,C++,Image,Opencv,Image Processing,Histogram,我想计算HSV图像直方图的平均值和标准偏差,但我只想对V通道进行直方图和计算 我一直在阅读关于如何对一组通道执行此操作的示例,并尝试了这些方法,但我对最初创建直方图的方法是否正确感到困惑,因为当我尝试执行它时,程序不断崩溃 这是我目前拥有的(变量test是一个cv::Mat图像,它可以是您希望用于重新创建问题的任何图像)。我可能已经错过了一些明显的,for循环可能在值范围上是不正确的,但是我以前没有在C++中这样做过。 cv::cvtColor(test, test, CV_BG
cv::cvtColor(test, test, CV_BGR2HSV);
int v_bins = 50;
int histSize[] = { v_bins };
cv::MatND hist;
float v_ranges[] = { 0, 255};
cv::vector<cv::Mat> channel(3);
split(test, channel);
const float* ranges[] = { v_ranges };
int channels[] = {0};
cv::calcHist(&channel[2], 1, channels, cv::Mat(), hist, 1, histSize, ranges, true, false); //histogram calculation
float mean=0;
float rows= hist.size().height;
float cols = hist.size().width;
for (int v = 0; v < v_bins; v++)
{
std::cout << hist.at<float>(v, v) << std::endl;;
mean = mean + hist.at<float>(v);
}
mean = mean / (rows*cols);
std::cout << mean<< std::endl;;
cvt颜色(测试,测试,cv_BGR2HSV);
int v_bins=50;
int histSize[]={v_bins};
cv::MatND hist;
浮动v_范围[]={0,255};
向量通道(3);
拆分(测试、通道);
常量浮点*范围[]={v_范围};
int通道[]={0};
cv::calcHist(&channel[2],1,channel,cv::Mat(),hist,1,histSize,ranges,true,false)//直方图计算
浮动平均值=0;
浮动行=历史大小().高度;
float cols=历史大小().宽度;
对于(int v=0;vmean
和stddev
参数都是cv::Scalar
,因此需要执行mean[0]
和stddev[0]
以获得单通道数组hist
的双值
此代码将阐明其用途:
#include <opencv2\opencv.hpp>
#include <iostream>
int main()
{
cv::Mat test = cv::imread("path_to_image");
cv::cvtColor(test, test, CV_BGR2HSV);
int v_bins = 50;
int histSize[] = { v_bins };
cv::MatND hist;
float v_ranges[] = { 0, 255 };
cv::vector<cv::Mat> channel(3);
split(test, channel);
const float* ranges[] = { v_ranges };
int channels[] = { 0 };
cv::calcHist(&channel[2], 1, channels, cv::Mat(), hist, 1, histSize, ranges, true, false); //histogram calculation
cv::Scalar mean, stddev;
cv::meanStdDev(hist, mean, stddev);
std::cout << "Mean: " << mean[0] << " StdDev: " << stddev[0] << std::endl;
return 0;
}
#包括
#包括
int main()
{
cv::Mat test=cv::imread(“路径到图像”);
cv::CVT颜色(测试,测试,cv_BGR2HSV);
int v_bins=50;
int histSize[]={v_bins};
cv::MatND hist;
浮动v_范围[]={0,255};
向量通道(3);
拆分(测试、通道);
常量浮点*范围[]={v_范围};
int通道[]={0};
cv::calcHist(&channel[2],1,channel,cv::Mat(),hist,1,histSize,ranges,true,false);//直方图计算
cv:标量平均值,标准差;
cv::平均标准差(历史,平均标准差);
std::cout在计算直方图的统计数据时要小心。如果您只运行meanstdev
,您将得到bin值的平均值和stdev。这不会告诉您太多
可能你想要的是平均值和stdev强度
因此,如果您想从直方图(或一组直方图)推导出图像的平均值和标准偏差,则可以使用以下代码:
// assume histogram is of type cv::Mat and comes from cv::calcHist
double s = 0;
double total_hist = 0;
for(int i=0; i < histogram.total(); ++i){
s += histogram.at<float>(i) * (i + 0.5); // bin centre
total_hist += histogram.at<float>(i);
}
double mean = s / total_hist;
double t = 0;
for(int i=0; i < histogram.total(); ++i){
double x = (i - mean);
t += histogram.at<float>(i)*x*x;
}
double stdev = std::sqrt(t / total_hist);
平均值是x的值。因此直方图[x]/sum(直方图)
为您提供p(x)
。标准偏差的定义类似,来自。数字稍微简单一些,因为像素只能取整数值,并且是单位间隔的
注意:如果要使用累积
选项计算一批图像的归一化统计信息,这也很有用
改编自:cv::矢量频道(3)我认为这是必要的,因为HSV被分为3个通道,我只需要V通道来记录历史。我想知道是否有cv::vector?或std::vector@sturkmencv::vector
适用于3.0之前的OpenCV版本。有关详细信息,请参阅。好的。我得到了一个输出,但对我来说,我得到的结果看起来很奇怪。我得到了一个平均值为69271.2,标准偏差为86937.1。这对直方图来说是现实的还是出了什么问题?@Bardslyta我还通过计算定义中的平均值和标准偏差更新了答案。你可以看到结果与OpenCV相同。如果你不期望这些结果,也许你不应该计算我an和stddev在直方图上,但在图像上。好的。我似乎误读了平均值和标准偏差函数,试图在直方图上而不是在图像上进行。很抱歉,混淆了什么是v_bins?@Hossein“v”频道的bins数。请参阅第一个片段
// assume histogram is of type cv::Mat and comes from cv::calcHist
double s = 0;
double total_hist = 0;
for(int i=0; i < histogram.total(); ++i){
s += histogram.at<float>(i) * (i + 0.5); // bin centre
total_hist += histogram.at<float>(i);
}
double mean = s / total_hist;
double t = 0;
for(int i=0; i < histogram.total(); ++i){
double x = (i - mean);
t += histogram.at<float>(i)*x*x;
}
double stdev = std::sqrt(t / total_hist);
mean = sum(x * p(x)) // expectation
std = sqrt(sum( p(x)*(x - mean)**2 ) // sqrt(variance)