依据作用域的不同,图像增强分为空域内处理频域内处理

  • 空域内处理是直接对图像进行处理,主要有灰度变换方法直方图方法等。通过调节灰度图像的明暗对比度,使得图像变得更加清晰。直方图均衡化、直方图规定化、线性滤波、非线性滤波等。
  • 频域内处理是在图像的某个变换域内,对图像的变换系数进行运算,然后通过逆变换获得图像增强效果。通过傅里叶变换将图像从空间域变换到频域,在频域进行滤波,然后再通过傅里叶反变换到空间域。频域滤波主要包括:低频滤波、高频滤波、带阻滤波器、同态滤波等。
  • 新的图像增强方法:模糊技术、小波变换等

环境:python3.6、Pycharm、Opencv、matplotlib

测试用图像(密码1234)百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固,支持教育网加速,支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.baidu.com/s/1uFdLfs-Jml6nZokkPdnuug

1.        图像读取及显示: 

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import cv2

#利用CV2读取文件,第一个变量是文件名,第二个变量表示读取文件的形式
image_0 = cv2.imread('couple.tiff',cv2.IMREAD_GRAYSCALE)    

plt.subplot(121)
plt.imshow(image_0)

plt.subplot(122)
#后面的参数是为了显示灰度图像,官网有介绍
plt.imshow(image_0,vmin=0,vmax=255,cmap='gray')             

plt.show()

2.         空域内增强

2.1        灰度变换增强

灰度变换增强是在空间域内对图像进行增强的一种简单而有效的方法,不改变原图中像素的位置,只改变像素的灰度值,并逐点进行。依据变换方式,分为线性变换、分段线性和非线性。

进行灰度变换,首先要获取图像的直方图。

matplotlib直方图函数hist

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import cv2

#利用CV2读取文件,第一个变量是文件名,第二个变量表示读取文件的形式
image_0 = cv2.imread('couple.tiff',cv2.IMREAD_GRAYSCALE)

plt.subplot(121)
#后面的参数是为了显示灰度图像,官网有介绍
plt.imshow(image_0,vmin=0,vmax=255,cmap='gray')

#转化为矩阵并拉平
img_np = np.array(image_0).flatten()
plt.subplot(122)
plt.hist(x=img_np,bins=255)

plt.show()

代码2:统计各个灰度值的像素数来画直方图

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import cv2

#利用CV2读取文件,第一个变量是文件名,第二个变量表示读取文件的形式
image_0 = cv2.imread('couple.tiff',cv2.IMREAD_GRAYSCALE)

plt.subplot(121)
#后面的参数是为了显示灰度图像,官网有介绍
plt.imshow(image_0,vmin=0,vmax=255,cmap='gray')

img_np = np.array(image_0)  #转化为矩阵
width,height = img_np.shape #获取宽与高
N = np.zeros(shape=(1,256),dtype='float')   #构造零矩阵,用以统计像素数

#遍历各个灰度值统计个数
for i in range(0,width):
    for j in range(0,height):
        k = img_np[i,j]
        N[0][k] = N[0][k] + 1

N = N.flatten() #扁平化

plt.subplot(122)
plt.bar([i for i in range(0,256)],height=N,width=1)

plt.show()

2.1.1         线性变换:

由于该灰度图的直方图显示其灰度值在0~255之间均有分布,因此更换图像为lena.tiff

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import cv2

#利用CV2读取文件,第一个变量是文件名,第二个变量表示读取文件的形式
image_0 = cv2.imread('lena.tiff',cv2.IMREAD_GRAYSCALE)

plt.subplot(221)
#后面的参数是为了显示灰度图像,官网有介绍
plt.imshow(image_0,vmin=0,vmax=255,cmap='gray')

img_np = np.array(image_0)  #转化为矩阵
width,height = img_np.shape #获取宽与高
N = np.zeros(shape=(1,256),dtype='float')   #构造零矩阵,用以统计像素数

#遍历各个灰度值统计个数
for i in range(0,width):
    for j in range(0,height):
        k = img_np[i,j]
        N[0][k] = N[0][k] + 1

N = N.flatten() #扁平化

plt.subplot(222)
plt.bar([i for i in range(0,256)],height=N,width=1)

#线性变化
plt.subplot(223)
J = img_np.astype('float')
J = 0 + (J-42) * (255-0)/(232-42)   #利用公式转换
#像素值小于0或大于255的分别赋值为0和255
for i in range(0,width):
    for j in range(0,height):
        if J[i,j] < 0 :
            J[i,j] = 0
        elif J[i,j] > 255:
            J[i,j] = 255
image_1 = J.astype('uint8')
plt.imshow(image_1,vmin=0,vmax=255,cmap='gray')

