您的位置:首页 > 编程语言

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

2015-11-19 13:33 495 查看
灰度分析原理很简单,对一张深度为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,未经允许请勿用于商业用途.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: