关闭

基于OPENCV的图像灰度分析及代码

1065人阅读 评论(0) 收藏 举报
分类:

灰度分析原理很简单,对一张深度为8位的图像,其灰度值为0~255区间,本文基于OPENCV设计了一个图像灰度分析的C++类,可以以图像的形式直观的显示图像的灰度分布,为后续处理提供参考。


本C++类的输入图像可以是单通道灰度图像,也可以是三通道彩色图像,但图像深度只能是只8位深度。


以下代码在VS2010 + OPENCV2.4.8 下调试通过。


CGrayHistogram类代码如下:


CGrayHistogram.h文件

<span style="font-size:14px;">/****************************************** 
* Copyright (C) 2015 HolaMirai(HolaMirai@163.com) 
* All rights reserved. 
*  
* 文件名:CGrayHistogram.h
* 摘要:CGrayHistogram类实现8位单通道灰度图像或三通道彩色图像各通道的灰度分析。
* 当前版本:V1.0, 2015年11月19日,HolaMirai,创建该文件
* 历史记录:... 
******************************************/  

/* 
* 类定义说明 
*/  
/******************************************** 
* CCalibration类 
* 使用buildGrayHistogram()分析图像灰度分布
* 使用buildColorHistogram()分析彩色图像各通道灰度分布和转换为灰度图像的灰度分布
*  
* 
********************************************/  


#ifndef CGRAYHISTOGRAM_H
#define CGRAYHISTOGRAM_H


#include <cv.h>
#include <highgui.h>

class CGrayHistogram
{
public:
	CGrayHistogram();
	~CGrayHistogram();

public:
	void buildGrayHistogram(IplImage *grayImage);     //创建灰度直方图
	void buildColorHistogram(IplImage *colorImage);   //创建彩色图像三通道直方图


public:
	
	IplImage *grayHist;  //灰度直方图
	IplImage *colorHist; //彩色图像三通道直方图

};

#endif</span>


CGrayHistogram.cpp文件

<span style="font-size:14px;">/****************************************** 
* Copyright (C) 2015 HolaMirai(HolaMirai@163.com) 
* All rights reserved. 
*  
* 文件名:CGrayHistogram.cpp 
* 摘要:灰度分析 CGrayHistogramn类的定实现文件
* 当前版本:V1.0, 2015年11月19日, HolaMirai, 创建该文件
* 历史记录:  
******************************************/  

#include "CGrayHistogram.h"

CGrayHistogram::CGrayHistogram()
{
	grayHist = cvCreateImage(cvSize(256*2,300),8,3);
	colorHist = cvCreateImage(cvSize(256*4,600),8,3); 
}

CGrayHistogram::~CGrayHistogram()
{
	cvReleaseImage(&grayHist);
	cvReleaseImage(&colorHist);
}

/* 
* 函数名称:buildGrayHistogram
* 函数功能:图像的灰度分布 
* 函数入口:  
* 输入参数:待分析的8位单通道或三通道图像
* 输出参数:无
* 返 回 值:无
* 其它说明:结果保存在 grayHist中
*/  
void CGrayHistogram::buildGrayHistogram(IplImage* grayImage)
{
	if( !grayImage ) return;
	IplImage *src = cvCreateImage(cvGetSize(grayImage),IPL_DEPTH_8U,1);
	
	
	if(grayImage->nChannels == 3)  
		cvCvtColor(grayImage, src, CV_BGR2GRAY);
	else
		src = cvCloneImage(grayImage);
	
	int size=256;  
	float range[]={0,255};  
	float* ranges[]={range};  


	CvHistogram* hist=cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1);  
	cvCalcHist(&src,hist,0,NULL);  
	
	float max=0;  
	cvGetMinMaxHistValue(hist,NULL,&max,NULL,NULL);  

	cvSet(grayHist,cvScalarAll(255),0);  
	double bin_width=(double)grayHist->width/size;  
	double bin_unith=(double)grayHist->height/max;  

	for(int i=0;i<size;i++)  
	{  
		CvPoint p0=cvPoint(i*bin_width,grayHist->height);  
		CvPoint p1=cvPoint((i+1)*bin_width, grayHist->height-cvGetReal1D(hist->bins,i)*bin_unith);  
		cvRectangle(grayHist,p0,p1,cvScalar(0,255,0),-1,8,0);  
	}  

	cvReleaseImage(&src);
}/** buildGrayHistogram()  **/

