2016-11-28 00:47:37 qq_24894159 阅读数 5084

滤波这一概念可以结合数字信号处理这一领域中的滤波。而在数字图像处理中滤波可以分为空间域滤波和频率域滤波。这篇博文主要来学习下空间域滤波。

空间域滤波机理

  *空间滤波器由一个邻域(典型的是一个较小的矩形)构成,对该邻域所包围的像素按照一定的操作计算出目标像素的值,这一过程就是空间滤波器的工作机理*

例如:
假设有一个这样的3*3的滤波器(每个元素代表权值w)

T=111111111

用T对下图进行滤波,其覆盖的第一个方块为红色的方框,对应元素相乘后结果求和,然后再求平均值(除以9),得出圆圈的像素。(这就是后边实现的均值滤波器)

空间相关与卷积

这里只是简单提一下这两个概念。

相关:滤波器位移过图像并计算每个位置乘积之后的处理
卷积:和相关相似,只是滤波器要先旋转180°

线性滤波器和非线性滤波器

概念:线性滤波器是指对像素进行线性操作;否则则称为非线性滤波器。

你可能问,什么是线性操作呢?线性操作简单来说就是满足下面式子的操作:

f(x+y)=f(x)+f(y)f(ax)=af(x)

均值滤波器就是一个典型的线性滤波器。
中值滤波器是一个典型的非线性滤波器。

平滑线性滤波器

平滑线性滤波器的主要作用是模糊处理和降低噪声。例如在提取图像的最大目标时,需要先进行模糊处理来降低噪声。然后增强某一阈值之上的灰度,来突出”亮”的部分。

T1=111111111T2=121242121

以上T1为简单的均值滤波器,T2为带权值的均值滤波器。后者更为重要些。
说了这么多,我们来实现一个简单的均值滤波器。

