opencv三色直方图程序

本文详细介绍了使用OpenCV库进行图像直方图绘制的方法,包括简版和标准版的代码实现,展示了如何分离RGB通道并分别计算各颜色通道的直方图,最后将直方图可视化。

1.简版
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>

using namespace cv;
using namespace std;

int main()
{
Mat srcImg=imread(“6.jpg”);
if(!srcImg.data){
printf(“载入图片出错了,请检查图片的正确位置”);
return false;
}
imshow(“原始图像”,srcImg);
//参量准备
int bins=256;
int hist_Size[]={bins};
float range[]={0,256};
const float* ranges[]={range};
MatND redHist,greenHist,blueHist;
int channel_b[]={0};//进行直方图计算(红色分量部分)
//进行红色分量直方图的计算
calcHist(&srcImg,1,channel_b,Mat(),blueHist,1,hist_Size,ranges,true,false);

//进行直方图绿色部分的计算
int channel_g[]={1};
calcHist(&srcImg,1,channel_g,Mat(),greenHist,1,hist_Size,ranges,true,false);

//进行直方图红色部分的计算
int channel_r[]={2};
calcHist(&srcImg,1,channel_r,Mat(),redHist,1,hist_Size,ranges,true,false);

double rMaxValue,gMaxValue,bMaxValue;
minMaxLoc(blueHist,0,&bMaxValue,0,0);//蓝色集中的值个数
minMaxLoc(greenHist,0,&gMaxValue,0,0);//绿色集中的值个数
minMaxLoc(redHist,0,&rMaxValue,0,0);

int scale=1;
int histHeight=256;
Mat histImage=Mat::zeros(histHeight,bins3,CV_8UC3);
for(int i=0;i<bins;i++)
{
float bBinValue=blueHist.at(i);
float gBinValue=greenHist.at(i);
float rBinValue=redHist.at(i);
int intensity_blue=cvRound(bBinValue
histHeight/bMaxValue);
int intensity_green=cvRound(gBinValuehistHeight/gMaxValue);
int intensity_red=cvRound(rBinValue
histHeight/rMaxValue);
//绘制各个分量
rectangle(histImage,Point(i*scale,histHeight-1),Point((i+1)scale-1,histHeight-intensity_blue),Scalar(255,0,0));
rectangle(histImage,Point((i+bins),histHeight-1),Point((i+1+bins)scale-1,histHeight-intensity_green),Scalar(0,255,0));
rectangle(histImage,Point(i+bins
2,histHeight-1),Point((i+bins
2+1)*scale-1,histHeight-intensity_red),Scalar(0,0,255));

}
imshow(“三色直方图”,histImage); //图像坐标和真正的二维坐标是有差异的
waitKey(0);
return 0;
}
2.标准版:
#include <opencv2\opencv.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
/本程序为分离通道的方式,把三分量分成三份,然后进行每一个分量的一维直方图的绘制/

using namespace cv;
using namespace std;

int main()
{
Mat srcImg=imread(“1.jpg”);
imshow(“原图”,srcImg);
if(!srcImg.data)
{
printf(“载入原图失败”);
return false;
}
//定义二维数组的
vector channels1;
Mat imageblueChannel;
Mat imagegreenChannel;
Mat imageredChannel;
split(srcImg,channels1);
imageblueChannel=channels1.at(0);
imagegreenChannel=channels1.at(1);
imageredChannel=channels1.at(2);

MatND dstbHist;
MatND dstgHist;
MatND dstrHist;

int dim=1;
float b1ranges[]={0,255};
float g1ranges[]={0,255};
float r1ranges[]={0,255};
const float *branges[]={b1ranges};
const float *granges[]={g1ranges};
const float *rranges[]={r1ranges};//这个就要注意名字的命名了,命名出错了可能就会寻址错误

int size=256;
int channels=0;

calcHist(&imageblueChannel,1,&channels,Mat(),dstbHist,dim,&size,branges);
calcHist(&imagegreenChannel,1,&channels,Mat(),dstgHist,dim,&size,granges);
calcHist(&imageredChannel,1,&channels,Mat(),dstrHist,dim,&size,rranges);

int scale=1;
Mat dst1Img(sizescale,size,CV_8U,Scalar(0));
Mat dst2Img(size
scale,size,CV_8U,Scalar(0));
Mat dst3Img(size*scale,size,CV_8U,Scalar(0));

double bminValue=0, bmaxValue=0,gminValue=0,gmaxValue=0,rminValue=0,rmaxValue=0;

minMaxLoc(dstbHist,&bminValue,&bmaxValue,0,0);

minMaxLoc(dstgHist,&gminValue,&gmaxValue,0,0);
minMaxLoc(dstrHist,&rminValue,&rmaxValue,0,0);
//printf("%f,%f",minValue,maxValue);
//绘制直方图
int hpt=saturate_cast(0.9size);//防止越界函数
for(int i=0;i<256;i++)
{
float binValue=dstbHist.at(i);
printf(“等级为%d的数量为:%f”,i,binValue);
int realValue=saturate_cast(binValue
hpt/bmaxValue);//对边界进行限制
rectangle(dst1Img,Point(iscale,size-1),Point((i+1)scale-1,size-realValue),Scalar(255));//从图像坐标入手的
}
for(int i=0;i<256;i++)
{
float binValue=dstgHist.at(i);
printf(“等级为%d的数量为:%f”,i,binValue);
int realValue=saturate_cast(binValue
hpt/gmaxValue);//对边界进行限制
rectangle(dst2Img,Point(i
scale,size-1),Point((i+1)scale-1,size-realValue),Scalar(255));//从图像坐标入手的
}
for(int i=0;i<256;i++)
{
float binValue=dstrHist.at(i);//获得的是数量呀
printf(“等级为%d的数量为:%f”,i,binValue);
int realValue=saturate_cast(binValue
hpt/rmaxValue);//对边界进行限制
rectangle(dst3Img,Point(i*scale,size-1),Point((i+1)*scale-1,size-realValue),Scalar(255));//从图像坐标入手的
}
imshow(“蓝色分量的直方图”,dst1Img);
imshow(“绿色分量的直方图”,dst2Img);
imshow(“红色分量的直方图”,dst3Img);
waitKey(0);
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值