• Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像


    前文传送门:

    「Python 图像处理 OpenCV (1):入门」

    普通操作

    1. 读取像素

    读取像素可以通过行坐标和列坐标来进行访问,灰度图像直接返回灰度值,彩色图像则返回B、G、R三个分量。

    需要注意的是, OpenCV 读取图像是 BGR 存储显示。

    灰度图片读取操作:

    import cv2 as cv
    
    # 灰度图像读取
    gray_img = cv.imread("maliao.jpg", cv.IMREAD_GRAYSCALE)
    print(gray_img[20, 30])
    
    # 显示图片
    cv.imshow("gray_img", gray_img)
    
    # 等待输入
    cv.waitKey()
    cv.destroyAllWindows()
    

    对于读取灰度图像的像素值,只会返回相应的灰度。

    彩色图像读取操作:

    import cv2 as cv
    
    # 彩色图像读取
    color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
    
    print(color_img[20, 30])
    
    blue = color_img[20, 30, 0]
    print(blue)
    
    green = color_img[20, 30, 1]
    print(green)
    
    red = color_img[20, 30, 2]
    print(red)
    
    # 显示图片
    cv.imshow("color_img", color_img)
    
    # 等待输入
    cv.waitKey()
    cv.destroyAllWindows()
    
    # 打印结果
    [  3   2 236]
    3
    2
    236
    

    需要注意的是在获取彩色图片像素时的第二个参数 1|2|3 的含义是获取 BGR 三个通道的像素。

    2. 修改像素

    修改像素时,直接对像素赋值新像素即可。

    如果是灰度图片,直接赋值即可。

    如果是彩色图片,则需依次给 BGR 三个通道的像素赋值。

    import cv2 as cv
    
    # 灰度图像读取
    gray_img = cv.imread("maliao.jpg", cv.IMREAD_GRAYSCALE)
    print(gray_img[20, 30])
    # 像素赋值
    gray_img[20, 30] = 255
    print(gray_img[20, 30])
    
    # 打印结果
    72
    255
    
    # 彩色图像读取
    color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
    print(color_img[20, 30])
    # 像素依次赋值
    color_img[20, 30, 0] = 255
    color_img[20, 30, 1] = 255
    color_img[20, 30, 2] = 255
    print(color_img[20, 30])
    
    # 打印结果
    [  3   2 236]
    [255 255 255]
    

    如果觉得依次对 BGR 三个通道赋值有些麻烦的话,也可以通过数组直接对像素点一次赋值:

    # 像素一次赋值
    color_img[20, 30] = [0, 0, 0]
    print(color_img[20, 30])
    
    # 打印结果
    [0 0 0]
    

    下面是对一个区域的像素进行赋值,将这个区域的像素全都赋值成为白色:

    import cv2 as cv
    
    color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
    color_img[50:100, 50:100] = [255, 255, 255]
    
    cv.imshow("color_img", color_img)
    cv.waitKey()
    cv.destroyAllWindows()
    

    使用 Numpy 操作

    1. 读取像素

    使用 Numpy 进行像素读取,调用方式如下:

    返回值 = 图像.item(位置参数)
    

    读取灰度图像和彩色图像如下:

    import cv2 as cv
    
    # 读取灰度图像
    gray_img = cv.imread("maliao.jpg", cv.IMREAD_GRAYSCALE)
    print(gray_img.item(20, 30))
    
    # 打印结果
    72
    
    # 读取彩色图像
    color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
    
    blue = color_img.item(20, 30, 0)
    print(blue)
    
    green = color_img.item(20, 30, 1)
    print(green)
    
    red = color_img.item(20, 30, 2)
    print(red)
    
    # 打印结果
    3
    2
    236
    

    2. 修改像素

    修改像素需要使用到 Numpy 的 itemset() 方法,调用方式如下:

    图像.itemset(位置, 新值)
    

    下面是我将 [20, 30] 这个修改为白色的示例:

    import cv2 as cv
    
    # 读取彩色图像
    color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
    
    print(color_img[20, 30])
    
    color_img.itemset((20, 30, 0), 255)
    color_img.itemset((20, 30, 1), 255)
    color_img.itemset((20, 30, 2), 255)
    
    print(color_img[20, 30])
    
    # 输出结果
    [  3   2 236]
    [255 255 255]
    

    注意:普通操作通常用于选择数组的区域,例如上面的示例中的选择了 [50:100, 50:100] 这么一个正方形。对于单个像素访问, Numpy 数组方法 array.item() 和 array.itemset() 被认为更好。

    Matplotlib 显示图像

    我们可以通过 OpenCV 读入图像,然后使用 Matplotlib 来进行图像显示。

    import cv2 as cv
    from matplotlib import pyplot as plt
    
    img=cv.imread('maliao.jpg', cv.IMREAD_COLOR)
    plt.imshow(img)
    plt.show()
    

    如果我们直接使用 Matplotlib 来显示 OpenCV 读入的图像,会得到下面这个蓝色的马里奥:

    这是因为对于 OpenCV 的像素是 BGR 顺序,然而 Matplotlib 所遵循的是 RGB 顺序。

    解决的方案有很多种(循环像素点的不算哈,这个太傻了),如下:

    import cv2 as cv
    from matplotlib import pyplot as plt
    
    img=cv.imread('maliao.jpg',cv.IMREAD_COLOR)
    
    # method1
    b,g,r=cv.split(img)
    img2=cv.merge([r,g,b])
    plt.imshow(img2)
    plt.show()
    
    # method2
    img3=img[:,:,::-1]
    plt.imshow(img3)
    plt.show()
    
    # method3
    img4=cv.cvtColor(img, cv.COLOR_BGR2RGB)
    plt.imshow(img4)
    plt.show()
    

    结果我就不贴了,这三种方法都可以完成 BGR 至 RGB 的转换。

    示例代码

    如果有需要获取源码的同学可以在公众号回复「OpenCV」进行获取。

    参考

    https://blog.csdn.net/eastmount/article/details/82120114

    http://woshicver.com/

  • 相关阅读:
    sessionId控制单点登陆
    验证码的编写
    关于selectpicker的多选问题
    java的excel表格的导出与下载
    SpringMVC的乱码问题
    乱码的解决问题
    layui select下拉框监听值变化 layui 下拉列表的change事件
    RabbitMQ在Ubuntu上的环境搭建
    JAVA中 redisTemplate 和 jedis的配合使用
    优化JAVA查询Mongodb数量过大,查询熟读慢的方法
  • 原文地址:https://www.cnblogs.com/babycomeon/p/12914957.html
Copyright © 2020-2023  润新知