function [Image] = fliter (img, type)
%初始化滤波器模板
f = ones(3,3);
[x,y] = size(img);
Image = zeros(x,y);
%注意由于我们是3*3的滤波器,对第一个像素img(1,1)滤波时,滤波器会有
%一部分在图像外部,所以我们要初始一个带着一圈0的壳的图像
temp = zeros(x+2,y+2);
%把中间的部分赋值原来的数值
temp(2:x+1,2:y+1) = img;
for i=2:x+1
  for j=2:y+1
    %计算均值
    Image(i-1,j-1) = mean(mean(f.*temp(i-1:i+1,j-1:j+1))');
  end;
end;
endfunction

统计排序(非线性)滤波器

由名字可知,这是基于数理统计的一种滤波器,采用的是非线性的计算。

中值滤波器

他是将邻域中的灰度值排序,然后取中值作为替换中心元素的灰度值。例如:3*3的中值滤波器,取排序后的第5个元素。

实现代码:

function [Image] = medianFliter (img)
[x,y] = size(img);
Image = zeros(x,y);
temp = zeros(x+2,y+2);
%同上面均值滤波的作用
temp(2:x+1,2:y+1) = img;
for i=1:x
  for j=1:y
    t = temp(i:i+2,j:j+2);
    %median为求中值函数,需要将t转化为一个列向量
    Image(i,j) = median(t(:));
  end;
end;

endfunction

在原图中增加了椒盐噪声,可以看到,中值滤波后椒盐噪声基本被去除。
从左到右依次为原图、均值滤波后、中值滤波后

锐化空间滤波器

锐化:即增强图像中的边缘部分。边缘部分一般为灰度激变的部分。有photoshop的可以去试一下带的锐化功能。

准备知识

我们学习过高等数学中的积分和微分,别方,我尽量解释的容易理解一点同时也尽量准确点(说实话,让我正确的解释积分和微分我估计也解释不清楚)。

积分我们可以简单的理解为求和

一次函数积分不就是就其与x轴所围面积的和吗?虽然有正负。那我们的均值滤波器可以思考下其实也是积分的原理,是离散的积分,计算出他们的乘积和,只不过最后又平均了一下。

微分我们可以简单的理解为求导

一阶微分(一阶求导):我们高中就知道函数的一阶导数显示了函数斜率。斜率决定了函数变化的快慢。
二阶微分(二阶求(偏)导):二阶求导就是在一阶的基础上继续求导。一阶导数也是一个函数的话,二阶求导可以理解为斜率变化的快慢。

通过下面这个图可以看出对于灰度激变图像,一阶和二阶的表现:
这里写图片描述
可以看出二阶对激变的时刻更加敏感。

知道来这些怎么对离散的灰度微分(求导)呢?

一阶微分:我们定义为两个像素之间的差值

fx=f(x+1)f(x)

二阶微分

2f2x=f(x+1)xf(x)x=f(x+1)+f(x1)2f(x)

下面我们就正式开始进行图像锐化

这里我们采用二阶微分进行锐化先

这里有一个概念各向同性滤波器。它就是旋转图片后滤波结果仍然相同,与图像的突变方向无关。最为简单的各向同性微分算子是拉普拉斯算子。一个二维图像函数f(x,y)的拉普拉斯算子定义为:

2f=2fx2+2fy2=f(x+1,y)+f(x1,y)2f(x,y)+f(x,y+1)+f(x,y1)2f(x,y)

我们可以定义为这样的模板
T3=010141010

T4=111181111

T5=010141010

T6=111181111

这样计算出一个图像的边界图像Temp,与原图像相加(相减),得到锐化的结果。(注意:边界图像中会有些部分小于0,我们要通过下面操作把他们置为0)

temp(temp<0) = 0;

最终表达式为:

g(x,y)=f(x,y)+c[2f(x,y)]

当采用上边T3T4模板时,c为-1,采用T5T6时,c=1;其中T4T6是包含对角变化

梯度的算子模板。
实现代码:

function [Image] = sharpen (img)
[x,y] = size(img);
Image = zeros(x,y);
temp = zeros(x+2,y+2);
temp(2:x+1,2:y+1) = img;
%这里我没有采用算子模板进行计算
for i=1:x
for j=1:y
   t = temp(i,j+1)+temp(i+2,j+1)+temp(i+1,j)+temp(i+1,j+2)-4*temp(i+1,j+1);
   Image(i,j) = t;
 end;
end;
Image(Image<0)=0;
figure;
imshow(uint8(Image));
Image = img.-Image;
endfunction

这里写图片描述
下面这张 c 错选为+号
这里写图片描述
这里写图片描述

非锐化掩蔽和高提升滤波

步骤:
1、模糊化原图。
2、原图减去模糊图像(差值称为模板)。
3、将模板加到原图。
f¯(x,y)表示模糊图像,

非锐化掩蔽公式

gmask(x,y)=f(x,y)f¯(x,y)

然后,在原图加上模板的权重部分:
g(x,y)=f(x,y)+kgmask(x,y)

当k= 1时,称为非锐化掩蔽,
当k> 1时,称为高提升滤波。

使用一阶微分对(非线性)图像锐化——梯度

这里可以参照这位博主的博文部分,
http://blog.csdn.net/ubunfans/article/details/42214925

Good Night!

2020-03-31 10:33:00 weixin_46563862 阅读数 11

chapter2 空间域图像增强(点增强)

1.图像增强的基本概念

在不考虑图像降质的情况下,通过经验和试探的方法,把图像感兴趣的部分进行选择性突出,而把不在意的部分进行压制,从而得到我们想要的信息。

  • 目的: 改善视觉效果,便于人眼或者机器进行分析和辨别
  • 分类: 空间域法: 灰度变换 , 直方图均匀化 ,伪彩色处理(没学)等
        频域法:高,低通滤波等

2.空域增强

1.什么是空域增强

  • 在空间域中,通过线性非线性变换来增强构成图像的像素.方法是直接对这些像素进行操作的过程。
  • 公式:g(x,y)=T[f(x,y)] ,表示为通过对像素f(x,y)进行变换,从而得到我们想要的效果像素g(x,y),因此最重要的就是能够知道这个变化函数T是什么
  • 常见的T包括:对数,幂函数,进行图像反转(最大灰度-像素)

2.空域增强的方式

  • 点处理:作用于单个像素的处理方法
  • 模板处理 : 作用于像素邻域的处理方法。

3常见T的应用类型

1.反转变换

适用于增强嵌入于图像暗色区域的白色或灰色细节,从而突出一些暗色区域的特征

2.对数变换

作用:将图像的低灰度值部分扩展,显示出低灰度部分更多的细节,将其高灰度值部分压缩,减少高灰度值部分的细节,从而达到强调图像低灰度部分的目的
公式:s=clogv+1(r*v+1) , 其中c是常数,v+1是底数,r在[0,1],加一的目的是使得log函数左移动避免小于0。

函数图像如下:

可以看到当V=200时,当r=0.4,s>0.8,可以知道其使得区域增强(变亮),但是对于亮的区域变暗了。

3.幂次变换

作用:幂次变换通过幂次曲线中的γ值把输入的窄带值映射到宽带输出值。
公式:S = cr^(x)其中c是常数。r是输入灰度

函数图像如下:

可以通过图像看出其特点

4.灰度直方图介绍

1.什么是直方图

直方图是图像灰度级与出现该灰度概率之间的关系的图形,x轴是灰度级,y轴是概率(图像中该灰度级出现的个数)。因此灰度图是反映一幅图像中的灰度级与出现这种灰度的概率之间的关系的图形,只反映概率,不反映像素位置关系,因此相同的直方图,可能图像不一样。

2.直方图的计算定义

5.直方图均匀化

直方图均衡化是一种增强图像对比度的方法,其主要思想是将一副图像的直方图分布变成近似均匀分布,从而增强图像的对比度.(在通信原理我们知道让事件出现的概率一样的时候,总信息量最大,熵也是是最大的,即对比度最大),使用对于图像而谈,图像如果通过T函数,其直方图能够变换成均匀的,那么其对比度就是最大的)
其中T®要满足:

  • 在0≤r≤1区间内,T®单值单调增加;
  • 对于0≤r≤1,有0≤T®≤1;

