OpenCV 计算图像一维直方图

OpenCV直方图计算学习  

环境:Visual studio  2012 +  opencv 2.4.5

统计彩色图像的指定区域的rgb通道的直方图分布


// HistogramCalculate.cpp : 定义控制台应用程序的入口点。
//计算给定图像区域的直方图

#include "stdafx.h"
#include 
   
   
    
    
#include 
    
    
     
     

using namespace std;
using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
{
	string filename = "meinv1.jpg";
	string winname = "MainWindow";
	namedWindow(winname,1);

	Mat src, dst;//声明原始图像和目标图像

	/// 装载图像
    src = imread( filename, 1 );
    if( !src.data ) //判断图像是否成功读取
    { return -1; }
	///显示读入的图像
	imshow(winname,src);

	///将原图像分割成三个单通道图像
	vector
     
     
      
       rgb_planes; //图像数组

	//给定图像中的某个矩形区域
	Rect roi(0,0,src.cols,src.rows);
	dst = src(roi);//提取矩形区域中的图像块
	split(dst,rgb_planes);//split函数将三通道图像分割成单通道图像
	 
	//设定直方图中bin的数目
	int histSize = 128;
	//设定取值范围
	float range[] = {0,256};//R、G、B三个特征的范围都是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++)
   {
	   //矩形图表示
	   rectangle( histImage,Point((i-1)*bin_w,hist_h),Point(i*bin_w,hist_h-cvRound(r_hist.at
      
      
       
       (i-1))),Scalar(0,0,255),1,8,0);
	   rectangle( histImage,Point((i-1)*bin_w,hist_h),Point(i*bin_w,hist_h-cvRound(g_hist.at
       
       
         (i-1))),Scalar(0,255,0),1,8,0); rectangle( histImage,Point((i-1)*bin_w,hist_h),Point(i*bin_w,hist_h-cvRound(b_hist.at 
        
          (i-1))),Scalar(255,0,0),1,8,0); //折线表示 line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at 
         
           (i-1)) ) , Point( bin_w*(i), hist_h - cvRound(r_hist.at 
          
            (i)) ), Scalar( 0, 0, 255), 1, 8, 0 ); line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at 
           
             (i-1)) ) , Point( bin_w*(i), hist_h - cvRound(g_hist.at 
            
              (i)) ), Scalar( 0, 255, 0), 1, 8, 0 ); line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at 
             
               (i-1)) ) , Point( bin_w*(i), hist_h - cvRound(b_hist.at 
              
                (i)) ), Scalar( 255, 0, 0), 1, 8, 0 ); } /// 显示直方图 namedWindow("calcHist Demo",0); imshow("calcHist Demo", histImage ); waitKey(0); return 0; } 
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   




下面的程序用了inRange函数,生成mask模板将r,g,b值限制在某一个区间内,然后调用calcHist函数

// HistogramCalculate2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
   
   
    
    
#include 
    
    
     
     

using namespace std;
using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
{
	string filename = "E:\\素材\\flower1.jpg";
	string winname = "MainWindow";
	namedWindow(winname,1);

	Mat src, dst;//声明原始图像和目标图像

	/// 装载图像
    src = imread( filename, 1 );
    if( !src.data ) //判断图像是否成功读取
    { return -1; }
	///显示读入的图像
	imshow(winname,src);
	
	///将原图像分割成三个单通道图像
	vector
     
     
      
       rgb_planes; //图像数组
	split(src,rgb_planes);//split函数将三通道图像分割成单通道图像
	
	//将数值低于min大于max的像素点排除在统计之外
	int r_min = 10,r_max = 256; //红色通道的统计范围
	int g_min = 20,g_max = 256; //绿色通道的统计范围
	int b_min = 30,b_max = 256; //蓝色通道的统计范围
	Mat red_mask,green_mask,blue_mask,mask;
	//调用inRange函数生成掩膜矩阵
	inRange(rgb_planes[0],r_min,r_max,red_mask); 
	//cvtColor(red_mask,mask,CV_GRAY2RGB); imshow("red mask",red_mask);waitKey(0);
	inRange(rgb_planes[1],g_min,g_max,green_mask);
	//cvtColor(green_mask,mask,CV_GRAY2RGB); imshow("green mask",green_mask);waitKey(0);
	inRange(rgb_planes[2],b_min,b_max,blue_mask);
	//cvtColor(blue_mask,mask,CV_GRAY2RGB); imshow("blue mask",blue_mask);waitKey(0);

	//设定直方图中bin的数目
	int histSize = 256;
	//设定取值范围
	float range[] = {0,256};//R、G、B三个特征的范围都是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,red_mask,r_hist,1,&histSize,&histRange,uniform,accumulate);
	calcHist(&rgb_planes[1],1,0,green_mask,g_hist,1,&histSize,&histRange,uniform,accumulate);
	calcHist(&rgb_planes[2],1,0,blue_mask,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++)
   {
	   //矩形图表示
	   /*rectangle( histImage,Point((i-1)*bin_w,hist_h),Point(i*bin_w,hist_h-cvRound(r_hist.at
      
      
       
       (i-1))),Scalar(0,0,255),1,8,0);
	   rectangle( histImage,Point((i-1)*bin_w,hist_h),Point(i*bin_w,hist_h-cvRound(g_hist.at
       
       
         (i-1))),Scalar(0,255,0),1,8,0); rectangle( histImage,Point((i-1)*bin_w,hist_h),Point(i*bin_w,hist_h-cvRound(b_hist.at 
        
          (i-1))),Scalar(255,0,0),1,8,0);*/ //折线表示 line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at 
         
           (i-1)) ) , Point( bin_w*(i), hist_h - cvRound(r_hist.at 
          
            (i)) ), Scalar( 0, 0, 255), 1, 8, 0 ); line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at 
           
             (i-1)) ) , Point( bin_w*(i), hist_h - cvRound(g_hist.at 
            
              (i)) ), Scalar( 0, 255, 0), 1, 8, 0 ); line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at 
             
               (i-1)) ) , Point( bin_w*(i), hist_h - cvRound(b_hist.at 
              
                (i)) ), Scalar( 255, 0, 0), 1, 8, 0 ); } /// 显示直方图 namedWindow("calcHist Demo",0); imshow("calcHist Demo", histImage ); waitKey(0); return 0; } 
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

运行结果:


由于代码段

 
 
//将数值低于min大于max的像素点排除在统计之外
int r_min = 10 , r_max = 256 ; //红色通道的统计范围
int g_min = 20 , g_max = 256 ; //绿色通道的统计范围
int b_min = 30 , b_max = 256 ; //蓝色通道的统计范围
Mat red_mask , green_mask , blue_mask , mask ;
//调用inRange函数生成掩膜矩阵
inRange ( rgb_planes [ 0 ], r_min , r_max , red_mask );
//cvtColor(red_mask,mask,CV_GRAY2RGB); imshow("red mask",red_mask);waitKey(0);
inRange ( rgb_planes [ 1 ], g_min , g_max , green_mask );
//cvtColor(green_mask,mask,CV_GRAY2RGB); imshow("green mask",green_mask);waitKey(0);
inRange ( rgb_planes [ 2 ], b_min , b_max , blue_mask );
//cvtColor(blue_mask,mask,CV_GRAY2RGB); imshow("blue mask",blue_mask);waitKey(0);
的作用,使得RGB各个通道的直方图起始位置各不相同


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值