/* 
* 函数名称:buildColorHistogram
* 函数功能:彩色图像的各通道灰度分布
* 函数入口:  
* 输入参数:待分析的8位单通道或三通道图像
* 输出参数:无
* 返 回 值:无
* 其它说明:结果保存在colorHist中
*/  
void CGrayHistogram::buildColorHistogram(IplImage *colorImage)
{

	if( !colorImage ) return;
	IplImage *src = cvCreateImage(cvGetSize(colorImage),IPL_DEPTH_8U,3);

	if(colorImage->nChannels == 1)  
		cvCvtColor(colorImage, src, CV_GRAY2BGR);
	else
		src = cvCloneImage(colorImage);
 
	IplImage* r=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);   
	IplImage* g=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);   
	IplImage* b=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);  

	cvSplit(src,b,g,r,NULL);   
	IplImage* gray = cvCreateImage(cvGetSize(src),8,1);
	cvCvtColor(src,gray,CV_BGR2GRAY);  

	int size=256;  
	float range[]={0,255};  
	float* ranges[]={range};  

	CvHistogram* r_hist = cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1);  
	CvHistogram* g_hist = cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1);  
	CvHistogram* b_hist = cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1);  
	CvHistogram* hist   = cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1); 

	//r_hist
	cvCalcHist(&r,r_hist,0,NULL);  
	IplImage* r_dst=cvCreateImage(cvSize(400,300),8,3);  
	cvSet(r_dst,cvScalarAll(255),0);  
	float r_max=0;  
	cvGetMinMaxHistValue(r_hist,NULL,&r_max,NULL,NULL);  
	double r_bin_width=(double)r_dst->width/size;  
	double r_bin_unith=(double)r_dst->height/r_max;  
	for(int i=0;i<size;i++)  
	{  
		CvPoint p0=cvPoint(i*r_bin_width,r_dst->height);  
		CvPoint p1=cvPoint((i+1)*r_bin_width,r_dst->height-cvGetReal1D(r_hist->bins,i)*r_bin_unith);  
		cvRectangle(r_dst,p0,p1,cvScalar(255,0,0),-1,8,0);  
	}  

	//g_hist
	cvCalcHist(&g,g_hist,0,NULL);  
	IplImage* g_dst=cvCreateImage(cvSize(400,300),8,3);  
	cvSet(g_dst,cvScalarAll(255),0);  
	float g_max=0;  
	cvGetMinMaxHistValue(g_hist,NULL,&g_max,NULL,NULL);  
	double g_bin_width=(double)g_dst->width/size;  
	double g_bin_unith=(double)g_dst->height/g_max;  
	for(int i=0;i<size;i++)  
	{  
		CvPoint p0=cvPoint(i*g_bin_width,g_dst->height);  
		CvPoint p1=cvPoint((i+1)*g_bin_width,g_dst->height-cvGetReal1D(g_hist->bins,i)*g_bin_unith);  
		cvRectangle(g_dst,p0,p1,cvScalar(0,255,0),-1,8,0);  
	}  

	//b_hist
	cvCalcHist(&b,b_hist,0,NULL);  
	IplImage* b_dst=cvCreateImage(cvSize(400,300),8,3);  
	cvSet(b_dst,cvScalarAll(255),0);  
	float b_max=0;  
	cvGetMinMaxHistValue(b_hist,NULL,&b_max,NULL,NULL);  
	double b_bin_width=(double)b_dst->width/size;  
	double b_bin_unith=(double)b_dst->height/b_max;  
	for(int i=0;i<size;i++)  
	{  
		CvPoint p0=cvPoint(i*b_bin_width,b_dst->height);  
		CvPoint p1=cvPoint((i+1)*b_bin_width,b_dst->height-cvGetReal1D(b_hist->bins,i)*b_bin_unith);  
		cvRectangle(b_dst,p0,p1,cvScalar(0,0,255),-1,8,0);  
	}
	//gray_hist
	cvCalcHist(&gray,hist,0,NULL);  
	IplImage* gray_dst=cvCreateImage(cvSize(400,300),8,3);  
	cvSet(gray_dst,cvScalarAll(255),0);  
	float max=0;  
	cvGetMinMaxHistValue(hist,NULL,&max,NULL,NULL);  
	double bin_width=(double)gray_dst->width/size;  
	double bin_unith=(double)gray_dst->height/max;  
	for(int i=0;i<size;i++)  
	{  
		CvPoint p0=cvPoint(i*bin_width,gray_dst->height);  
		CvPoint p1=cvPoint((i+1)*bin_width,gray_dst->height-cvGetReal1D(hist->bins,i)*bin_unith);  
		cvRectangle(gray_dst,p0,p1,cvScalar(0),-1,8,0);  
	}  

	cvSetZero(colorHist);  
	CvRect rect = cvRect(0, 0, 400, 300);   
	cvSetImageROI(colorHist, rect);   
	cvCopy(r_dst, colorHist);

	rect = cvRect(400, 0, 400, 300);  
	cvSetImageROI(colorHist, rect);   
	cvCopy(g_dst, colorHist);

	rect = cvRect(0, 300, 400, 300);  
	cvSetImageROI(colorHist, rect);   
	cvCopy(b_dst, colorHist);

	rect = cvRect(400, 300, 400, 300);  
	cvSetImageROI(colorHist, rect);   
	cvCopy(gray_dst, colorHist);
	cvResetImageROI(colorHist);  
   
	cvReleaseImage(&src);

	cvReleaseImage(&r);  
	cvReleaseImage(&g);  
	cvReleaseImage(&b); 
	cvReleaseImage(&gray); 

	// temp ͼƬ
	cvReleaseImage(&r_dst);  
	cvReleaseImage(&g_dst);  
	cvReleaseImage(&b_dst);  
	cvReleaseImage(&gray_dst);  
}</span>