简单的推导:
可以理解 T 的作用是将输入图像里面像素点灰度为a的全部变为b, 0ap(r)dr\int_0^a p(r) {\rm d}r = 0bp(s)ds\int_0^b p(s) {\rm d}s

p(s)ds的意义是区间(s,s+ds)上的概率
p®dr的意义是区间(r,r+dr)上的概率

显然两者是相等的,有p(r)dr=p(s)ds,那么有ds/dr =dT(r)/dr = p(r)/p(s),如果p(s)是均匀分布那么p(s)=1/255,那么有255p(r) =dT(r)/d(r),则T®=255*0rp(x)dx\int_0^r p(x) {\rm d}x,如果是离散,就用离散的形式表示。这就是均匀化的基本推导


3.作业

1.编写代码,实现Log变换和实现gamma变换

# include<iostream>
# include<opencv2/opencv.hpp>
# include<math.h>

using namespace std;
using namespace cv;

int main()
{
	Mat image = imread("D:/1.jpg", 1);

	if (image.empty())
	{
		cout << "未找到文件,请检查文件目录" << endl;
		return -1;
	};

	Mat originalgray_image;
	cvtColor(image, originalgray_image, COLOR_BGR2GRAY); //灰度图
	imshow("gray_image", originalgray_image); //显示原图的灰度图

	Mat gray_image;
	gray_image = originalgray_image;

	int height = gray_image.rows;
	int width = gray_image.cols;
	float fVal = 0.0;
	float fgammar = 0.2;

	for ( int row = 0; row < height; ++row)
	{
		for (int col = 0; col < width; ++col)
		{
			//实现log运算
			fVal = (gray_image.at<uchar>(row, col) + 1) / 255.0; //归一化
			fVal = log10(fVal*(10-1) + 1);
			if(fVal > 1)
			{
				fVal = 1;
			}
			fVal = fVal * 255;
			gray_image.at<uchar>(row, col) =fVal;
			

			/*实现grammer运算
			fVal = (gray_image.at<uchar>(row, col) + 1) / 255.0; //归一化
			fVal = pow(fVal,fgammar);
			if (fVal > 1)
			{
				fVal = 1;
			}
			fVal = fVal * 255;
			gray_image.at<uchar>(row, col) = fVal;
		     */	
		}
		
	}
	imshow("log_image", gray_image); //显示log变换的原图的灰度图
	waitKey(0);

	return 0;
}

