python灰度处理_python 简单图像处理(9) 灰度变换

对这个工具,你一定很熟悉吧,Photoshop里有,很多简单的图像处理软件里面也会有

那这个工具到底是什么意思呢,它和我们要讲到的灰度变换有很大的关系

在图像处理中,像图像度变换和直方图均衡都属于点运算范畴。

处理时作用域是单个像素

有表达式:

g(x,y) = T[ f(x,y) ]    T为映射关系

在点运算中,映射关系是关键,它描述了输入灰度级和输出灰度级之间的关系。

灰度变换是图像增强的一种重要手段,用于改善图像的显示效果,属于空域处理方法

最开始我们讲的反转就属于灰度变换的一种

其变换关系为

g(x,y)  = 255 - f(x,y)

我们来讲讲常用的灰度变换

(1)灰度线性变换

1.图像反转

2.线性灰度变换

表达式关系为

3.分段线性灰度变换

表达式关系为

我们来写程序来实现这些功能:

importcvdefHist(image,color=cv.RGB(102,204,204)):

a=[0]*256w=image.width

h=image.height

iHist=cv.CreateImage((256,256),8,3)foriinrange(h):forjinrange(w):

iGray=int(image[i,j])

a[iGray]=a[iGray]+1S=max(a)forkinrange(256):

a[k]=a[k]*255/S

x=(k,255)

y=(k,255-a[k])

cv.Line(iHist,x,y,color)returniHistdefGrayTr(image,array):

w=image.width

h=image.height

size=(w,h)

iGrayTr=cv.CreateImage(size,image.depth,1)foriinrange(h):forjinrange(w):

idex=int(image[i,j])

iGrayTr[i,j]=array[idex]returniGrayTrdefInvert():

aInvert=[0]*256foriinrange(256):

aInvert[i]=255-ireturnaInvertdefLinear():

aLinear=[0]*256foriinrange(256):ifi<60:

aLinear[i]=30elifi<200:

aLinear[i]=int((220.0-30.0)/(200-60)*(i-60)+30)else:

aLinear[i]=220returnaLineardefSubLinear():

aSubLinear=[0]*256foriinrange(256):ifi<60:

aSubLinear[i]=int(30.0/60*i)elifi<200:

aSubLinear[i]=int((220.0-30.0)/(200-60)*(i-60)+30)else:

aSubLinear[i]=int((255.0-220.0)/(255-200)*(i-200)+220)returnaSubLinear

image=cv.LoadImage('lena.jpg',0)

iInvert=GrayTr(image,Invert())

iLinear=GrayTr(image,Linear())

iSubLinear=GrayTr(image,SubLinear())

cv.ShowImage('image',image)

cv.ShowImage('iInvert',iInvert)

cv.ShowImage('iLinear',iLinear)

cv.ShowImage('iSubLinear',iSubLinear)

cv.ShowImage('iHist',Hist(image))

cv.ShowImage('iIHist',Hist(iInvert))

cv.ShowImage('iLHist',Hist(iLinear))

cv.ShowImage('iSubHist',Hist(iSubLinear))

cv.WaitKey(0)

运行效果如下:

我们看到第三幅图的直方图和其他的有很大差别

主要是在我们把原图中灰度值在60以下的点全部映射到灰度值30

使得灰度值为30的点特别多,导致其它的灰度值的点显得很少,相应的画出来也就特别短

但明显的,我们看到没有点映射到30一下和220以上,在灰度值上产生了截断效果

另外我们来看看灰度窗和灰度级分层:

灰度窗是左边映射关系:增强特定灰度值的对比度,其它的全部置0

灰度级分层:把在特定灰度级和其他灰度级的区域分开

编写程序:

importcvdefGrayTr(image,array):

w=image.width

h=image.height

size=(w,h)

iGrayTr=cv.CreateImage(size,image.depth,1)foriinrange(h):forjinrange(w):

idex=int(image[i,j])

iGrayTr[i,j]=array[idex]returniGrayTrdefWindow():

aWindow=[0]*256foriinrange(60,121):

aWindow[i]=int(255.0/(120-60)*(i-60))returnaWindowdefSlice():

aSlice=[0]*256foriinrange(256):ifi>59andi<121:

aSlice[i]=200else:

aSlice[i]=30returnaSlice

image=cv.LoadImage('lena.jpg',0)

iWindow=GrayTr(image,Window())

iSlice=GrayTr(image,Slice())

cv.ShowImage('image',image)

cv.ShowImage('iWindow',iWindow)

cv.ShowImage('iSlice',iSlice)

cv.WaitKey(0)

效果如下:

(2)灰度非线性变换

左边为对数变换,右边为指数变换(当然,上面的图不是很标准)

重点是生成对应的映射对

程序如下:

importcvimportmathdefGrayTr(image,array):

w=image.width

h=image.height

size=(w,h)

iGrayTr=cv.CreateImage(size,image.depth,1)foriinrange(h):forjinrange(w):

idex=int(image[i,j])

iGrayTr[i,j]=array[idex]returniGrayTrdefLog():

aLog=[0]*256foriinrange(1,256):

aLog[i]=int(32*math.log(i,2))returnaLogdefExp():

aExp=[0]*256NUM=1.01k=math.pow(NUM,255)foriinrange(1,256):

aExp[i]=int(255*math.pow(NUM,i)/k)returnaExp

image=cv.LoadImage('lena.jpg',0)

iLog=GrayTr(image,Log())

iExp=GrayTr(image,Exp())

cv.ShowImage('image',image)

cv.ShowImage('iLog',iLog)

cv.ShowImage('iExp',iExp)

cv.WaitKey(0)

效果如下

好啦。灰度变换就讲到这里啦!!

本文链接:https://my.lmcjl.com/post/10087.html

展开阅读全文

4 评论

留下您的评论.