现在的位置: 首页 > 综合 > 正文

图像增强之线性灰度增强

2014年01月13日 ⁄ 综合 ⁄ 共 2744字 ⁄ 字号 评论关闭

图像模糊不清或曝光过度的情况下,可以通过线性灰度增强来对图像内的像素进行线性扩展,改变图片的显示效果。

转换公式: g(x,y)=((d-c)/(b-a))(f(x,y)-a)+c

其中,f(x,y)为转换前图像,其灰度范围为[a,b];g(x,y)为转换后图像,其灰度范围为[c,d]。

//线性灰度增强 g(x,y)=[(d-c)/(b-a)]*(f(x,y)-a)+c
bool GrayLinearTransform(IplImage* src, IplImage* dst, uchar dstStart, uchar dstEnd)
{
	uchar* srcData = (uchar*)src->imageData;
	//获取图像最大最小灰度(分情况可简化为255-0)
	int imageMax,imageMin;
	imageMax = imageMin = srcData[0];
	for( int x = 0; x < src->height; x++)
		for(int y = 0; y < src->width; y++)
		{
			int value = srcData[x*src->widthStep+y];
			if( imageMax < value)
				imageMax = value;
			else
				if(imageMin>value)
					imageMin = value;
		}
	float linearRatio = float(dstEnd-dstStart)/(imageMax-imageMin);
	for( int x = 0; x < src->height; x++)
		for(int y = 0; y < src->width; y++)
		{
			int step = src->widthStep;
			int a = srcData[x*step+y];
			int bb = linearRatio*(a-imageMin)+ dstStart;
			dst->imageData[x*step+y] =   bb;
		}
	return true;
}

在OpenCV中,函数

cvNormalize( const CvArr* src, CvArr* dst,
                          double a CV_DEFAULT(1.), double b CV_DEFAULT(0.),
                          int norm_type CV_DEFAULT(CV_L2),
                          const CvArr* mask CV_DEFAULT(NULL) );

也可实现相同功能:

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

#include "stdafx.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>


// 隐藏 console 窗口
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

//线性灰度增强 g(x,y)=[(d-c)/(b-a)]*(f(x,y)-a)+c
bool GrayLinearTransform(IplImage* src, IplImage* dst, uchar dstStart, uchar dstEnd)
{
	uchar* srcData = (uchar*)src->imageData;
	//获取图像最大最小灰度(分情况可简化为255-0)
	int imageMax,imageMin;
	imageMax = imageMin = srcData[0];
	for( int x = 0; x < src->height; x++)
		for(int y = 0; y < src->width; y++)
		{
			int value = srcData[x*src->widthStep+y];
			if( imageMax < value)
				imageMax = value;
			else
				if(imageMin>value)
					imageMin = value;
		}
	float linearRatio = float(dstEnd-dstStart)/(imageMax-imageMin);
	for( int x = 0; x < src->height; x++)
		for(int y = 0; y < src->width; y++)
		{
			int step = src->widthStep;
			int a = srcData[x*step+y];
			int bb = linearRatio*(a-imageMin)+ dstStart;
			dst->imageData[x*step+y] =   bb;
		}
	return true;
}


int main( int argc, char** argv )
{
	cvNamedWindow( "win",1);
	::cvMoveWindow("win",300,100);
    IplImage* src = cvLoadImage( "C:\\Users\\Administrator\\Pictures\\lena.jpg", 1 );
	//cvShowImage("win", src); 
	//cvWaitKey(0);
	IplImage * dst_gray = cvCreateImage( cvGetSize(src), src->depth, 1);
	cvSetZero(dst_gray);
	cvCvtColor(src,dst_gray,CV_BGR2GRAY);//得到灰度图
	cvShowImage("win", dst_gray);
	cvWaitKey(0);
	IplImage* transform = ::cvCreateImage(cvGetSize(dst_gray),dst_gray->depth,1);
	cvSetZero(transform);
	if(GrayLinearTransform(dst_gray,transform,100,200))
	{
		cvShowImage("win", transform);
		cvWaitKey(0);
	}
	IplImage* transform2=::cvCreateImage(cvGetSize(dst_gray),dst_gray->depth,1);
	cvSetZero(transform2);
	cvNormalize(dst_gray,transform2,255,0,CV_MINMAX,NULL);
	cvShowImage("win", transform2);
	cvWaitKey(0);
	::cvReleaseImage(&src);
	::cvReleaseImage(&dst_gray);
	::cvReleaseImage(&transform);
	::cvReleaseImage(&transform2);
	::cvDestroyWindow("win");
    return 0;
}

转换前,灰度图像:

将灰度区间缩小为[100,200]得到图片:

再将灰度图片由[100,200]放大至[0,255]:

 经过缩放后的图片有一定的“锐化”效果

抱歉!评论已关闭.