2.使用函数实现直方图均匀化

// 1. 使用函数实现直方图均匀化
// 2. 函数: void equalizeHist(InputArray src,OutputArray dst)
# include<opencv2/opencv.hpp>
# include<ostream>

using namespace std;
using namespace cv;

int main()
{
	
	Mat image = imread("D:/Vistual studio editor/Code/数字图像处理/2.图像增强/直方图/直方图/image.jpg", 0);
	if (image.empty())
	{
		cout << "文件不存在" << endl;
		return 1;
	}
	//namedWindow("image",WINDOW_AUTOSIZE);
	imshow("image", image);
	waitKey(0);

	Mat mEnhanced;
	equalizeHist(image, mEnhanced);
	imshow("menhanced", mEnhanced);
	waitKey(0);
	return 0;
}

3.实现直方图计算

# include<opencv2/opencv.hpp>
# include<ostream>

using namespace std;
using namespace cv;

int main()
{

	Mat image = imread("D:/Vistual studio editor/Code/数字图像处理/2.图像增强/直方图/直方图/image.jpg", 0);
	if (image.empty())
	{
		cout << "文件不存在" << endl;
		return 1;
	}
	//namedWindow("image",WINDOW_AUTOSIZE);
	imshow("image", image);

	int hist_number[256] = { 0 };
	for (int row = 0 ; row < image.rows; ++row)
	{
		for (int col = 0; col < image.cols; ++col)
		{
			int image_number = image.at<uchar>(row, col);
			hist_number[image_number] += 1;
		}
	}

	for (int number = 0; number < 256; ++number)
	{
		cout << number << " : " << hist_number[number] << endl;
	}

	waitKey(0);
	return 0;
}

4.函数进行直方图计算,和绘制

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

int main()
{

	//加载图像
	Mat image;
	image = imread("D:/图片/壁纸/动漫/1.jpg", 0);//生成单通道,灰度图

	//判断是否为空
	if (image.empty())
	{
		cerr << "" << endl;
		return -1;
	}
	imshow("src", image);
	// 2. 函数 :CV_EXPORTS void calcHist( const Mat* images,int nimages,const int* channels,InputArray mask,OutputArray hist,int dims,const int* histSize,const float** ranges,bool uniform = true,bool accumulate = false );
	int image_number = 1;
	int channels[] = { 0 };
	Mat histA;
	int dims = 1;
	int histsize[] = { 256 };
	float midrange[] = { 0,255 };
	const float* ranges[] = { midrange };

	calcHist(&image, image_number, channels, Mat(), histA, dims, histsize, ranges);

	double  min_number;
	double  mix_number;
	minMaxLoc(histA, &min_number, &mix_number, 0, 0);
	int hist_number = histA.rows; //255
	Mat background(hist_number, hist_number, CV_8UC3, Scalar(255, 255, 255)); //白色
	Scalar lines_color(172, 172, 150);
    int hpt = static_cast<int>(0.9 * hist_number);
	for (int h = 0; h < hist_number; h++)
	{
		float bin = histA.at<float>(h);
		cout << h << ":" << bin << endl;
		int intensity = static_cast<int>(bin*hist_number / mix_number);
		line(background, Point(h, hist_number), Point(h, hist_number - intensity), lines_color);
	}
	imshow("ddd", background);
	waitKey(0);
	return 0;
}

4.参考资料

  1. 直方图均衡化的数学原理 :
    https://blog.csdn.net/superjunenaruto/article/details/52431941
  2. line()函数来对直线的绘制 :
    https://blog.csdn.net/hk121/article/details/81085213
2014-07-11 15:34:21 mghhz816210 阅读数 22222

空间域增强的第部分:图像反转对数变换幂次变换分段线性变换


(s:现点值,r: 原点值)

图像反转:

    这个无需多说,就是把黑变白,白变黑,拿八位灰度图像来说                                

    表达式:s=255-r

    作用:看清暗色图像中白色和灰色的细节。


