问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

opencv中,怎么计算彩色图像的直方图calchist

发布网友 发布时间:2022-05-03 03:39

我来回答

2个回答

懂视网 时间:2022-05-05 03:42

1.一些小概念: (1) 像素在图像中的分布情况是这幅图像的一个重要特征。 (2) 直方图是一个简单的表,它给出了一幅图像或一组图像中用于给定数的像素数量。 2.calcHist 函数 calHist 是opencv 中可以计算直方图。 private:int histSize[1];//色度变换宽度floa

1.一些小概念:


(1) 像素值在图像中的分布情况是这幅图像的一个重要特征。

(2) 直方图是一个简单的表,它给出了一幅图像或一组图像中用于给定数值的像素数量。


2.calcHist 函数


calHist 是opencv 中可以计算直方图。


private:
		int histSize[1];//色度变换宽度
		float hranges[2];//像素的最小值及最大值
		const float * ranges[1];//
		int channels[1];//使用的通道
	public:
	 Histogram1D(){
		histSize[0] = 256;
		hranges[0] = 0.0;
		hranges[1] = 255.0;
		ranges[0] = hranges;
		channels[0] = 0;
	 }
	 cv::MatND getHistogram(const cv::Mat &image){
		cv::MatND hist;
		cv::calcHist(&image,1,channels,cv::Mat(),hist,1,histSize,ranges);
		return hist;
	 }

下面给出对一个具体图像求出直方图的例子


#include 
#include 
#include "cv.h"
#include "highgui.h"
#include 
using namespace std;

class Histogram1D {

private:
	int histSize[1];
	float hranges[2];
	const float* ranges[1];
	int channels[1];

public:
	Histogram1D() {
		histSize[0]= 256;
		hranges[0]= 0.0;
		hranges[1]= 255.0;
		ranges[0]= hranges; 
		channels[0]= 0; 
	}

 cv::MatND getHistogram(const cv::Mat &image) {
	
		cv::MatND hist;

		cv::calcHist(&image, //目标图像
			1,			// 计算一张直方图
			channels,	// 使用的通道数量
			cv::Mat(),	// 图像开关
			hist,		// 返回的直方图
			1,			// 1D直方图
			histSize,	// 色图宽度
			ranges		// 像素值的范围
			);

		return hist;
	}

	cv::Mat getHistogramImage(const cv::Mat &image){

		cv::MatND hist= getHistogram(image);

		double maxVal=0;
		double minVal=0;
		cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);

		cv::Mat histImg(histSize[0], histSize[0], CV_8U,cv::Scalar(255));

		int hpt = static_cast(0.9*histSize[0]);

		for( int h = 0; h < histSize[0]; h++ ) {

			float binVal = hist.at(h);
			int intensity = static_cast(binVal*hpt/maxVal);
			cv::line(histImg,cv::Point(h,histSize[0]),cv::Point(h,histSize[0]-intensity),cv::Scalar::all(0));
		}
		return histImg;
	}
};

int main()
{
	cv::Mat image= cv::imread("group.jpg",0);
	if (!image.data)
		return 0; 

	cv::namedWindow("Image");
	cv::imshow("Image",image);

	Histogram1D h;

	cv::MatND histo= h.getHistogram(image);

	for (int i=0; i<256; i++) 
		cout << "Value " << i << " = " << histo.at(i) << endl; 

	cv::namedWindow("Histogram");
	cv::imshow("Histogram",h.getHistogramImage(image));

	cv::waitKey();
	return 0;
}

输出结果


热心网友 时间:2022-05-05 00:50

CV_EXPORTS 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 accumulate=false );

参数1表示需要用来计算直方图的源图像序列,因此可以允许有多张大小一样,数据类型相同的图像被用来统计其直方图特征。

  参数2表示的就是使用多少张图像序列中的图像用于计算直方图。

  参数3的出现主要是考虑到输入的每一张图像有可能是多通道的,比如说RGB图就是3通道的,那么从统计意义上来讲,
一张RGB图其实就是3张单通道的图像,而计算直方图时其本质也是针对单张图像进行的。这里虽然我们输入的图像序列images中有很多图片,但是并不是
每一张图片的每一个通道都会被用来计算。所以参数3的功能是指定哪些通道的图像被用来计算(后面的解释都假设图像序列中图像是3通道的,那么有的图像可能
有多个通道都被用来计算,有的图像可能连一个通道都没有被采用),这时参数3里面保存的是通道的序号,那么图像序列images中的第一张图片的通道序号
(假设图像时3通道的)为0,1,2;images中第二张图片的图像序列接着上一次的,为3,4,5,;依次类推即可。

  参数4是mask掩膜操作,即指定每张图片的哪些像素被用于计算直方图,这个掩膜矩阵不能够针对特定图像设定特定的掩膜,因此在这里是一视同仁对待的。

  参数5是保存计算的直方图结果的矩阵,有可能是*矩阵。

  参数6是需要计算的直方图的维数。

  参数7是所需计算直方图的每一维的大小,即每一维bin的个数。

  参数8是所需计算直方图的每一维的范围,如果参数9的uniform为true,这此时的参数8的大小为2,里面的
元素值表示的是每一维的上下限这两个数字;如果参数9的uniform为false,则此时的参数8的大小为bin的个数,即参数7的值,参数8里面的元
素值需要人为的指定,即每一维的坐标值不一定是均匀的,需要人为指定。

  参数9如果为true的话,则说明所需计算的直方图的每一维按照它的范围和尺寸大小均匀取值;如果为false的话,说明直方图的每一维不是均匀分布取值的,参考参数8的解释。

  参数10如果为false,则表示直方图输出矩阵hist在使用该函数的时候被清0了,如果为true,则表示hist在使用calcHist()函数时没有被清0,计算的结果会累加到前一次保存的值中。

  使用该函数的时候需要注意,如果在默认参数的情况下uniform = true,则此时的ranges大小必须是histSize大小的两倍,并且channels的大小必须等于dims维数。

  从上面可以理解,channels里的值已经指定了使用哪些单通道的图像来计算目标直方图,因此一旦channels的尺寸确定,则对应的直方图的维数也就确定了,所以我们不能使用多张图像来计算一个一维的直方图。

以上内容来自:基础学习笔记之opencv(19):有关图像序列的直方图计算

[cpp] view plain copy print?
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

/** @函数 main */
int main( int argc, char** argv )
{
Mat src, dst;

/// 装载图像
src = imread( argv[1], 1 );

if( !src.data )
{ return -1; }

/// 分割成3个单通道图像 ( R, G 和 B )
vector<Mat> rgb_planes;
split( src, rgb_planes );

/// 设定bin数目
int histSize = 255;

/// 设定取值范围 ( R,G,B) )
float range[] = { 0, 255 } ;
const float* histRange = { range };

bool uniform = true; bool accumulate = false;

Mat r_hist, g_hist, b_hist;

/// 计算直方图:
calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );

// 创建直方图画布
int hist_w = 400; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/histSize );

Mat histImage( hist_w, hist_h, CV_8UC3, Scalar( 0,0,0) );

/// 将直方图归一化到范围 [ 0, histImage.rows ]
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );

/// 在直方图画布上画出直方图
for( int i = 1; i < histSize; i++ )
{
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
Scalar( 0, 0, 255), 2, 8, 0 );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
Scalar( 0, 255, 0), 2, 8, 0 );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
Scalar( 255, 0, 0), 2, 8, 0 );
}

/// 显示直方图
namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE );
imshow("calcHist Demo", histImage );

waitKey(0);

return 0;

}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
女生多大后可以不在长身高? 如何不用软件把手机投屏到电脑上手机屏幕怎样投放到电脑上 战时拒绝、故意延误军事订货罪既遂的处罚? 战时故意延误军事订货罪处罚标准 名师1+1导读方案:汤姆·索亚历险记目录 三星sm-g7200打开微信慢,无法正常收看,网速不慢。 笔记本电脑如何调亮屏幕亮度 大伙说说洗衣机要不要带烘干好 热烘干洗衣机怎么样 ef英语哪个好 改善、开发、提供、保护、建造,的近义词是什么 修筑的近义词和隐蔽的近义词。 哪位朋友,有好一点的微信中秋祝福短信,最好是带表情,图案的那种。短信祝... 修筑、凝结、耸立、智慧、神清气爽、隐隐约约的近义词 勇猛、惊奇、建筑的近义词是什么 笛子怎样贴膜才既好吹,又好听? 怎么看自己wifi是不是被蹭网了 oracle字段按rownumber 排序不准确怎么解决 小米Play手机无法识别SIM卡怎么处理? 小米play随机的流量卡不知怎么的欠了一元。咋回事,每月10G的流量顶多用一半。这一元到底怎么扣的 小米play自带流量什么意思???是送一张卡还是怎么回事?用完了怎么办,能不能自己装电话卡 转转上小米play有自带卡吗? 小米Play手机自带的电话卡给别的手机用,超10GB后依然被降到3G。 想知道两个人的三观是否“契合”,从哪里能看出来? 中国和西方的工匠精神体现了什么样的三观 三观企业管理集团有限公司怎么样? 三观视界是做什么的? 北汽新能源EX360动力电池参数是什么? 近年来,为什么毁三观的广告越来越多了? 特斯拉降价1天卖出蔚来1年销量,李斌喊话忠于选择,这样的三观你佩服吗? 形容建筑庄严庞大又小巧亲切的成语? 如何在power point做直方图 谁帮我看下我的opencv求灰度直方图代码啊~?!怎么该显示直方图的地方黑 ... 耗电软件指的是常用软件吗? 后台高耗电安什么软件? 美缝剂搞在瓷砖上面粘粘的有油漆的松香水可不可以搞得掉? 喝红酒会不会胖 喝红酒会胖吗? 每晚睡觉前喝红酒会胖吗? 晚上喝红酒会不会发胖 晚上喝一瓶红酒会胖吗 晚上喝红酒会不会胖哦~ 晚上喝红酒会不会长胖??? HM什么牌子呢 夜里喝红酒容易发胖吗 晚上喝甜型红酒会发胖吗? 地理hm什么意思 Rank()与DENSE_RANK()的区别? 英雄联盟中适合单带的上单英雄都有谁? 英雄联盟新英雄介绍触手怪的技能演示视频中 Q技能另外一个英雄是谁,拿着火把是皮肤还是新英雄!?