plt.subplot(224)
J = J.flatten()
plt.hist(J,bins=255)



plt.show()

上方图片是原图及其直方图,下方图片是修改后的图片及其直方图。原图的直方图显示其灰度值在42~232之间,利用线性变换将灰度值均匀分布在0~255之间。图像变得更加清晰。

2.1.2         分段线性变化

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import cv2

# 利用CV2读取文件,第一个变量是文件名,第二个变量表示读取文件的形式
image_0 = cv2.imread('lena.tiff', cv2.IMREAD_GRAYSCALE)

plt.subplot(321)
# 后面的参数是为了显示灰度图像,官网有介绍
plt.imshow(image_0, vmin=0, vmax=255, cmap='gray')

img_np = np.array(image_0)  # 转化为矩阵
width, height = img_np.shape  # 获取宽与高
N = np.zeros(shape=(1, 256), dtype='float')  # 构造零矩阵,用以统计像素数

# 遍历各个灰度值统计个数
for i in range(0, width):
    for j in range(0, height):
        k = img_np[i, j]
        N[0][k] = N[0][k] + 1

N = N.flatten()  # 扁平化

plt.subplot(322)
plt.bar([i for i in range(0, 256)], height=N, width=1)

# 灰度变换-线性变化
plt.subplot(323)
J = img_np.astype('float')
J = 0 + (J - 42) * (255 - 0) / (232 - 42)  # 利用公式转换
# 像素值小于0或大于255的分别赋值为0和255
for i in range(0, width):
    for j in range(0, height):
        if J[i, j] < 0:
            J[i, j] = 0
        elif J[i, j] > 255:
            J[i, j] = 255
image_1 = J.astype('uint8')
plt.imshow(image_1, vmin=0, vmax=255, cmap='gray')

plt.subplot(324)
J = J.flatten()
plt.hist(J, bins=255)

# 灰度变换-分段线性变换
Q = img_np.astype('float')
for i in range(0, width):
    for j in range(0, height):
        if 0 <= Q[i, j] < 100:
            Q[i, j] = 0 + Q[i, j] * (50 / 100)
        elif 100 <= Q[i, j] < 200:
            Q[i, j] = 50 + ( Q[i, j] - 100 ) * (200 - 50) / (200 - 100)
        elif 200 <= Q[i,j] <255:
            Q[i,j] = 200 + ( Q[i,j] - 200 )* (255 - 200) / (255 - 200)

for i in range(0, width):
    for j in range(0, height):
        if Q[i,j] <= 0 :
            Q[i,j] = 0
        elif Q[i,j] >= 255:
            Q[i,j] = 255

image_2 = Q.astype('uint8')
plt.subplot(325)
plt.imshow(image_2,vmin=0,vmax=255,cmap='gray')
plt.subplot(326)
plt.hist(Q.flatten(),bins=255)

plt.show()

变换显示在最下方的图片中,对于0~100的灰度值进行压缩,对100~200的灰度值进行变化。

2.1.3         非线性变换

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import cv2
import math

# 利用CV2读取文件,第一个变量是文件名,第二个变量表示读取文件的形式
image_0 = cv2.imread('lena.tiff', cv2.IMREAD_GRAYSCALE)

plt.subplot(221)
# 后面的参数是为了显示灰度图像,官网有介绍
plt.imshow(image_0, vmin=0, vmax=255, cmap='gray')

img_np = np.array(image_0)  # 转化为矩阵
width, height = img_np.shape  # 获取宽与高
N = np.zeros(shape=(1, 256), dtype='float')  # 构造零矩阵,用以统计像素数

# 遍历各个灰度值统计个数
for i in range(0, width):
    for j in range(0, height):
        k = img_np[i, j]
        N[0][k] = N[0][k] + 1

N = N.flatten()  # 扁平化

plt.subplot(222)
plt.bar([i for i in range(0, 256)], height=N, width=1)

# 灰度变换-非线性变化(对数变换)
plt.subplot(223)
J = img_np.astype('float')
for i in range(0, width):
    for j in range(0, height):
        J[i,j] = 0 + math.log(J[i,j] + 1)/(0.06 * math.log(2))

image_1 = J.astype('uint8')
plt.imshow(image_1,vmin=0,vmax=255,cmap='gray')

plt.subplot(224)
J = J.flatten()
plt.hist(J,bins=255)


plt.show()

只尝试了对数变换的效果,指数变换代码也很容易编写。

2.2        直方图增强

2.2.1        直方图均衡化

直方图均衡化是一种利用灰度变换自动调节图像对比度质量的方法,基本思想是通过灰度级的概率密度函数求出灰度变换函数,它是一种以累计分布函数变换法为基础的直方图修正法。

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