对数变换:

    此变换使一窄带低灰度输入图像值映射为一宽带输出值。相对的是输入灰度的高调整值。可以利用这种变换来扩展被压缩的高值图像中的暗像素。相对的是反对数变换的调整值。(这段转自《数字图像处理》(第二版)(冈萨雷斯))

                附:说的太透彻了,找不到比这更好的语言了 

      表达式:s=c log(1+r);

     变换曲线:

     应用:用于对数值范围过大的数据进行调整显示,如傅立叶变换后的图像数据(0-1.5e6).


幂次变换:

    又叫伽玛校正,和对数变换的原理差不多,不多说了,只是参数多了一个,可变宽带的输入像素值范围可选了,把低值带拉伸还是把高值拉伸要看伽马的设定了。

    表达式:伽马变换(这个是图片格式,粘的太丑,不过不影响什么)

变换曲线:

                 一个是伽马等于4,一个是伽马等于0.2;一个拉伸高像素值的范围,一个拉伸低像素值的范围。哪部分的斜率越大,哪部分的拉伸比例就越大。


分段线性变换:

分为:对比拉伸灰度切割位图切割

图:

 位图切割就是比如8位的图像,我把像素点的每一位拿出来做个位平面,然后就有8个位平面了。


以上这几个处理方法都是将固定范围内的像素值的显示范围放大或缩小,让图像更符合人为意愿。

2010-12-29 14:14:00 weixin_30747253 阅读数 48

这真是一件悲剧的事,早上,我花了很长时间写了这篇文章

当我快要完成时,然后电脑就蓝屏了,重启后,一切都成了浮云

好啦,没耐心再写那么多了,尽量简单吧

 

在图像识别中,需要有边缘鲜明的图像,即图像锐化。

图象锐化的目的是为了突出图像的边缘信息,加强图像的轮廓特征,以便于人眼的观察和机器的识别。

在空间域进行图象锐化主要有以下方法

  1. 梯度算子
  2. 其他锐化算子
  3. 拉普拉斯算子

(1)梯度空间算子

图像的边缘最直观的表现就是边缘两侧的灰度值相差比较大,在微积分中我们学过梯度的概念

梯度是一个列向量,可表示为:

而某点处梯度的模很好的反应了该点两侧的变化大小

所以,梯度值很大的点也就代表了图像的边缘

而在实际计算中,为了降低运算量,一般用一下两种方法来代替模运算

由于数字图像处理中处理的是数字离散信号

所以,我们用差分来等同于连续信号中的微分运算

典型的梯度运算有

而另一种称为Roberts梯度的差分运算可由下来表示

 

我们来编写程序来实现上面计算

import cv

def Sharp(image,flag1=0,flag2=0):
w
= image.width
h
= image.height
size
= (w,h)
iSharp
= cv.CreateImage(size,8,1)
for i in range(h-1):
for j in range(w-1):
if flag2 == 0:
x
= abs(image[i,j+1]-image[i,j])
y
= abs(image[i+1,j]-image[i,j])
else:
x
= abs(image[i+1,j+1]-image[i,j])
y
= abs(image[i+1,j]-image[i,j+1])
if flag1 == 0:
iSharp[i,j]
= max(x,y)
else:
iSharp[i,j]
= x+y
return iSharp



image
= cv.LoadImage('lena.jpg',0)
iMaxSharp
= Sharp(image)
iAddSharp
= Sharp(image,1)
iRMaxSharp
= Sharp(image,0,1)
iRAddSharp
= Sharp(image,1,1)
cv.ShowImage(
'iMaxSharp',iMaxSharp)
cv.ShowImage(
'image',image)
cv.ShowImage(
'iAddSharp',iAddSharp)
cv.ShowImage(
'iRAddSharp',iRAddSharp)
cv.ShowImage(
'iRMaxSharp',iRMaxSharp)
cv.WaitKey(0)
我们来看看运行结果

下面是Roberts梯度

可以比较下两种方法的效果

 

(2)其他锐化算子

利用梯度和差分原理可以组成以下锐化算子

1.Sobel算子

2.Prewitt算子

3.Isotropic算子

