定义:
对图像中的每个像素进行灰度变换运算。
输出图象每个象素点的灰度值仅由输入图像相同位置象素点的灰度值决定。
设输入图像和输出图像在 ( x , y ) (x,y) (x,y)处的灰度值分别是 r r r 和 s s s,则点运算可表示为 s = T ( r ) s = T(r) s=T(r), T T T 表示输入图像与输出图像像素的灰度映射关系。
运算的用途:实现对比度增强等。
图像的点运算包括:
非线性变换例子:
#1、导入包
import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
#2、读入图片
gray_img = cv2.imread('spine.tif',0)
cv2.imshow('gray_img',gray_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#3、构造跟原图同样大小的零值图,用于保存分段线性变换结果
piecewise_linear_img = np.zeros((gray_img.shape[0],gray_img.shape[1]),np.uint8)
#4、设置分段线性函数参数
r1,s1 = 40,100
r2,s2 = 200,250
k1 = s1/r1
k2 = (s2-s1)/(r2-r1)
k3 = (255-s2)/(255-r2)
#5、便利图像每个像素,按公式进行变换
for i in range(gray_img.shape[0]):
for j in range(gray_img.shape[1]):
if gray_img[i,j] <= r1:
piecewise_linear_img[i,j] = k1*gray_img[i,j]
elif r1 <= gray_img[i,j] <= r2:
piecewise_linear_img[i,j] = k2*(gray_img[i,j]-r1) + s1
else:
piecewise_linear_img[i,j] = k3*(gray_img[i,j]-r2) + s2
#6、构造跟原图同样大小的零值图,用于保存伽马变换的结果
gamma_img = np.zeros((gray_img.shape[0],gray_img.shape[1],1),dtype=np.float32)
#7、遍历图像每个像素值,按公式进行变换
for i in range(gray_img.shape[0]):
for j in range(gray_img.shape[1]):
gamma_img[i,j] = math.pow(gray_img[i,j],0.5)
cv2.normalize(gamma_img,gamma_img,0,255,cv2.NORM_MINMAX)#将伽马变换后的图像像素值统一到0-255
cv2.convertScaleAbs(gamma_img)#将图片转换为uint8类型
#显示变换结果,进行效果对比
plt.subplot(321),plt.imshow(gray_img,'gray'),plt.title('srcImg')#plt.subplt(321)指一个三行两列的图从左到右从上到下的第一个位置
plt.subplot(322),plt.hist(gray_img.ravel(),256,[0,256]),plt.title('Histogram'),plt.xlim([0,256]) #plt.hist直方图,ravel()方法将矩阵拉成一维数组
plt.subplot(323),plt.imshow(piecewise_linear_img,'gray'),plt.title('piecewise_linear')
plt.subplot(324),plt.hist(piecewise_linear_img.ravel(),256,[0,256]),plt.title('Histogram'),plt.xlim([0,256])
plt.subplot(325),plt.imshow(gamma_img,'gray'),plt.title('gamma_img')
plt.subplot(326),plt.hist(gamma_img.ravel(),256,[0,256]),plt.title('Histogram'),plt.xlim([0,256])
plt.tight_layout()
输出输入的灰度值成线性函数关系: s = f ( r ) = a r + b s =f(r)=ar+b s=f(r)=ar+b
import cv2 as cv
# 线性变换
def linear(img,a,b):
"""
s =f(r)=ar+b
"""
r = np.copy(img)
s = a*r+b
return s
if __name__=="__main__":
img = cv.imread("3.png")
img = cv.cvtColor(img,cv.COLOR_RGB2GRAY)
# 调节 a,b值观察图像变化
a = 1
b = 255
re_img = linear(img,a,b)
cv.imshow('img',img)
cv.imshow('re_img,a={},b={}'.format(a,b),re_img)
cv.waitKey(0)
cv.destroyAllWindows()
灰度的线性变换不利于突出感兴趣区域,且容易出现饱和、截止等情况。
灰度的线性变换不利于突出感兴趣区域,且容易出现饱和、截止等情况。解决办法是对进行非线性变换。
灰度对数变换(可增强暗部细节): s = c l o g ( 1 + r ) c 为常数,建议值 c = 255 / l o g ( 256 ) s = clog(1+r)\ c为常数,建议值c = 255/log(256) s=clog(1+r) c为常数,建议值c=255/log(256)
灰度反对数变换(可增强亮部细节): s = e x p ( r / c ) − 1 s = exp(r/c) - 1 s=exp(r/c)−1
伽玛变换又称为 指数变换 或 幂次变换,是另一种常用的灰度非线性变换。 s = c r γ , c ≥ 0 , γ ≥ 0 ; 实际使用公式: s = 255 × ( r 255 + e p s ) γ s = cr^\gamma ,c\geq0,\gamma\geq0;\ 实际使用公式:s = 255\times(\frac{r}{255+eps})^\gamma s=crγ,c≥0,γ≥0; 实际使用公式:s=255×(255+epsr)γ
e p s eps eps 为补偿系数(一般为0), γ \gamma γ 为伽马系数
当 γ < 1 \gamma<1 γ<1 时,低亮度区域对比度增强
当 γ > 1 \gamma>1 γ>1 时, 高亮度区域对比度增强
当 γ = 1 \gamma=1 γ=1时,该灰度变换是线性的,此时通过线性方式改变原图像。
# 非线性变化:γ变换
def gamma(img,gamma):
"""
s = c * r^gamma
"""
r = np.copy(img)
s = np.power(r/255,gamma)
return s
在实际应用中,为了突出图像中感兴趣的研究对象,常常要求增强某一灰度范围的对比度,或对不同范围的灰度值进行不同的处理,即分段线性拉伸。分段线性拉伸是仅将某一范围的灰度值进行拉伸,而其余范围的灰度值实际上被压缩了。
# 非线性变化:对比拉伸
def constr(img):
"""
s = 0.2*r r<90
s = 3*r 90
r = np.copy(img)
row,col = r.shape
for i in range(row):
for j in range(col):
if r[i][j] < 90:
r[i][j] *=0.2
if r[i][j] > 90 and r[i][j] < 160:
r[i][j] *= 3
if r[i][j] > 160:
r[i][j] *= 0.8
return r
S 形灰度变换曲线,降低较亮和较暗部分的对比度,加强中间灰度级物体对比度: s = 255 2 1 + 1 s i n ( a π 2 ) s i n [ a π ( r 255 − 1 2 ) ] s = \frac{255}{2}{1+\frac{1}{sin(a\frac{\pi}{2})}sin[a\pi(\frac{r}{255}-\frac{1}{2})]} s=22551+sin(a2π)1sin[aπ(255r−21)] S 形灰度变换曲线,加强较亮和较暗部分的对比度,降低灰度级中间物体对比度: s = 255 2 1 + 1 t a n ( a π 2 ) t a n [ a π ( r 255 − 1 2 ) ] s = \frac{255}{2}{1+\frac{1}{tan(a\frac{\pi}{2})}tan[a\pi(\frac{r}{255}-\frac{1}{2})]} s=22551+tan(a2π)1tan[aπ(255r−21)]
阈值变换可以将灰度图像转换成黑白二值图像,用户指定一阈值T,灰度低于T置0,高于T置255。 s = { 0 , r < T 255 , r ≥ T s = \begin{cases} 0,& r
# 非线性变化:阈值变换
def threshold(img,T):
r = np.copy(img)
r[r>T] = 255
r[r<T] = 0
return r