• python计算机视觉1:基本操作与直方图



    本文主要内容来源于书籍《python计算机视觉编程》
    我是一名初学者,如果你发现文中有错误,请留言告诉我,谢谢


     PIL模块 

    PIL模块全程为Python Imaging Library,是python中一个免费的图像处理模块。


     打开图像 

    PIL模块常用到它的Image类,打开图像首先要导入Image类
    from PIL import Image
    然后调用Imageopen方法。
    例如

    from PIL import Image
    
    image = Image.open("smallpi.jpg") # 返回一个Image图像对象
    print(image)
    # 结果
    <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=800x450 at 0x4731348>
     

     图像的保存及格式转换 

    图像保存用的是Image对象的save()方法,传入的参数为保存图像文件的名字。
    当传入不同的扩展名时,它会根据扩展名自动转换图像的格式。
    例如

    from PIL import Image
    
    image = Image.open("smallpi.jpg") # 打开jpg图像文件
    image.save("smallpi.png") # 保存图像,并转换成png格式
     

     

     转化成灰度图像 

    获得Image对象后,调用其convert()方法,传入参数"L",即可以返回该图像的灰度图像对象。

    from PIL import Image
    
    image = Image.open("smallpi.jpg")
    
    image_gray = image.convert("L") # 转化成灰度图像
    print(image_gray)
    # 结果
    <PIL.Image.Image image mode=L size=800x450 at 0x46AD648>

     Image对象与图像矩阵相互转化 

     Image对象转化成图像矩阵 

    Image对象转化成图像矩阵只要将Image对象作为numpy.array()参数即可。

    import numpy as np
    from PIL import Image
    
    image = Image.open("smallpi.jpg")
    image_array = np.array(image)
    print(image_array)
    # 结果
    [[[177 177 177]
      [177 177 177]
      [176 176 176]
      ..., 
      #此处省略
      ...,
      [232 232 232]
      [232 232 232]
      [232 232 232]]]

     图像矩阵转化成Image对象 

    图像矩阵转化成Image对象通过Image模块的fromarray()方法。

    import numpy as np
    from PIL import Image
    
    image = Image.open("smallpi.jpg")
    image_array = np.array(image.convert("L"))
    image_array = 255 - image_array # 图像矩阵处理,将灰度图像反相
                                    # 反相指的是,黑变白,白变黑
    image2 = Image.fromarray(image_array)
    print(image2)
    # 结果
    <PIL.Image.Image image mode=RGB size=800x450 at 0x4753748>

     

     图像的显示 

    图像的显示需要用到matplotlib模块。
    首先需要导入matplotlib.pyplot
    import matplotlib.pyplot as plt
    然后,调用pyplot的imshow()方法,传入Image对象即可

    from PIL import Image
    import matplotlib.pyplot as plt
    
    image = Image.open("smallpi.jpg")
    plt.imshow(image) # 绘制图像image
    plt.show() # 需要调用show()方法,不然图像只会在内存中而不显示出来

      

    图像显示结果(带坐标轴)

    如果想把坐标轴去掉只需要调用pyplot的axis()方法,传入"off"参数

    from PIL import Image
    import matplotlib.pyplot as plt
    
    image = Image.open("smallpi.jpg")
    plt.imshow(image) # 绘制图像image
    plt.axis("off") # 去掉坐标轴
    plt.show() # 需要调用show()方法,不然图像只会在内存中而不显示出来 

    图像显示结果(不带坐标轴)

    如果要显示灰度图像,需要导入matplotlib的cm模块
    import matplotlib.cm as cm
    然后在调用pyplot.show()时,传入关键字参数cmap=cm.gray

    from PIL import Image            
    import matplotlib.pyplot as plt
    import matplotlib.cm as cm         
    
    image = Image.open("smallpi.jpg") # 打开图像
    image_gray = image.convert("L") # 转化成灰度图像
    
    plt.subplot(2,1,1)
    plt.imshow(image_gray) # 没传入关键字参数cmap=cm.gray
    plt.axis("off") # 去掉坐标轴
    
    plt.subplot(2,1,2)
    plt.imshow(image_gray, cmap=cm.gray) # 指明 cmap=cm.gray
    plt.axis("off") # 去掉坐标轴
    
    plt.show() # 显示图像 

    显示结果
    上:没指定cmap , 下:指定cmap=cm.gray


     创建缩略图 

    创建图像缩略图可以通过Image的thumbnail()方法,参数传入一个元组,指明缩略图的大小,如thumbnail((128,128))
    例如

    from PIL import Image
    
    image = Image.open("smallpi.jpg")
    image_thumbnail = image.thumbnail((128,128))
    
    image.save("thumbnail.jpg") 

    结果为


     复制和粘贴区域 

    复制区域是指截取图像中的一部分,并将这一部分作为一个新的Image对象。
    复制区域的方法为crop(),参数为一个含4个元素的元组,用来指定截取区域的左上角点和右下角点。

    from PIL import Image
    
    image = Image.open("smallpi.jpg") # 打开图像
    box = (300,100,500,300) # 截取区域
    image_crop = image.crop(box) # 按指定截取区域对图像进行截取复制
    
    image_crop.save("image_crop.jpg") # 保存

    保存的截取区域图像为

    粘贴区域是指在指定图像中放入另一个图像,其方法为paste()。该方法有两个参数,第一个参数为需要粘贴进去的图像,第二个参数为粘贴区域。

    from PIL import Image
    
    image = Image.open("smallpi.jpg")
    box = (300,100,500,300)        # 先截取一部分
    image_crop = image.crop(box)    
    
    # 为了看到粘贴效果,现将截取部分转180度
    image_crop = image_crop.transpose(Image.ROTATE_180) # 转180度
    image.paste(image_crop,box) # 将转180度后的图像粘贴到原图像
    
    image.save("image_paste.jpg")
    粘贴后原图像变成 


     图像的尺寸调整和旋转 

    尺寸调整方法为resize(),参数为一元组,指定调整后的大小,如resize((128,128))。
    图像旋转的方法为
    rotate(),参数为旋转角度(数值,单位为度),逆时针方向,如rotate(45)`

    from PIL import Image
    
    image = Image.open("smallpi.jpg")
    
    image_resize = image.resize((200,200)) # 尺寸调整
    image_rotate = image.rotate(45) # 图像旋转
    # image.transpose()也可以旋转图像,但只能旋转90度的整数倍
    # 参数为 Image.ROTATE_90 旋转90度
    # 180度,270度可类推
    
    image_resize.save("image_resize.jpg")
    image_rotate.save("image_rotate.jpg")

    尺寸调整为200*200

    图像逆时针旋转45度


     图像直方图 

    图像直方图用来统计图像中像素值的分布情况,即统计不同像素值出现的次数。方法为调用matplotlib.pyplothist方法,参数传入图像像素序列和统计区间个数。

    from PIL import Image
    import matplotlib.pyplot as plt
    import matplotlib.cm as cm
    
    #打开图像,并转化成灰度图像
    image = Image.open("smallpi.jpg").convert("L") 
    image_array = np.array(image)
    
    plt.subplot(2,1,1)
    plt.imshow(image,cmap=cm.gray)
    plt.axis("off")
    plt.subplot(2,1,2)
    plt.hist(image_array.flatten(),256) #flatten可以将矩阵转化成一维序列
    plt.show()

    结果为


     灰度变换 

    对于一张灰度图像,其每个像素点都用一个0-255之间的值表示,0表示黑色,越接近0越黑;255表示白色,越接近255越白。
    灰度变换就是通过一个特定的函数,使灰度值从一个值转换成另外一个值。
    这里列出3种灰度变换

    1. 【反相】= 255

    2.【转换到100-200】变换后的灰度值 =(原灰度值/255)*100+100

    3. 【像素平方】变换后的灰度值 = 255*(原灰度值/255)2

    2

    from PIL import Image
    import matplotlib.pyplot as plt
    import matplotlib.cm as cm
    
    image = Image.open("smallpi.jpg").convert("L")
    image_array = np.array(image)
    
    x = np.arange(255)
    
    # 反相
    plt.subplot(3,2,1)
    plt.plot(x,255-x) # 画出变换函数图像
    plt.subplot(3,2,2)
    plt.imshow(Image.fromarray(255-image_array),cmap=cm.gray)
    plt.axis("off")
    
    # 转换到 100-200
    plt.subplot(3,2,3)
    plt.plot(x,(x/255.0)*100+100) # 画出变换函数图像
    plt.subplot(3,2,4)
    plt.imshow( Image.fromarray((image_array/255.0)*100+100), cmap=cm.gray )
    plt.axis("off")
    
    # 像素平方
    plt.subplot(3,2,5)
    plt.plot(x,255*(x/255.0)**2) # 画出变换函数图像
    plt.subplot(3,2,6)
    plt.imshow( Image.fromarray(255*(image_array/255.0)**2), cmap=cm.gray )
    plt.axis("off")
    
    plt.show()

      

    `结果如下,(左边是变换函数,右边是图像变换结果)


     直方图均衡化 

    由上面图像的直方图可以看出,一般情况下,图像上某些灰度值较多,有些灰度值较少,直方图均衡化为的是使灰度值较为均衡。

    直方图均衡化是利用直方图的累积函数作为灰度变换函数,对图像进行转换。直方图均衡化可以增强图像的对比度。

    累积函数和概率论中的累积分布函数类似。例如对于还有5个数的序列[1,2,3,4,5],其累积函数含有5个数,第一个数是1,第二个是1+2=3,……,第五个数是1+2+3+4+5=15,所以其累积函数是[1,3,6,10,15]。

    我们把直方图均衡化的过程封装在一个函数里面,函数名字叫做histeq,输入原图像矩阵和直方图分块数,输出均衡化后的图像矩阵和累积函数。

    import numpy as np 
    from PIL import Image
    import matplotlib.pyplot as plt
    import matplotlib.cm as cm
    
    def histeq(image_array,image_bins=256):
        
        # 将图像矩阵转化成直方图数据,返回元组(频数,直方图区间坐标)
        image_array2,bins = np.histogram(image_array.flatten(),image_bins)
    
        # 计算直方图的累积函数
        cdf = image_array2.cumsum()
    
        # 将累积函数转化到区间[0,255]
        cdf = (255.0/cdf[-1])*cdf
        
        # 原图像矩阵利用累积函数进行转化,插值过程
        image2_array = np.interp(image_array.flatten(),bins[:-1],cdf)
    
        # 返回均衡化后的图像矩阵和累积函数
        return image2_array.reshape(image_array.shape),cdf
    
    
    
    image = Image.open("pika.jpg").convert("L") 
    image_array = np.array(image)
    plt.subplot(2,2,1)
    plt.hist(image_array.flatten(),256)
    plt.subplot(2,2,2)
    plt.imshow(image,cmap=cm.gray)
    plt.axis("off")
    
    a = histeq(image_array)  # 利用刚定义的直方图均衡化函数对图像进行均衡化处理
    plt.subplot(2,2,3)
    plt.hist(a[0].flatten(),256)
    plt.subplot(2,2,4)
    plt.imshow(Image.fromarray(a[0]),cmap=cm.gray)
    plt.axis("off")
    
    plt.show()

     结果如下图所示,第一行为原图像直方图和原图像,第二行为均衡化后的直方图和图像。可以看出均衡化后图像对比度增强了,原先灰色区域的细节变得清晰。

  • 相关阅读:
    Ajax基本案例详解之$.getjson的实现
    Ajax基本案例详解之$.getjson的实现
    Ajax传递json数据
    Ajax传递json数据
    Ajax基本案例详解之load的实现
    多节点日志数据 数据集成
    crontab 问题分析
    不留文档的某某离开后 审计服务器操作历史
    /cloudmonitor.log 主机监控
    网关会对开发者的接口非业务调用错误做统一处理
  • 原文地址:https://www.cnblogs.com/smallpi/p/4550360.html
Copyright © 2020-2023  润新知