好啦,我们还是写程序吧

 

import cv

def SuanSharp(image,arrayX,arrayY):
w
= image.width
h
= image.height
size
= (w,h)
iSuanSharp
= cv.CreateImage(size,8,1)
tmpX
= [0]*9
tmpY
= [0]*9
for i in range(1,h-1):
for j in range(1,w-1):
for k in range(3):
for l in range(3):
tmpX[k
*3+l] = image[i-1+k,j-1+l]*arrayX[k*3+l]
tmpX[k
*3+l] = image[i-1+k,j-1+l]*arrayX[k*3+l]
iSuanSharp[i,j]
= sum(tmpX)+sum(tmpY)
return iSuanSharp


image
= cv.LoadImage('lena.jpg',0)
SobelX
= [1,0,-1,2,0,-2,1,0,-1]
SobelY
= [-1,-2,-1,0,0,0,1,2,1]
PrewittX
= [1,0,-1,1,0,-1,1,0,-1]
PrewittY
= [-1,-1,-1,0,0,0,1,1,1]
IsotropicX
= [1,0,-1,1.414,0,-1.414,1,0,-1]
IsotropicY
= [-1,-1.414,-1,0,0,0,1,1.414,1]
iSobelSharp
= SuanSharp(image,SobelX,SobelY)
iPrewittSharp
= SuanSharp(image,PrewittX,PrewittY)
iIsotropicSharp
= SuanSharp(image,IsotropicX,IsotropicY)
cv.ShowImage(
'image',image)
cv.ShowImage(
'iPrewittSharp',iPrewittSharp)
cv.ShowImage(
'iSobelSharp',iSobelSharp)
cv.ShowImage(
'iIsotropicSharp',iIsotropicSharp)
cv.WaitKey(0)

 

看看运行效果吧

 

好吧,这三个图的运算花了好几秒的时间,循环太多了,其实可以用numpy做矩阵运算

我们在这里主要学习图像处理原理,不是学习编程

 

(3)拉普拉斯运算

拉普拉斯运算比较适合于改善因为光线的漫反射而造成的图像模糊,拉普拉斯算子法是常用的边缘增强处理算子

它是各向同性的二阶导数

对于连续二元函数有:

整理后有:

可以得到拉普拉斯算子模板:

看看运行效果

而对于Photoshop这类软件来说,锐化和我这里所说的锐化不同

它是在原图基础上,加强边缘效果

我们只要把模板适当改动就能实现这样的效果

 

还有一种思路,我们在前面讲了图像的平滑,我们用原图减去平滑后的图像

得到的就是锐化边缘了

第四幅图我们对轮廓线做了对数灰度变换,前面讲过的

不过,效果没有前面直接锐化清晰

我们还可以在原图上乘以一个大于1的因子再减去模糊后的图像

得到如下结果

 

好啦,图像空域的锐化处理就讲到这里啦,是不是很简单呢?

转载于:https://www.cnblogs.com/xianglan/archive/2010/12/29/1920490.html

2014-07-13 19:00:52 mghhz816210 阅读数 3158

空间域的直方图处理分两个方法:直方图均衡化直方图规定化。直方图规定化中利用了直方图均衡化。


