图像增强——python+opncv(直方图和直方图均衡化、使用图像灰度映射实现图像增强、图像空域增强与滤波)

直方图和直方图均衡化

a) 计算图像R,G,B通道的直方图,并利用matplotlib显示出来

import cv2
import numpy as np
from matplotlib import pyplot as plt 

img = cv2.imread('F:/img/island.png')
color = ('r','g','b')

plt.figure(figsize=(7,7))
for i,col in enumerate(color):
    plt.hist(img[:,:,i].ravel(),256,[0,256],color = col);


plt.show()
plt.imshow(img,cmap = 'gray')

b) 计算图像island.png对应灰度图像的直方图和直方累计图,并利用matplotlib显示出来

c) 利cv2.equalizeHist()进行均衡化,并画出均衡化后的直方图和直方累计图

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('F:/img/island.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

hist_img,_ = np.histogram(gray,256)
cdf_img = np.cumsum(hist_img)

plt.figure(figsize=(13,13))
plt.subplot(2,2,1)
plt.plot(range(256),cdf_img,color = 'b')
plt.legend(loc='best')

plt.subplot(2,2,2)
plt.hist(gray.ravel(),256,[0,256],color = 'b');


plt.subplot(2,2,3)
plt.imshow(gray,cmap = 'gray')

plt.show()

使用图像灰度映射实现图像增强

a) 图像的灰度线性变换是通过建立灰度映射来调整原始图像的灰度,从而改善图像的质量,凸显图像的细节,提高图像的对比度。灰度线性变换的计算公式如下所示 g(x)=αf(x)+β

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 10 20:28:47 2020

@author: Administrator
"""

# -*- coding: utf-8 -*-
import cv2  
import numpy as np  
import matplotlib.pyplot as plt

#读取原始图像
img = cv2.imread('F:/img/lena.png')

#图像灰度转换
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#获取图像高度和宽度
height = grayImage.shape[0]
width = grayImage.shape[1]

#创建6幅图像
result_1 = np.zeros((height, width), np.uint8)
result_2 = np.zeros((height, width), np.uint8)
result_3 = np.zeros((height, width), np.uint8)
result_4 = np.zeros((height, width), np.uint8)
result_5 = np.zeros((height, width), np.uint8)
result_6 = np.zeros((height, width), np.uint8)

#保持原始图像
for i in range(height):
    for j in range(width):  
        if (int(grayImage[i,j]) > 255):
            gray = 255
        else:
            gray = int(grayImage[i,j])        
        result_1[i,j] = np.uint8(gray)

#图像灰度上移变换 DB=DA+50
for i in range(height):
    for j in range(width):     
        if (int(grayImage[i,j]+30) > 255):
            gray = 255
        else:
            gray = int(grayImage[i,j]+30)        
        result_2[i,j] = np.uint8(gray)

#图像灰度上移变换 DB=1.5*DA
for i in range(height):
    for j in range(width):     
        if (int(grayImage[i,j]*1.5) > 255):
            gray = 255
        else:
            gray = int(grayImage[i,j]*1.5)        
        result_3[i,j] = np.uint8(gray)

#图像灰度上移变换 DB=0.2*DA
for i in range(height):
    for j in range(width):     
        if (int(grayImage[i,j]*0.2) > 255):
            gray = 255
        else:
            gray = int(grayImage[i,j]*0.2)        
        result_4[i,j] = np.uint8(gray)
        
#图像灰度上移变换 DB=255-1*DA
for i in range(height):
    for j in range(width):
        gray = 255 - grayImage[i,j]
        result_5[i,j] = np.uint8(gray)

#图像灰度上移变换 DB=1.5*DA+10
for i in range(height):
    for j in range(width):     
        if (int(grayImage[i,j]*1.5+10) > 255):
            gray = 255
        else:
            gray = int(grayImage[i,j]*1.5+10)        
        result_6[i,j] = np.uint8(gray)

plt.figure(figsize=(14,14))

plt.subplot(2,3,1)
plt.title('original')
plt.imshow(result_1,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,2)
plt.title('a=1,b=30')
plt.imshow(result_2,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,3)
plt.title('a=1.5,b=0')
plt.imshow(result_3,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,4)
plt.title('a=0.2,b=0')
plt.imshow(result_4,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,5)
plt.title('a=-1,b=255')
plt.imshow(result_5,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,6)
plt.title('a=1.5,b=10')
plt.imshow(result_6,cmap = 'gray')
plt.axis('off')

plt.show()

b) 伽玛变换又称为指数变换或幂次变换,是一种常用的灰度非线性变换。

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 10 20:51:27 2020

@author: Administrator
"""

import cv2  
import numpy as np  
import matplotlib.pyplot as plt

#读取原始图像

def gamma(img,c,v):
    lut = np.zeros(256,dtype=np.float32)
    for i in range(256):
        lut[i] = c*i**v
        output_img = cv2.LUT(img,lut)
        output_img = np.uint8(output_img+0.5) 
    return output_img

img = cv2.imread('F:/img/airport.png')   

output = gamma(img,0.00000005, 4.0) 

plt.figure(figsize=(15,15))

plt.subplot(1,2,1)
plt.title('original')
plt.imshow(img,cmap = 'gray')
plt.axis('off')

