幂律变换 数字图像处理_数字图像处理中的幂律变换matalb - CSDN
精华内容
参与话题
  • 数字图像处理(Digital Image Processing)是通过计算机对图像进行...在数字图像处理学习笔记(八)中,已对图像增强之线性变换、对数变换、幂律变换、分段线性变换、灰度级分层等做过详细理论论述,本文将对上述理...

    数字图像处理(Digital Image Processing)是通过计算机对图像进行去除噪声、增强、复原、分割、提取特征等处理的方法和技术。本专栏将以学习笔记形式对数字图像处理的重点基础知识进行总结整理,欢迎大家一起学习交流!
    专栏链接:数字图像处理学习笔记

    在数字图像处理学习笔记(八)中,已对图像增强之线性变换、对数变换、幂律变换、分段线性变换、灰度级分层等做过详细理论论述,本文将对上述理论知识做实践方面的实现。

    具体理论知识可参考我之前的博文:数字图像处理学习笔记(八)——图像增强处理方法之点处理

    一、图像增强之线性变换

    代码实现参考

    import cv2
    import random
    import imutils
    import numpy as np
    
    # 彩色图像每个像素值是[x,y,z], 灰度图像每个像素值便是一个np.uint8
    image = cv2.imread('E:/1.PNG')
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  #将彩色图像变为灰度图像(RGB彩色变灰色)
    
    # 图像大小调整
    ori_h, ori_w = image.shape[:2]   #获得原图像长宽
    height, width = gray_img.shape[:2]   #获得灰度图像长宽
    image = cv2.resize(image, (int(ori_w / ori_h * 400), 400), interpolation=cv2.INTER_CUBIC)  #对图像大小变换且做三次插值
    gray_img = cv2.resize(gray_img, (int(width / height * 400), 400), interpolation=cv2.INTER_CUBIC)  #对图像大小变换且做三次插值
    
    # a<0 and b=0: 图像的亮区域变暗,暗区域变亮
    a, b = -0.5, 0
    new_img1 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8) #初始化一个新图像做变换,且大小同灰度图像大小
    for i in range(new_img1.shape[0]):
        for j in range(new_img1.shape[1]):
            new_img1[i][j] = gray_img[i][j] * a + b  #原始图像*a+b
    
    # a>1: 增强图像的对比度,图像看起来更加清晰
    a, b = 1.5, 20
    new_img2 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(new_img2.shape[0]):
        for j in range(new_img2.shape[1]):
            if gray_img[i][j] * a + b > 255:
                new_img2[i][j] = 255
            else:
                new_img2[i][j] = gray_img[i][j] * a + b
    
    # a<1: 减小了图像的对比度, 图像看起来变暗
    a, b = 0.5, 0
    new_img3 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(new_img3.shape[0]):
        for j in range(new_img3.shape[1]):
            new_img3[i][j] = gray_img[i][j] * a + b
    
    # a=1且b≠0, 图像整体的灰度值上移或者下移, 也就是图像整体变亮或者变暗, 不会改变图像的对比度
    a, b = 1, -50
    new_img4 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(new_img4.shape[0]):
        for j in range(new_img4.shape[1]):
            pix = gray_img[i][j] * a + b
            if pix > 255:
                new_img4[i][j] = 255
            elif pix < 0:
                new_img4[i][j] = 0
            else:
                new_img4[i][j] = pix
    
    # a=-1, b=255, 图像翻转
    new_img5 = 255 - gray_img
    
    cv2.imshow('origin', imutils.resize(image, 800))
    cv2.imshow('gray', imutils.resize(gray_img, 800))
    cv2.imshow('a<0 and b=0', imutils.resize(new_img1, 800))
    cv2.imshow('a>1 and b>=0', imutils.resize(new_img2, 800))
    cv2.imshow('a<1 and b>=0', imutils.resize(new_img3, 800))
    cv2.imshow('a=1 and b><0', imutils.resize(new_img4, 800))
    cv2.imshow('a=-1 and b=255', imutils.resize(new_img5, 800))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    
    

    运行结果截图

    原图
    在这里插入图片描述
    变为灰度图像

    在这里插入图片描述
    图像的亮区域变暗,暗区域变亮
    在这里插入图片描述
    图像整体的灰度值上移, 也就是图像整体变亮, 不会改变图像的对比度
    在这里插入图片描述
    图像整体的灰度值下移, 也就是图像整体变暗, 不会改变图像的对比度
    在这里插入图片描述
    在这里插入图片描述
    图像翻转
    在这里插入图片描述

    二、对比度拉伸

    代码参考

    import cv2
    import imutils
    import numpy as np
    
    # image = cv2.imread('E:/city.PNG')
    
    image = cv2.imread('E:/city.PNG')
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # 在灰度图进行分段线性对比度拉伸
    # 此种方式变换函数把灰度级由原来的线性拉伸到整个范围[0, 255]
    r_min, r_max = 255, 0
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            if gray_img[i, j] > r_max:
                r_max = gray_img[i, j]
            if gray_img[i, j] < r_min:
                r_min = gray_img[i, j]
    r1, s1 = r_min, 0
    r2, s2 = r_max, 255
    
    precewise_img = np.zeros((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    k1 = s1 / r1
    k3 = (255 - s2) / (255 - r2)
    k2 = (s2 - s1) / (r2 - r1)
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            if r1 <= gray_img[i, j] <= r2:
                precewise_img[i, j] = k2 * (gray_img[i, j] - r1)
            elif gray_img[i, j] < r1:
                precewise_img[i, j] = k1 * gray_img[i, j]
            elif gray_img[i, j] > r2:
                precewise_img[i, j] = k3 * (gray_img[i, j] - r2)
    
    cv2.imshow('origin image', imutils.resize(image, 480))
    cv2.imshow('gray image', imutils.resize(gray_img, 480))
    cv2.imshow('precewise image', imutils.resize(precewise_img, 480))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    
    
    

    运行结果截图

    原图
    在这里插入图片描述
    变为灰度图像
    在这里插入图片描述
    灰度图像对比度拉伸后结果图
    在这里插入图片描述

    三、灰度级分层

    代码参考

    import cv2
    import imutils
    import numpy as np
    
    # 在某一范围(A, B)突出灰度,其他灰度值保持不变
    image = cv2.imread('E:/city.PNG')
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    r_left, r_right = 150, 230
    r_min, r_max = 0, 255
    level_img = np.zeros((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            if r_left <= gray_img[i, j] <= r_right:
                level_img[i, j] = r_max
            else:
                level_img[i, j] = gray_img[i, j]
    
    cv2.imshow('origin image', imutils.resize(image, 480))
    cv2.imshow('level image', imutils.resize(level_img, 480))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    运行结果截图

    原图
    在这里插入图片描述
    灰度级分层处理后的图像

    在这里插入图片描述

    四、幂律变换

    代码参考

    import math
    import numpy as np
    import cv2
    import imutils
    
    # #幂律变换 φ>1
    # # image = cv2.imread('E:/1.png')
    image = cv2.imread('E:/1.png')
    gamma_img1 = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            gamma_img1[i, j, 0] = math.pow(image[i, j, 0], 5)
            gamma_img1[i, j, 1] = math.pow(image[i, j, 1], 5)
            gamma_img1[i, j, 2] = math.pow(image[i, j, 2], 5)
    cv2.normalize(gamma_img1, gamma_img1, 0, 255, cv2.NORM_MINMAX)
    gamma_img1 = cv2.convertScaleAbs(gamma_img1)
    cv2.imshow('image', imutils.resize(image, 400))
    cv2.imshow('gamma1 transform', imutils.resize(gamma_img1, 400))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    
    
    #幂律变换,φ<1
    # image = cv2.imread('E:/1.png')
    image = cv2.imread('E:/city.png')
    gamma_img2 = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            gamma_img2[i, j, 0] = math.pow(image[i, j, 0], 0.4)
            gamma_img2[i, j, 1] = math.pow(image[i, j, 1], 0.4)
            gamma_img2[i, j, 2] = math.pow(image[i, j, 2], 0.4)
    cv2.normalize(gamma_img2, gamma_img2, 0, 255, cv2.NORM_MINMAX)
    gamma_img2 = cv2.convertScaleAbs(gamma_img2)
    cv2.imshow('image', imutils.resize(image, 400))
    cv2.imshow('gamma2 transform', imutils.resize(gamma_img2, 400))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    运行结果截图

    φ>1

    原图
    在这里插入图片描述
    幂律变换后的图像

    在这里插入图片描述

    φ<1

    原图
    在这里插入图片描述
    幂律变换后的图像
    在这里插入图片描述

    五、阈值处理

    代码参考

    import cv2
    import imutils
    import numpy as np
    
    image = cv2.imread('E:/1.png')
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    #阈值处理函数:当r1=r2, s1=0, s2=L-1时,此时分段线性函数便是阈值处理函数
    plist = []
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            plist.append(gray_img[i, j])
    r_avg = int(sum(plist)/len(plist))
    thresh_img = np.zeros((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            if gray_img[i, j] < r_avg:
                thresh_img[i, j] = 0
            else:
                thresh_img[i, j] = 255
    
    cv2.imshow('origin image', imutils.resize(image, 480))
    cv2.imshow('thresh image', imutils.resize(thresh_img, 480))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    
    

    运行结果截图

    原图
    在这里插入图片描述
    阈值处理后的图像
    在这里插入图片描述

    六、直方图均衡化

    代码实现参考

    import cv2
    import imutils
    import numpy as np
    import matplotlib.pyplot as plt
    
    wiki_img=cv2.imread('E:/1.PNG')
    wiki_gray=cv2.cvtColor(wiki_img,cv2.COLOR_BGR2GRAY)
    
    #对图像进行均衡化处理,增强图像对比度
    wiki_equ=cv2.equalizeHist(wiki_gray)
    
    hist=cv2.calcHist([wiki_gray],[0],None,[256],[0,256])
    equ_hist=cv2.calcHist([wiki_equ],[0],None,[256],[0,256])
    fig=plt.figure()
    ax1=fig.add_subplot(1,2,1)
    ax1.plot(hist)
    ax2=fig.add_subplot(1,2,2)
    ax2.plot(equ_hist)
    plt.show()
    
    cv2.imshow('wiki_origin',imutils.resize(wiki_img,400))
    cv2.imshow('wiki_gray',imutils.resize(wiki_gray,400))
    cv2.imshow('wiki_equ',imutils.resize(wiki_equ,400))
    if cv2.waitKey(0)==27:
        cv2.destroyAllWindows()
    

    运行结果截图

    原图
    在这里插入图片描述
    灰度变换图像
    在这里插入图片描述
    直方图均衡化后的图像

    在这里插入图片描述
    直方图显示

    在这里插入图片描述

    七、均值滤波器

    代码参考

    import cv2
    import copy
    import random
    import imutils
    import numpy as np
    
    img=cv2.imread('E:/1.PNG')
    gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    #利用OpenCV提供函数实现均值滤波
    blur_img=cv2.blur(gray_img,(3,3))
    
    #在灰度图上手动实现均值滤波器
    gray_avg_img=copy.deepcopy(gray_img)   #在复制图像上修改,首先复制一份
    for i in range(1,gray_img.shape[0]-1):
        for j in range(1,gray_img.shape[1]-1):
            sum_pix=sum([gray_img[l,k] for l in range(i-1,i+2) for k in range(j-1,j+2)]) #range函数写到i+2实际遍历到i+1,j+1同理
            gray_avg_img[i,j]=int(sum_pix/9) #9个点求和除均值,均值滤波实现
    
    #在RGB彩色图上手动实现均值滤波
    rgb_avg_img=copy.deepcopy(img)
    for i in range(1,img.shape[0]-1):
        for j in range(1,img.shape[1]-1):  #RGB三个通道,实现三次
            sum_b_pix=sum([img[l,k,0] for l in range(i-1,i+2) for k in range(j-1,j+2)])
            sum_g_pix = sum([img[l, k, 1] for l in range(i - 1, i + 2) for k in range(j - 1, j + 2)])
            sum_r_pix = sum([img[l, k, 2] for l in range(i - 1, i + 2) for k in range(j - 1, j + 2)])
            rgb_avg_img[i,j]=[int(sum_b_pix/9),int(sum_g_pix/9),int(sum_r_pix/9)]
    
    cv2.imshow('origin image',imutils.resize(img,500))
    cv2.imshow('gray image',imutils.resize(gray_img,500))
    cv2.imshow('blur image',imutils.resize(blur_img,500))
    cv2.imshow('gray average image',imutils.resize(gray_avg_img,500))
    cv2.imshow('rgb average image',imutils.resize(rgb_avg_img,500))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    运行结果截图

    原图
    在这里插入图片描述
    灰度处理后的图像
    在这里插入图片描述
    OpenCV库提供的blur函数实现均值滤波后的图像
    在这里插入图片描述
    自己编写均值滤波函数实现的均值滤波图像
    在这里插入图片描述
    RGB三通道下的均值滤波器实现的均值滤波图像
    在这里插入图片描述

    八、最大、最小、中值滤波器

    代码参考

    import cv2
    import copy
    import random
    import imutils
    import numpy as np
    
    img=cv2.imread('E:/1.PNG')
    gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    #给灰度图像自动添加椒盐噪声
    pepper_img=copy.deepcopy(gray_img)
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            if random.randint(0,20)==0:
                pix=random.randint(250,255)
                pepper_img[i,j]=pix
    
    #opencv提供CV2.medianBlur()函数实现中值滤波
    blur_img=cv2.medianBlur(pepper_img,5)
    
    #自实现中值滤波
    temp_arr=np.zeros((9))
    median_img=copy.deepcopy(pepper_img)
    max_img=copy.deepcopy(pepper_img)
    min_img=copy.deepcopy(pepper_img)
    for i in range(1,pepper_img.shape[0]-1):   #九个数字全部提取出来
        for j in range(1,pepper_img.shape[1]-1):
            temp_arr[0] = pepper_img[i - 1, j - 1]
            temp_arr[1] = pepper_img[i - 1, j]
            temp_arr[2] = pepper_img[i - 1, j + 1]
            temp_arr[3] = pepper_img[i - 1, j - 1]
            temp_arr[4] = pepper_img[i, j - 1]
            temp_arr[5] = pepper_img[i, j]
            temp_arr[6] = pepper_img[i, j + 1]
            temp_arr[7] = pepper_img[i + 1, j - 1]
            temp_arr[8] = pepper_img[i + 1, j]
            arr = np.sort(temp_arr)   #从小到大排序
            median_img[i,j]=arr[4]       
            max_img[i,j]=arr[8]
            min_img[i,j]=arr[0]
    
    rgb_avg_img=copy.deepcopy(img)
    for i in range(1,img.shape[0]-1):
        for j in range(1,img.shape[1]-1):
            sum_b_pix = sum([img[l,k,0] for l in range(i-1,i+2) for k in range(j-1,j+2)])
            sum_g_pix = sum([img[l, k, 1] for l in range(i - 1, i + 2) for k in range(j - 1, j + 2)])
            sum_r_pix = sum([img[l, k, 2] for l in range(i - 1, i + 2) for k in range(j - 1, j + 2)])
            rgb_avg_img[i,j]=[int(sum_b_pix/9),int(sum_g_pix/9),int(sum_r_pix/9)]
    
    cv2.imshow('pepper image',imutils.resize(pepper_img,600))
    cv2.imshow('blur image',imutils.resize(blur_img,600))
    cv2.imshow('median image',imutils.resize(pepper_img,600))
    cv2.imshow('mean image',imutils.resize(rgb_avg_img,600))
    cv2.imshow('max image',imutils.resize(max_img,600))
    cv2.imshow('min image',imutils.resize(min_img,600))
    
    if cv2.waitKey(0)==27:
        cv2.destroyAllWindows()
    
    
    

    运行结果截图

    原图
    在这里插入图片描述
    椒盐噪声图像
    在这里插入图片描述
    OpenCV库自带函数实现中值滤波
    在这里插入图片描述
    中值滤波图像
    在这里插入图片描述
    最大值滤波器图像
    在这里插入图片描述
    最小值滤波器图像
    在这里插入图片描述

    九、锐化滤波器

    代码参考

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    #读取图像
    img=cv2.imread('E:/1.PNG')
    girl_img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    
    #灰度化处理图像
    grayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    #高斯滤波
    gaussianBlur=cv2.GaussianBlur(grayImage,(3,3),0)
    
    #阈值处理
    ret,binary=cv2.threshold(gaussianBlur,127,255,cv2.THRESH_BINARY) #小于127变0,在127到255之间的变1
    
    #Roberts算子
    kernelx=np.array([[-1,0],[0,1]],dtype=int)
    kernely=np.array([[0,-1],[1,0]],dtype=int)
    x=cv2.filter2D(binary,cv2.CV_16S,kernelx)
    y=cv2.filter2D(binary,cv2.CV_16S,kernely)
    absX=cv2.convertScaleAbs(x)
    absY=cv2.convertScaleAbs(y)
    Roberts=cv2.addWeighted(absX,0.5,absY,0.5,0)
    
    #Prewitt算子
    kernelx=np.array([[1,1,1],[0,0,0],[-1,-1,-1]],dtype=int)
    kernely=np.array([[-1,0,1],[-1,0,1],[-1,0,1]],dtype=int)
    x=cv2.filter2D(binary,cv2.CV_16S,kernelx)
    y=cv2.filter2D(binary,cv2.CV_16S,kernely)
    absX=cv2.convertScaleAbs(x)
    absY=cv2.convertScaleAbs(y)
    Prewitt=cv2.addWeighted(absX,0.5,absY,0.5,0)
    
    #Sobel算子
    x=cv2.Sobel(binary,cv2.CV_16S,1,0)
    y=cv2.Sobel(binary,cv2.CV_16S,0,1)
    absX=cv2.convertScaleAbs(x)
    absY=cv2.convertScaleAbs(y)
    Sobel=cv2.addWeighted(absX,0.5,absY,0.5,0)
    
    #拉普拉斯算法
    dst=cv2.Laplacian(binary,cv2.CV_16S,ksize=3)
    Laplacian=cv2.convertScaleAbs(dst)
    
    #效果图
    titles=['Source Image','Binary Image','Roberts Image','Prewitt Image','Sobel Image','Laplacian Image']
    images=[girl_img,binary,Roberts,Prewitt,Sobel,Laplacian]
    for i in np.arange(6):
        plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')  #2行3列图像显示
        plt.title(titles[i])
        plt.xticks([]),plt.yticks([])
    plt.show()
    

    运行结果截图

    在这里插入图片描述

    欢迎留言,一起学习交流~~~

    感谢阅读

    END

    展开全文
  • 本文主要介绍对《数字图像处理》第三章书中示例图片实现 反转变换、对数变换以及伽马变换的代码 若要获取更多数字图像处理,python,深度学习,机器学习,计算机视觉等高清PDF以及 更多有意思的 分享,可搜一搜 微信...

    本文主要介绍对《数字图像处理》第三章书中示例图片实现 反转变换对数变换以及伽马变换的代码

    若要获取更多数字图像处理,python,深度学习,机器学习,计算机视觉等高清PDF以及 更多有意思的 分享,可搜一搜 微信公共号 “分享猿” 免费获取资源。也可扫描下面的二维码关注,期待你的到来~
    在这里插入图片描述
    图像增强的三类基本函数:线性函数(反转和恒等变换)、对数函数(对数和反对数变换)、幂律函数(n次幂和n次跟变换)

    一、反转变换

    公式S=L-1-r
    在这里插入图片描述
    代码实现

    import cv2
    import numpy as np
    
    img = cv2.imread(r'C:\Users\xxx\Desktop\breast.tif',0)
    
    reverse_img = 255 - img
    
    cv2.imshow('srcimg',img)
    cv2.imshow('reverse_img',reverse_img)
    cv2.waitKey(0)
    

    下列分别是乳房X射线原始图及用上式给出的反转图像
    在这里插入图片描述 在这里插入图片描述
    二、对数变换

    公式s=clog(1+r)
    下图是当c=1时的r与s关系图
    在这里插入图片描述
    代码实现

    import cv2
    import math
    import numpy as np
    
    def logTransform(c,img):
    
        #3通道RGB
        '''h,w,d = img.shape[0],img.shape[1],img.shape[2]
        new_img = np.zeros((h,w,d))
        for i in range(h):
            for j in range(w):
                for k in range(d):
                    new_img[i,j,k] = c*(math.log(1.0+img[i,j,k]))'''
    
        #灰度图专属
        h,w = img.shape[0], img.shape[1]
        new_img = np.zeros((h, w))
        for i in range(h):
            for j in range(w):
                new_img[i, j] = c * (math.log(1.0 + img[i, j]))
    
    
        new_img = cv2.normalize(new_img,new_img,0,255,cv2.NORM_MINMAX)
    
        return new_img
        
    #替换为你的图片路径
    img = cv2.imread(r'C:\Users\xxx\Desktop\Fourier spectrum.tif',0)
    
    log_img = logTransform(1.0,img)
    cv2.imshow('log_img',log_img)
    cv2.imwrite(r'C:\Users\xxx\Desktop\Fourier spectrum2.jpg',log_img)
    cv2.waitKey(0)
    

    备注:当r=255时,s=5.541

    下列图像分别是傅里叶频谱和应用上式中的对数变换(c=1)的结果
    在这里插入图片描述 在这里插入图片描述
    由于对数曲线在像素值较低的区域斜率大,在像素值较高的区域斜率较小,所以图像经过对数变换后,较暗区域的对比度将有所提升。可用于增强图像的暗部细节

    三、幂律(伽马)变化

    公式:s=cr^γ
    其中c、γ 为常数。考虑偏移量上式可写为 s=c(ε+r)^γ
    对于不同的 γ 值,s 与 r的关系曲线如下图所示
    在这里插入图片描述
    伽马变换可以很好地拉伸图像的对比度,扩展灰度级。
    由图可知,
    当图像的整体灰度偏暗时,选择γ<1,可以使图像增亮;
    当图像的整体灰度偏亮时,选择γ>1,可以使图像变暗,
    提高图像的对比度,凸显细节。

    用于图像获取、打印和显示的各种设备根据幂律来产生响应,用于校正这些幂律响应现象的处理称为伽马校正
    例如,阴极射线管(CRT)设备有一个灰度-电压响应,该响应是一个指数变化范围约为1.8~2.5的幂函数。

    代码实现

    import math
    import numpy as np
    import cv2
    
    def gammaTranform(c,gamma,image):
        h,w,d = image.shape[0],image.shape[1],image.shape[2]
        new_img = np.zeros((h,w,d),dtype=np.float32)
        for i in range(h):
            for j in range(w):
                new_img[i,j,0] = c*math.pow(image[i, j, 0], gamma)
                new_img[i,j,1] = c*math.pow(image[i, j, 1], gamma)
                new_img[i,j,2] = c*math.pow(image[i, j, 2], gamma)
        cv2.normalize(new_img,new_img,0,255,cv2.NORM_MINMAX)
        new_img = cv2.convertScaleAbs(new_img)
    
        return new_img
    
    img = cv2.imread(r'C:\Users\xxx\Desktop\gray.jpg',1)
    
    new_img = gammaTranform(1,2.5,img)
    
    cv2.imshow('x',new_img)
    cv2.imwrite(r'C:\Users\xxx\Desktop\gray_2.5.jpg',new_img)
    cv2.waitKey(0)
    

    下图是用变换s = r^1/2.5 = r^0.4进行伽马校正的示例的结果
    在这里插入图片描述
    一般,随着设备的不同,伽马值也不同

    使用幂律变换进行对比度增强
    γ<1 增强亮度
    分别是原图,以及c=1时的γ=0.6、0.4、0.3时应用上公示的结果
    在这里插入图片描述

    γ>1 增强暗度
    航拍图像
    在这里插入图片描述
    下面三幅图片分别是c=1时γ等于3.0、4.0、5.0时应用公式变换的结果
    在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

    搜索公众号“分享猿”,并回复关键词“代码”,获取本文全部代码
    留言或者公众号关注我,我们一起分享数字图像处理心得,一起交流学习吧~

    展开全文
  • 本系列python版本:python3.5.4 本系列opencv-python版本:opencv-python3.4.2.17 本系列使用的开发环境是jupyter notebook,是一个python的交互式开发环境,测试十分方便,并集成了...上文【数字图像处理系列二...

    本系列python版本:python3.5.4
    本系列opencv-python版本:opencv-python3.4.2.17
    本系列使用的开发环境是jupyter notebook,是一个python的交互式开发环境,测试十分方便,并集成了vim操作,安装教程可参考:windows上jupyter notebook主题背景、字体及扩展插件配置(集成vim环境)


    上文【数字图像处理系列二】基本概念:亮度、对比度、饱和度、锐化、分辨率 中我们一起学习了数字图像概念和形成原理,并在实践和对比中一起分析了图像亮度、对比度、饱和度、锐化、分辨率等属性。图像的基础知识介绍完毕,此后将开始着重介绍数字图像处理和分析,本文便从 图像灰度变换增强 开始说起,这在图像预处理中也可以说是很重要的了,杠~~

    老规矩,先上图:
    在这里插入图片描述

    经过图像增强后的图片:
    在这里插入图片描述





    一、图像增强知识预热



    1、为啥要做图像增强

    在图像形成的过程中,存在很多因素影响图像的清晰度,列举几个常见影响图像清晰度因素如下:

    • 光照不够均匀,这会造成图像灰度过于集中
    • 由CCD(摄像头)获得图像时金A/D(数模)转换、线路传送时产生噪声污染,影响图像质量

    因此必须在图像处理分析之前对图像的质量进行改善,改善方法分为两类:

    • 图像增强
    • 图像复原

    图像增强不考虑图像质量下降的原因,只将图像中感兴趣的特征有选择的突出,而衰减不需要的特征,它的目的主要是提高图像的可懂度; 图像复原技术与增强技术不同,它需要了解图像质量下降的原因,首先要建立"降质模型",再利用该模型,恢复原始图像。

    本文便重点研究一下图像增强技术,图像增强主要是以对比度和阈值处理为目的,且都是在空间域进行的操作。我们假设 f(x,y) 是输入图像,g(x,y) 为经过增强变换处理后的图像,则有:

    这里的 T 便是在点 (x,y) 的邻域定义的关于 f 的算子,根据邻域的不同,图像增强分为两种:

    • 邻域处理技术
    • 点处理技术,又称 图像灰度变换增强技术,本文重点将讨论


    2、图像增强邻域处理技术

    空间域处理 g(x,y) = T[f(x, y)] 中点 (x,y) 便是图像的像素坐标,而邻域是中心在 (x,y) 的矩形,其尺寸比图像要小得多,如下图所示:
    在这里插入图片描述

    图像增强邻域处理技术的核心思想便是: 当对 (x,y) 做变换时,变换算子 T 是对以 (x,y) 为中心的邻域作用然后得出变换结果,如上图,假如该邻域的大小是3*3的正方形,算子 T 定义为 计算该邻域的平均灰度,如 (x,y) = (100,200),则 g(100,200) 的结果便是计算 f(100,200) 和它的8个邻点的和,然后在除以9 (即是由邻域包围的像素灰度的平均值),当然这种邻域处理思想在后续的图像滤波处理中是基本应用,如均值滤波、中值滤波和高斯滤波等都是采用邻域处理技术。



    3、图像增强点处理技术

    点处理技术,既是当邻域的大小为 1*1 时,此时 g 的值仅仅取决于点 (x,y) 处的值,此时 T 称为灰度变换函数,此种图像增强方式就是图像灰度变换增强,定义公式如下:

    其中 s 是变换后的像素,r 是变换前的像素,此后讨论的线性变换、 分段线性变换、 对数变换、 反对数变换、 幂律(伽马)变换均是基于此公式为基础进行的,因此图像灰度变换便是基于点的增强方式,它将每一个像素的灰度值按照一定的数学变换公式转换为一个新的灰度值,达到增强图像的效果。





    二、图像灰度变换增强



    说在前面: 线性变换和分段线性变换一般对灰度图像进行处理,也可以直接对RGB图像进行处理;对数变换、 反对数变换、 幂律(伽马)变换则是直接对RGB图像进行相应的图像增强,达到自己想要的结果

    如果对RGB图像进行变换之后需要多两部操作:(1) 图像归一化、(2) 图像像素值类型转化为np.uint8,需要用到两个函数,在这里做简单介绍,后续示例程序中将会使用到:

    函数cv2.normalize()

    #数字图像归一化操作
    cv2.normalize(src, dst, alpha, beta, norm_type, dtype, mask) → dst
    

    参数解释:

    • src: 原图像对象

    • dst: 经过转化后的图像对象

    • alpha: 归一化后灰度像素最小值,一般为0

    • beta: 归一化后灰度像素最大值,一般为255

    • norm_type: 归一化的类型,可以取以下值

      (1) cv2.NORM_MINMAX: 数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用
      (2) cv2.NORM_INF:此类型的定义没有查到,根据OpenCV 1的对应项,可能是归一化数组的C-范数(绝对值的最大值)
      (3) cv2.NORM_L1 : 归一化数组的L1-范数(绝对值的和)
      (4) cv2.NORM_L2: 归一化数组的(欧几里德)L2-范数

    • dtype: 为负数时,输出图像像素值的type与输入相同,一般使用默认

    • mask: 操作掩膜,用于指示函数是否仅仅对指定的元素进行操作,一般使用默认


    函数cv2.convertScaleAbs()

    #该函数较简单,便是将原图像的像素值均转化成类型为np.uint8
    dst = cv2.convertScaleAbs(src)
    



    1、线性变换

    图像增强线性变换主要可以对图像的对比度和亮度进行调整,线性变换公式如下:

    参数 a 影响图像的对比度,参数 b 影响图像的亮度,具体分为可分为以下几种情况:

    • a>1: 增强图像的对比度,图像看起来更加清晰
    • a<1: 减小了图像的对比度, 图像看起来变暗
    • a<0 and b=0:图像的亮区域变暗,暗区域变亮
    • a=1 and b≠0:图像整体的灰度值上移或者下移,也就是图像整体变亮或者变暗,不会改变图像的对比度,b>0时图像变亮,b<0时图像变暗
    • a=-1 and b=255:图像翻转

    上代码:

    import cv2
    import random
    import imutils
    import numpy as np
    
    #彩色图像每个像素值是[x,y,z], 灰度图像每个像素值便是一个np.uint8
    image = cv2.imread('E:/peking_rw/ocr_project/base_prehandle/img/ali.jpg')
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    #图像大小调整
    ori_h, ori_w = image.shape[:2]
    height, width = gray_img.shape[:2]
    image = cv2.resize(image, (int(ori_w/ori_h*400), 400), interpolation=cv2.INTER_CUBIC)
    gray_img = cv2.resize(gray_img, (int(width/height*400), 400), interpolation=cv2.INTER_CUBIC)
    
    #a<0 and b=0: 图像的亮区域变暗,暗区域变亮
    a, b = -0.5, 0
    new_img1 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(new_img1.shape[0]):
        for j in range(new_img1.shape[1]):
            new_img1[i][j] = gray_img[i][j]*a + b
            
    #a>1: 增强图像的对比度,图像看起来更加清晰
    a, b = 1.5, 20
    new_img2 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(new_img2.shape[0]):
        for j in range(new_img2.shape[1]):
            if gray_img[i][j]*a + b > 255:
                new_img2[i][j] = 255
            else:
                new_img2[i][j] = gray_img[i][j]*a + b
    
    #a<1: 减小了图像的对比度, 图像看起来变暗
    a, b = 0.5, 0
    new_img3 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(new_img3.shape[0]):
        for j in range(new_img3.shape[1]):
            new_img3[i][j] = gray_img[i][j]*a + b
    
    #a=1且b≠0, 图像整体的灰度值上移或者下移, 也就是图像整体变亮或者变暗, 不会改变图像的对比度
    a, b = 1, -50
    new_img4 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(new_img4.shape[0]):
        for j in range(new_img4.shape[1]):
            pix = gray_img[i][j]*a + b
            if pix > 255:
                new_img4[i][j] = 255
            elif pix < 0:
                new_img4[i][j] = 0
            else:
                new_img4[i][j] = pix
    
    #a=-1, b=255, 图像翻转
    new_img5 = 255 - gray_img
    
    cv2.imshow('origin', imutils.resize(image, 800))
    cv2.imshow('gray', imutils.resize(gray_img, 800))
    cv2.imshow('a<0 and b=0', imutils.resize(new_img1, 800))
    cv2.imshow('a>1 and b>=0', imutils.resize(new_img2, 800))
    cv2.imshow('a<1 and b>=0', imutils.resize(new_img3, 800))
    cv2.imshow('a=1 and b><0', imutils.resize(new_img4, 800))
    cv2.imshow('a=-1 and b=255', imutils.resize(new_img5, 800))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    代码运行效果,原灰度图像:
    在这里插入图片描述

    通过对图像对比度、亮度增强之后效果如下:

    在这里插入图片描述

    注: 明白一点就是图像增强从来没有通用的理论,在不同的场景下会有不同的需求,图像灰度增强最简单的线性变换可以满足对图像对比度和亮度进行随意的调整,得到自己想要的结果




    2、分段线性变换

    分段线性变换函数来增强图像对比度的方法实际是增强原图各部分的反差,即增强输入图像中感兴趣的灰度区域,相对抑制那些不感兴趣的灰度区域。增分段线性函数的主要优势在于它的形式可任意合成,而其缺点是需要更多的用户输入。分段线性函数通用公式如下:

    下面我们便通过实例来感受一下分段线性函数对于图像增强的几个方面的应用,并体会上面公式的含义!


    2.1 分段线性变换应用之对比度拉伸、阈值处理

    低对比度图像一般由光照不足,成像传感器动态范围太小,图像获取过程中镜头光圈设置错误引起,对比度拉伸是扩展图像灰度级动态范围的处理。变换算子 T 如下所示:

    在这里插入图片描述

    根据r1、s1、r2、s2可分为以下两种增强情况:

    • r1 <= r2、s1 <= s2: 对比度拉伸,增强感兴趣区域
    • r1 = r2: 阈值处理,产生一个二值图像


    (1) 对比度拉伸实例演示

    下面令(r1, s1) = (rmin,0)、(r2, s2) = (rmax,L-1),其中 rmin、rmax 分别代表数字图像中最小灰度级和最大灰度级,此变换函数将灰度级由原来范围线性拉伸到整个范围[0,L-1], 上示例代码:

    import cv2
    import imutils
    import numpy as np
    
    image = cv2.imread('E:/peking_rw/ocr_project/base_prehandle/img/pollen.jpg')
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    #在灰度图进行分段线性对比度拉伸
    #此种方式变换函数把灰度级由原来的线性拉伸到整个范围[0, 255]
    r_min, r_max = 255, 0
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            if gray_img[i, j] > r_max:
                r_max = gray_img[i, j]
            if gray_img[i, j] < r_min:
                r_min = gray_img[i, j]
    r1, s1 = r_min, 0
    r2, s2 = r_max, 255
    
    precewise_img = np.zeros((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    k1 = s1/r1
    k3 = (255-s2)/(255-r2)
    k2 = (s2 - s1)/(r2 - r1)
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            if r1 <= gray_img[i, j] <= r2:
                precewise_img[i, j] = k2*(gray_img[i, j] - r1)
            elif gray_img[i, j] < r1:
                precewise_img[i, j] = k1*gray_img[i, j]
            elif gray_img[i, j] > r2:
                precewise_img[i, j] = k3*(gray_img[i, j] - r2)
                
    cv2.imshow('origin image', imutils.resize(image, 480))
    cv2.imshow('precewise image', imutils.resize(precewise_img, 480))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    上述代码是在灰度图片上进行的图像增强,我们也可以直接在原图上进行图像增强,显示出来的效果都是相同的,代码如下:

    import cv2
    import imutils
    import numpy as np
    
    image = cv2.imread('E:/peking_rw/ocr_project/base_prehandle/img/pollen.jpg')
    
    #直接在原图上进行分段线性对比度拉伸
    #此种方式变换函数把灰度级由原来的线性拉伸到整个范围[0, 255] 
    r_min, r_max = 255, 0
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            for k in range(image.shape[2]):
                if image[i, j, k] > r_max:
                    r_max = image[i, j, k]
                if image[i, j, k] < r_min:
                    r_min = image[i, j, k]
    r1, s1 = r_min, 0
    r2, s2 = r_max, 255
    k1 = s1/r1
    k3 = (255-s2)/(255-r2)
    k2 = (s2 - s1)/(r2 - r1)
    
    precewise_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            for k in range(image.shape[2]):
                if r1 <= image[i, j, k] <= r2:
                    precewise_img[i, j, k] = k2*(image[i, j, k] - r1)
                elif image[i, j, k] < r1:
                    precewise_img[i, j, k] = k1*gray_img[i, j, k]
                elif image[i, j, k] > r2:
                    precewise_img[i, j, k] = k3*(gray_img[i, j, k] - r2)
    
    #原图中做分段线性变化后需要对图像进行归一化操作,并将数据类型转换到np.uint8
    cv2.normalize(precewise_img, precewise_img, 0, 255, cv2.NORM_MINMAX)
    precewise_img = cv2.convertScaleAbs(precewise_img)
    
    cv2.imshow('origin image', imutils.resize(image, 480))
    cv2.imshow('precewise image', imutils.resize(precewise_img, 480))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    花粉原图和经过对比度拉伸后的图像效果如下:
    在这里插入图片描述



    (2) 阈值处理实例演示

    import cv2
    import imutils
    import numpy as np
    
    image = cv2.imread('E:/peking_rw/ocr_project/base_prehandle/img/pollen.jpg')
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    #阈值处理函数:当r1=r2, s1=0, s2=L-1时,此时分段线性函数便是阈值处理函数
    plist = []
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            plist.append(gray_img[i, j])
    r_avg = int(sum(plist)/len(plist))
    thresh_img = np.zeros((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            if gray_img[i, j] < r_avg:
                thresh_img[i, j] = 0
            else:
                thresh_img[i, j] = 255
    
    cv2.imshow('origin image', imutils.resize(image, 480))
    cv2.imshow('thresh image', imutils.resize(thresh_img, 480))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    经过阈值处理后的花粉图像如下所示:



    2.2 分段线性变换应用之灰度级分层

    为了在数字图像中突出我们感兴趣的灰度级区域 [A,B],在实际情况下可以有两种处理方式,对应下图:

    • 突出灰度范围在 [A,B] 的区域,将其他区域灰度级降低到一个更低的级别
    • 突出灰度范围在 [A,B] 的区域,其他区域保持原灰度级不变

    在这里插入图片描述

    上示例代码(下面展示的是:其他区域保持原灰度级不变的情况)

    import cv2
    import imutils
    import numpy as np
    
    #在某一范围(A, B)突出灰度,其他灰度值保持不变
    image = cv2.imread('E:/peking_rw/ocr_project/base_prehandle/img/kidney.jpg')
    gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    r_left, r_right = 150, 230
    r_min, r_max = 0, 255
    level_img = np.zeros((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
    for i in range(gray_img.shape[0]):
        for j in range(gray_img.shape[1]):
            if r_left <= gray_img[i, j] <= r_right:
                level_img[i, j] = r_max
            else:
                level_img[i, j] = gray_img[i, j]
                
    cv2.imshow('origin image', imutils.resize(image, 480))
    cv2.imshow('level image', imutils.resize(level_img, 480))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    原图和效果图如下所示:
    在这里插入图片描述




    3、对数变换

    对数变换将图像的低灰度值部分扩展,将其高灰度值部分压缩,以达到强调图像低灰度部分的目的;同时可以很好的压缩像素值变化较大的图像的动态范围,目的是突出我们需要的细节。反对数变换则与对数函数不同的是,强调的是图像的高灰度部分,对数变换公式如下:

    下面示例将演示对数变换:

    import cv2
    import imutils
    import numpy as np
    
    image = cv2.imread('E:/peking_rw/ocr_project/base_prehandle/img/DFT_no_log.jpg')
    log_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            log_img[i, j, 0] = math.log(1 + image[i, j, 0])
            log_img[i, j, 1] = math.log(1 + image[i, j, 1])
            log_img[i, j, 2] = math.log(1 + image[i, j, 2])
    cv2.normalize(log_img, log_img, 0, 255, cv2.NORM_MINMAX)
    log_img = cv2.convertScaleAbs(log_img)
    cv2.imshow('image', imutils.resize(image, 400))
    cv2.imshow('log transform', imutils.resize(log_img, 400))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    傅里叶频谱和经过对数变换增强后的频谱图像
    在这里插入图片描述




    4、幂律变换

    幂律变换主要用于图像的校正,对漂白的图片或者是过黑的图片进行修正,幂律变换的公式如下:

    根据 φ 的大小,主要可分为一下两种情况:

    • φ > 1: 处理漂白的图片,进行灰度级压缩
    • φ < 1: 处理过黑的图片,对比度增强,使得细节看的更加清楚

    4.1 当φ > 1时示例如下:

    #幂律变换 φ>1
    image = cv2.imread('E:/peking_rw/ocr_project/base_prehandle/img/aerial.jpg')
    gamma_img1 = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            gamma_img1[i, j, 0] = math.pow(image[i, j, 0], 5)
            gamma_img1[i, j, 1] = math.pow(image[i, j, 1], 5)
            gamma_img1[i, j, 2] = math.pow(image[i, j, 2], 5)
    cv2.normalize(gamma_img1, gamma_img1, 0, 255, cv2.NORM_MINMAX)
    gamma_img1 = cv2.convertScaleAbs(gamma_img1)
    cv2.imshow('image', imutils.resize(image, 400))
    cv2.imshow('gamma1 transform', imutils.resize(gamma_img1, 400))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    漂白图片和经过幂律变换后图像对比效果:
    在这里插入图片描述


    4.2 当φ< 1时示例如下:

    #幂律变换,φ<1
    image = cv2.imread('E:/peking_rw/ocr_project/base_prehandle/img/fractured_spine.jpg')
    gamma_img2 = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            gamma_img2[i, j, 0] = math.pow(image[i, j, 0], 0.4)
            gamma_img2[i, j, 1] = math.pow(image[i, j, 1], 0.4)
            gamma_img2[i, j, 2] = math.pow(image[i, j, 2], 0.4)
    cv2.normalize(gamma_img2, gamma_img2, 0, 255, cv2.NORM_MINMAX)
    gamma_img2 = cv2.convertScaleAbs(gamma_img2)
    cv2.imshow('image', imutils.resize(image, 400))
    cv2.imshow('gamma2 transform', imutils.resize(gamma_img2, 400))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    过黑图片和经过幂律变换后效果展示图:
    在这里插入图片描述





    三、直方图均衡化


    说在前面: 数字图像直方图均衡化目的就是提升图像的对比度,将较亮或者较暗区域的输入像素映射到整个区域的输出像素,是图像增强一种很好的且方便的方式,因此单独列为一节进行讲解



    1、认识图像的直方图

    图像直方图:反应图像强度分布的总体概念,宽泛的来说直方图给出了图像对比度、亮度和强度分布信息。下面从理论的角度阐述一下图像直方图的公式定义

    对于灰度级范围为[0,L-1]的数字图像的直方图是离散函数:

    其中 rk 是第k级灰度值,nk 便是图像中灰度为 rk 的像素个数。当然如果数字图像长宽维度为MN,则对直方图归一化之后的公式为:

    下面我们先从直观的角度来感受一下不同图像对应的直方图的区别,这对后续直方图均衡化增强图像理解有很大的帮助

    在这里插入图片描述


    从上图中我们注意到: 在暗图像中,直方图的分布都集中在灰度级的低(暗)端; 亮图像直方图的分布集中在灰度级的高端;低对比度图像具有较窄的直方图,且都集中在灰度级的中部;而高对比度的图像直方图的分量覆盖了很宽的灰度范围,且像素分布也相对均匀,此时图片的效果也相对很不错。于是我们可以得出结论:若一幅图像的像素倾向于占据整个可能的灰度级并且分布均匀,则该图像有较高的对比度并且图像展示效果会相对好,于是便引出图像直方图均衡化,对图像会有很强的增强效果



    2、图像增强之直方图均衡化

    这里不详细介绍直方图均衡化原理,想了解请看博客: 直方图均衡化原理

    下面给出直方图均衡化的实现:

    import cv2
    import imutils
    import numpy as np
    import matplotlib.pyplot as plt
    
    wiki_img = cv2.imread('E:/peking_rw/ocr_project/base_prehandle/img/wiki.jpg')
    wiki_gray = cv2.cvtColor(wiki_img, cv2.COLOR_BGR2GRAY)
    
    #对图像进行均衡化处理,增强图像对比度
    wiki_equ = cv2.equalizeHist(wiki_gray)
    
    hist = cv2.calcHist([wiki_gray], [0], None, [256], [0, 256])
    equ_hist = cv2.calcHist([wiki_equ], [0], None, [256], [0, 256])
    fig = plt.figure()
    ax1 = fig.add_subplot(1, 2, 1)
    ax1.plot(hist)
    ax2 = fig.add_subplot(1, 2, 2)
    ax2.plot(equ_hist)
    plt.show()
    
    cv2.imshow('wiki_origin', imutils.resize(wiki_img, 400))
    cv2.imshow('wiki_gray', imutils.resize(wiki_gray, 400))
    cv2.imshow('wiki_equ', imutils.resize(wiki_equ, 400))
    if cv2.waitKey(0) == 27:
        cv2.destroyAllWindows()
    

    直方图均衡化斥候:直方图前后对比图、图像前后对比图
    在这里插入图片描述





    四、总结



    不总结了,本篇分享到此结束,码字码到眼睛疼,如果诸位看管觉得还可以帮忙点个赞,后续将持续更新数字图像处理和分析等操作,也欢迎关注博主微信公众号

    在这里插入图片描述

    展开全文
  • 幂律变换的基本形式为:,其中和是常数 有时考虑到偏移量,上式也写为。然而,偏移量是一般显示标定问题,因而作为一个结果,通常在上式中忽略不计。 与对数变换情况类似,部分值得幂律曲线将较窄范围的暗色值,...

    幂律变换的基本形式为:s=cr^{\gamma },其中c\gamma是常数

    有时考虑到偏移量,上式也写为s=c(r+\varepsilon )^{\gamma }。然而,偏移量是一般显示标定问题,因而作为一个结果,通常在上式中忽略不计。

    与对数变换情况类似,部分\gamma值得幂律曲线将较窄范围的暗色值,映射位较宽的目标输出值,相反,对于输入高灰度级值时也成立。

    \gamma>1的值所生成的曲线和\gamma<1所生成的曲线的效果完全相反,当c=\gamma=1时简化为了恒等变换。

    下面使用Python实现幂律变换:

    使用的图片数据为:

     导入要使用的第三方库:

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

     读取图片数据,并可视化:

    img = Image.open('小亮点.jpg')
    plt.axis('off')
    plt.imshow(img)
    plt.show()

     图像数据转换为numpy数组:

    img_data = np.array(img)

     定义幂律变换函数:

    def power_law_rollovers(img, func, c, b):
        img_data = np.array(img)
        a = np.shape(img_data)
        new_img = []
        for i in range(a[0]):
            new_row = []
            for j in range(a[1]):
                data = list(img_data[i][j])
                new_data = func(data, c, b)
                new_row.append(np.array(new_data))
            new_img.append(np.array(new_row))
        return new_img
    def power_law(data, c, b):
        new_data = []
        for k in data:
            a = int(c*(k**b))
            new_data.append(a)
        return new_data

     结果:

    共生成4张图片,参数c=1,参数\gamma分别等于0.8,0.6,0.4,0.3

    new_img1 = power_law_rollovers(img, power_law, 1, 0.8)
    new_img2 = power_law_rollovers(img, power_law, 1, 0.6)
    new_img3 = power_law_rollovers(img, power_law, 1, 0.4)
    new_img4 = power_law_rollovers(img, power_law, 1, 0.3)
    
    new_img1 = np.array(new_img1)
    new_img2 = np.array(new_img2)
    new_img3 = np.array(new_img3)
    new_img4 = np.array(new_img4)
    
    new_img1 = Image.fromarray(new_img1.astype('uint8')).convert('RGB')
    new_img2 = Image.fromarray(new_img2.astype('uint8')).convert('RGB')
    new_img3 = Image.fromarray(new_img3.astype('uint8')).convert('RGB')
    new_img4 = Image.fromarray(new_img4.astype('uint8')).convert('RGB')
    
    plt.figure(figsize=(25,60))
    plt.subplot(221)
    plt.axis('off')
    gray1 = new_img1.convert('L')
    plt.imshow(gray1, cmap='gray')
    plt.subplot(222)
    plt.axis('off')
    gray2 = new_img2.convert('L')
    plt.imshow(gray2, cmap='gray')
    plt.subplot(223)
    plt.axis('off')
    gray3 = new_img3.convert('L')
    plt.imshow(gray3, cmap='gray')
    plt.subplot(224)
    plt.axis('off')
    gray4 = new_img4.convert('L')
    plt.imshow(gray4, cmap='gray')
    plt.show()

     

     

    展开全文
  • 文章目录变换核磁共振图像代码实现遇到问题附代码: 变换 变换,点运算的一种,运算公式为s=crγ,其中,c和γ是正常数。 当γ<1,此时扩展低灰度级,压缩高灰度级,在正比函数上方,使图像变亮; 当...
  • 对数变换: CImg&lt;int&gt; SrcImg; SrcImg.load_tiff("E:/Desktop/picture_process/Lenna/3/Fig0305(a)(DFT_no_log).tif"); SrcImg.display(); cimg_forXY(SrcImg, x, y) { SrcImg(x, y) = int...
  • // 对比度增强.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include #include using namespace cv;...using namespace std;...//rows cols type 目标图像的行,列,以
  • C++数字图像处理(1)-伽马变换

    千次阅读 2020-03-08 11:49:01
    1、算法原理 伽马变换(幂律变换)是常用的灰度变换,是一种简单的图像增强算法。数学公式如下:(1) 式(1)中,r为输入的灰度值,取值范围为[0, 1]。C称为灰度缩放系数,用于整体拉伸图像灰度,通常取值为1。...
  • 彩色图像的增强处理在许多可携带设备中都是一个非常重要的过程,包括像平板、数字相机和智能手机等。但是,考虑到便携设备有限的存储容量和较低的计算能力,提高处理过程中的计算效率就成为了一个优先解决问题。这篇...
  • 数字图像处理--------灰度变换

    千次阅读 2020-07-10 20:45:31
    对于数字图像处理而言,一般包含着空间域处理和变换域处理两种形式。空间域处理方法主要是直接以图像中的像素操作为基础,它主要分为灰度变换和空间滤波两类。灰度变换是在图像的单个像素上操作,主要以对比度和阈值...
  • 数字图像处理期中学习报告

    千次阅读 2018-09-07 19:26:28
    数字图像处理数字图像处理 一学习内容总结 第一章 绪论 1 什么是数字图像处理 2 使用数字图像处理领域的实例 3 数字图像处理的基本步骤 4 图像处理系统的组成 第二章 数字图像处理基础 1 视觉感知要素 2 光和电磁...
  • 数字图像处理冥次变换

    千次阅读 2016-10-10 14:19:28
    灰度是指使用黑色调表示物体,用黑色为基准色,不同的饱和度的黑色来显示图像,灰度共有256级 灰度色,就是指纯白、纯黑以及两者中的一系列从黑到白的过渡色 如把有黑-灰-白连续变化的灰度值量化为256个灰度级...
  • 本章主要讲的是空间域的操作(即图像本身) 本章主要讨论形如g(x,y)=T[f(x,y)]g(x,y) = T[f(x,y)]g(x,y)=T[f(x,y)]的灰度变换和空间滤波 上面的公式也可以写成更一般的形式s=T(r)s = T(r)s=T(r) s、rs、rs、r分别...
  • FPGA与数字图像处理技术

    千次阅读 2017-09-17 09:01:18
    数字图像处理方法的重要性源于两个主要应用领域: 改善图像信息以便解释。 为存储、传输和表示而对图像数据进行处理,以便于机器自动理解。 图像处理(image processing): 用计算机对图像...
  • 目录背景知识灰度变换和空间滤波基础一些基本的灰度变换函数图像反转对数变换幂律(伽马)变换分段线性变换函数对比度拉伸灰度级分层比特平面分层直方图处理直方图均衡空间滤波基础空间滤波机理空间相关与卷积相关...
  • 图像处理分为空间域和变换域(在图像的傅里叶变换上进行处理),空间域是指图像平面本身,主要是直接以图像中的像素操作为基础进行图像处理,空间域的处理主要分为灰度变换和空间滤波两类,本文主要介绍灰度变换在...
  • 数字图像处理之灰度变换

    千次阅读 2017-06-25 10:31:34
    灰度变换图像处理技术中的最简单的技术。 图像增强常用的三类基本函数: 1. 线性函数(反转和恒等变换) 2. 对数函数(对数和反对数变换) 3. 幂律函数(n次幂和n次根变换)基本灰度变换函数如图: 直方图...
  • 数字图像处理-空间与处理-灰度变换-基本灰度变换函数(求反、线性灰度变换、换、对数变换、伽马变换、阈值化/二值化) [Python图像处理] 十五.图像的灰度线性变换 图像增强:线性、 分段线性、 对数、 反对数、 幂律...
  • 数字图像处理之亮度变换 by方阳 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/6557603.html 第二篇博客,为自己加油加油!! 今天写一点亮度变换的东西;亮度变换...
1 2 3 4 5 ... 15
收藏数 294
精华内容 117
关键字:

幂律变换 数字图像处理