直方图均衡化:(转自http://blog.csdn.net/honpey/article/details/8770919)

直方图均衡化的作用是图像增强。

有两个问题比较难懂,一是为什么要选用累积分布函数,二是为什么使用累积分布函数处理后像素值会均匀分布。

第一个问题。均衡化过程中,必须要保证两个条件:①像素无论怎么映射,一定要保证原来的大小关系不变,较亮的区域,依旧是较亮的,较暗依旧暗,只是对比度增大,绝对不能明暗颠倒;②如果是八位图像,那么像素映射函数的值域应在0和255之间的,不能越界。综合以上两个条件,累积分布函数是个好的选择,因为累积分布函数是单调增函数(控制大小关系),并且值域是0到1(控制越界问题),所以直方图均衡化中使用的是累积分布函数。

第二个问题。累积分布函数具有一些好的性质,那么如何运用累积分布函数使得直方图均衡化?比较概率分布函数和累积分布函数,前者的二维图像是参差不齐的,后者是单调递增的。直方图均衡化过程中,映射方法是

其中,n是图像中像素的总和,是当前灰度级的像素个数,L是图像中可能的灰度级总数。

来看看通过上述公式怎样实现的拉伸。假设有如下图像:


得图像的统计信息如下图所示,并根据统计信息完成灰度值映射:


映射后的图像如下所示:

以上就是直方图映射均衡化的步骤,当然还有一些基于此的更优算法,比如Photoshop中的方法,在此就不一一列举了,大同小异。

参考:

http://blog.csdn.net/zrongh/article/details/7302816               直方图均衡化原理

http://bbs.ednchina.com/BLOG_ARTICLE_219471.HTM     直方图均衡化


直方图规定化:(转自:http://blog.csdn.net/juyingmin/article/details/5675851)

原理:
       在实际应用中,希望能够有目的地增强某个灰度区间的图像, 即能够人为地修正直方图的形状, 使之与期望的形状相匹配,这就是直方图规定化的基本思想。换句话说,希望可以人为地改变直方图形状,使之成为某个特定的形状,直方图规定化就是针对上述要求提出来的一种增强技术,它可以按照预先设定的某个形状来调整图像的直方图。直方图规定化是在运用均衡化原理的基础上,通过建立原始图像和期望图像之间的关系,选择地控制直方图,使原始图像的直方图变成规定的形状,从而弥补了直方图均衡不具备交互作用的特性。

 

例如:Pr (r)为原图像的灰度密度函数, Pz (z)为希望得到的增强图像的灰度密度函数,二者的直方图如下:

 

直方图规定化增强处理的步骤如下:

  1,其增强原理是先对原始的直方图均衡化:S = T(r)

  2,同时对规定的直方图均衡化:v = G(z)

 3,由于都是均衡化,故令 S = v,则:z = G-1(v) = G-1[T(r)] 

 

组映射:

存在一维离散整数函数I(a),(a=0,1,2……N-1),而且满足0≤I(0) ≤I(1) ≤……≤I(a) ≤……≤I(N-1) ≤M-1。寻找能使 |∑ps(si)-∑pu(uj)| 达到最小的I(a),其中ps(si)的求和区间为[0I(a)]pu(uj)的求和区间仍为[0a]a=0时,将介于0I(0)之间的ps(si)都映射到pu(u0)中;1≤a≤N-1时,将介于I(a-1)+1I(a)之间的ps(si)都映射到pu(uj)中去。

代码:

根据希望达到的直方图数据,对当前图像直方图转换,得到转换的直方图数据。


 

  1. void HistogramSpecification(int* src, int* dst, int* histMap)  
  2. {  
  3.     int x = 0, y = 0, i = 0;  
  4.     int minX = 0;  
  5.     int minValue = 0;  
  6.     int srcMin[256][256];  
  7.     short lastStartY = 0, lastEndY = 0, startY = 0, endY = 0;  
  8.     //计算原始图像到目标图像累积直方图各灰度级的差的绝对值  
  9.     for (y = 0; y < 256; y++)  
  10.     {  
  11.         for (x = 0; x < 256; x++)  
  12.         {  
  13.             srcMin[x][y] = abs(src[y] - dst[x]);  
  14.         }  
  15.     }  
  16.   
  17.     //GML映射  
  18.     for (x = 0; x < 256; x++)  
  19.     {  
  20.         minValue = srcMin[x][0];  
  21.         for (y = 0; y < 256; y++)  
  22.         {  
  23.             if (minValue > srcMin[x][y])  
  24.             {  
  25.                 endY = y;  
  26.                 minValue = srcMin[x][y];  
  27.             }  
  28.         }  
  29.   
  30.         if (startY != lastStartY || endY != lastEndY)  
  31.         {  
  32.             for (i = startY; i <= endY; i++)  
  33.             {  
  34.                 histMap[i] = x;//建立映射关系  
  35.             }  
  36.             lastStartY = startY;  
  37.             lastEndY = endY;  
  38.             startY = lastEndY + 1;  
  39.         }  
  40.     }  
  41. }  


没有更多推荐了,返回首页