plt.subplot(1,2,2)
plt.title('gamma')
plt.imshow(output,cmap = 'gray')
plt.axis('off')

plt.show()

c) 图像灰度的对数变换是另外一种常见的灰度非线性变化。

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 10 21:21:28 2020

@author: Administrator
"""

import cv2  
import numpy as np  
import matplotlib.pyplot as plt

def log(c,img):
    output = c*np.log(1.0+img)
    output = np.uint8(output+0.5)
    return output

img = cv2.imread('F:/img/street.jpg') 

output = log(42,img)

plt.figure(figsize=(18,18))

plt.subplot(1,2,1)
plt.title('original')
plt.imshow(img,cmap = 'gray')
plt.axis('off')

plt.subplot(1,2,2)
plt.title('log')
plt.imshow(output,cmap = 'gray')
plt.axis('off')

plt.show()

图像空域增强与滤波

a) 利用scikit-image包提供的random_noise函数给图像lena.png添加各类噪声

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 10 21:31:24 2020

@author: Administrator
"""

import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage.util import random_noise
 
img = cv2.imread('F:/img/lena.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#高斯噪声
gaussian_img = random_noise(gray, mode='gaussian')
gaussian_img = np.array(255*gaussian_img, dtype = 'uint8')

#椒噪声
pepper_img = random_noise(gray, mode='pepper',amount=0.1)
pepper_img = np.array(255*pepper_img, dtype = 'uint8')

#盐噪声
salt_img = random_noise(gray, mode='salt',amount=0.1)
salt_img = np.array(255*salt_img, dtype = 'uint8')

#椒盐噪声
sp_img = random_noise(gray, mode='s&p',amount=0.1)
sp_img = np.array(255*sp_img, dtype = 'uint8')

#斑点噪声
speckle_img = random_noise(gray, mode='speckle')
speckle_img = np.array(255*speckle_img, dtype = 'uint8')

plt.figure(figsize=(13,13))

plt.subplot(2,3,1)
plt.title('original')
plt.imshow(gray,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,2)
plt.title('gaussian')
plt.imshow(gaussian_img,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,3)
plt.title('salt')
plt.imshow(salt_img,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,4)
plt.title('pepper')
plt.imshow(pepper_img,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,5)
plt.title('sp')
plt.imshow(sp_img,cmap = 'gray')
plt.axis('off')

plt.subplot(2,3,6)
plt.title('speckle')
plt.imshow(speckle_img,cmap = 'gray')
plt.axis('off')

plt.show()

b) 分别利用、box滤波器、高斯滤波器、中值滤波器对以上五种加了噪声的图像进行滤波,比较滤波器的效果

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 10 22:21:58 2020

@author: Administrator
"""

import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage.util import random_noise
 
img = cv2.imread('F:/img/lena.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#高斯噪声
gaussian_img = random_noise(gray, mode='gaussian')
gaussian_img = np.array(255*gaussian_img, dtype = 'uint8')

#椒噪声
pepper_img = random_noise(gray, mode='pepper',amount=0.1)
pepper_img = np.array(255*pepper_img, dtype = 'uint8')

#盐噪声
salt_img = random_noise(gray, mode='salt',amount=0.1)
salt_img = np.array(255*salt_img, dtype = 'uint8')

#椒盐噪声
sp_img = random_noise(gray, mode='s&p',amount=0.1)
sp_img = np.array(255*sp_img, dtype = 'uint8')

#斑点噪声
speckle_img = random_noise(gray, mode='speckle')
speckle_img = np.array(255*speckle_img, dtype = 'uint8')

imgs = [gray,gaussian_img,pepper_img,salt_img,sp_img,speckle_img]
titles = ['original','gaussian', 'pepper', 'salt', 'sp','speckle']

plt.figure(figsize=(13,13))
#均值滤波器
for i in range(6):
    img_mean = cv2.blur(imgs[i], (5,5))
    plt.subplot(2,3,i+1)
    plt.imshow(img_mean,cmap = 'gray')
    plt.title(titles[i]+' blur')
    plt.axis('off')
plt.show()

plt.figure(figsize=(13,13))
#高斯滤波器
for i in range(6):
    img_Guassian = cv2.GaussianBlur(imgs[i],(5,5),0)
    plt.subplot(2,3,i+1)
    plt.imshow(img_Guassian,cmap = 'gray')
    plt.title(titles[i]+' guass')
    plt.axis('off')
plt.show()

plt.figure(figsize=(13,13))
#中值滤波器
for i in range(6):
    img_median = cv2.medianBlur(imgs[i], 5)
    plt.subplot(2,3,i+1)
    plt.imshow(img_median,cmap = 'gray')
    plt.title(titles[i]+' med')
    plt.axis('off')
plt.show()

plt.figure(figsize=(13,13))
#双边滤波
for i in range(6):
    img_bilater = cv2.bilateralFilter(imgs[i],9,75,75)
    plt.subplot(2,3,i+1)
    plt.imshow(img_bilater,cmap = 'gray')
    plt.title(titles[i]+' bil')
    plt.axis('off')
plt.show()


原创文章 7 获赞 8 访问量 1164

猜你喜欢

转载自blog.csdn.net/bestlinton/article/details/105450974