测试文件test.cpp


test.cpp文件

#include "opencv2/opencv.hpp"
#include "iostream"
#include "CGrayHistogram.h"
using namespace std;
void main()
{
	char winName[][15] = {"grayHist","EqualizeHist","colorHist"};
	IplImage *img = cvLoadImage("lena.jpg",1);
	IplImage *gray = cvLoadImage("lena.jpg",0);
	IplImage *grayEual = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);

	//灰度分布
	CGrayHistogram hist;
	hist.buildGrayHistogram(img);
	cvShowImage(winName[0],hist.grayHist);

	//灰度直方图均衡化后灰度分布
	cvShowImage("lena",gray);
	cvEqualizeHist(gray,grayEual);
	cvShowImage("lena_EqualizeHist",grayEual);
	hist.buildGrayHistogram(grayEual);
	cvShowImage(winName[1],hist.grayHist);

	//彩色图像各通道灰度分布
	hist.buildColorHistogram(img);
	cvShowImage(winName[2],hist.colorHist);

	cvWaitKey(0);

}

测试图片:



结果如下图:




参考资料:http://www.linuxidc.com/Linux/2012-09/70010.htm


 转载请注明作者和出处:http://blog.csdn.net/holamirai,未经允许请勿用于商业用途.

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:49212次
    • 积分:881
    • 等级:
    • 排名:千里之外
    • 原创:28篇
    • 转载:13篇
    • 译文:1篇
    • 评论:15条
    最新评论