OpenCV简单图像处理 灰度变换

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

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

 

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

处理时作用域是单个像素

有表达式:

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

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

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

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

其变换关系为

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

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

(1)灰度线性变换

1.图像反转

2.线性灰度变换

表达式关系为

3.分段线性灰度变换

表达式关系为

 

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

  
  
import cv def Hist(image,color = cv.RGB(102,204,204)): a = [0]*256 w = image.width h = image.height iHist = cv.CreateImage((256,256),8,3) for i in range(h): for j in range(w): iGray = int(image[i,j]) a[iGray] = a[iGray] + 1 S = max(a) for k in range(256): a[k] = a[k]*255/S x = (k,255) y = (k,255-a[k]) cv.Line(iHist,x,y,color) return iHist def GrayTr(image,array): w = image.width h = image.height size = (w,h) iGrayTr = cv.CreateImage(size,image.depth,1) for i in range(h): for j in range(w): idex = int(image[i,j]) iGrayTr[i,j] = array[idex] return iGrayTr def Invert(): aInvert = [0]*256 for i in range(256): aInvert[i] = 255 - i return aInvert def Linear(): aLinear = [0]*256 for i in range(256): if i<60: aLinear[i] = 30 elif i<200: aLinear[i] = int((220.0-30.0)/(200-60)*(i-60)+30) else: aLinear[i] = 220 return aLinear def SubLinear(): aSubLinear = [0]*256 for i in range(256): if i<60: aSubLinear[i] = int(30.0/60*i) elif i<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) return aSubLinear 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

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

编写程序:

  
  
import cv def GrayTr(image,array): w = image.width h = image.height size = (w,h) iGrayTr = cv.CreateImage(size,image.depth,1) for i in range(h): for j in range(w): idex = int(image[i,j]) iGrayTr[i,j] = array[idex] return iGrayTr def Window(): aWindow = [0]*256 for i in range(60,121): aWindow[i] = int(255.0/(120-60)*(i-60)) return aWindow def Slice(): aSlice = [0]*256 for i in range(256): if i>59 and i<121: aSlice[i] = 200 else: aSlice[i] = 30 return aSlice 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)灰度非线性变换

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

重点是生成对应的映射对

程序如下:

  
  
import cv import math def GrayTr(image,array): w = image.width h = image.height size = (w,h) iGrayTr = cv.CreateImage(size,image.depth,1) for i in range(h): for j in range(w): idex = int(image[i,j]) iGrayTr[i,j] = array[idex] return iGrayTr def Log(): aLog = [0]*256 for i in range(1,256): aLog[i] = int(32*math.log(i,2)) return aLog def Exp(): aExp = [0]*256 NUM = 1.01 k = math.pow(NUM,255) for i in range(1,256): aExp[i] = int(255*math.pow(NUM,i)/k) return aExp 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)
效果如下

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值