• opencv-python教程学习系列7-opencv图像基本操作


    前言

    opencv-python教程学习系列记录学习python-opencv过程的点滴,本文主要介绍图像的基本操作,坚持学习,共同进步。

    系列教程参照OpenCV-Python中文教程

    系统环境

    系统:win7_x64;

    python版本:python3.5.2;

    opencv版本:opencv3.3.1;

    内容安排

    1.知识点介绍;

    2.测试代码;

    具体内容

    1.知识点介绍;

    使用的库包含cv2、numpy和matplotlib,包含修改图像像素、获取图像属性、提取ROI、拆分合并通道、图像填充等内容;

    1.1 获取并修改图像像素;

    1)读取一副图像,根据像素的行和列的坐标获取它的像素值,返回RGB的值,灰度图则返回灰度值;图像中的坐标是从0开始计数的。

    px=img[100,100]#某坐标对应的像素值
    print(px)
    blue = img[100,100,0]#数字0表示选择BGR通道
    print(blue)
    img[101,101]=[235,255,255]
    print(img[101,101])

    2)numpy是经过优化了的进行快速矩阵运算的包,不推荐逐个获取像素值并修改,能矩阵运算就不要用循环。
    建议使用numpy的array.item()和array.itemset()函数。但是返回是标量,如果想获得所有RGB的值,需要使用array.item()分割他们。

    #numpy
    print(img[10, 10])
    print(img.item(10,10,2))
    img.itemset((10,10,2),100)
    print(img.item(10,10,2))
    

    1.2 获取图像属性,包括行、列、通道数目、图像数据类型、像素数目等;

    image.shape - 获取图像的形状,返回值是一个包含行数/列数/通道数的元组,如果图像是灰度图,返回值仅有行数和列数,

    可通过检查返回值可以判断是灰度图还是彩色图;

    image.size - 获取图像的像素数目;

    img.dtype - 图像的数据类型,在debug时很重要,因为OpenCV-Python代码中经常出现数据类型的不一致;

    print(img.dtype)
    

    1.3 图像ROI,对图像的特定区域操作。ROI是使用numpy索引来获得的。要先知道图像尺寸,以及要移动的图像的像素坐标,可以使用matplotlib!!

    ball =img[300:350,230:300]
    

    1.4 拆分及合并图像通道,cv2.split()是比较耗时的操作,能用numpy就尽量使用。

    r,g,b=cv2.split(img)#拆分
    img=cv2.merge([r,g,b])#合并
    b=img[:,:,0]#拆分b通道
    img[:,:,2]=0#使用numpy索引使所有红色通道值都为0
    

    1.5 图像扩边(填充),使用cv2.copyMakeBorder()函数。这经常在卷积运算或0填充时被用到;

    具体的参数有输入图像、上下左右对应边界的像素数目、边界类型;

    cv2.BORDER_CONSTANT添加有颜色的常数值边界,还需要下一个参数(value);
    cv2.BORDER_REFLIECT边界元素的镜像。例如:fedcba | abcdefgh | hgfedcb;
    cv2.BORDER_101或者cv2.BORDER_DEFAULT跟上面一样,但稍作改动,例如:gfedcb | abcdefgh | gfedcba;
    cv2.BORDER_REPLICATE复后一个元素。例如: aaaaaa| abcdefgh|hhhhhhh;
    cv2.BORDER_WRAP 不知怎么了, 就像样: cdefgh| abcdefgh|abcdefg;
    value边界颜色;

    blue = [0,0,255]#分别表示RGB通道;
    constant = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_CONSTANT,value=blue)
    plt.subplot(236),plt.imshow(constant,'gray'),plt.title('constant')

    2.测试代码;

    import cv2
    import numpy
    img = cv2.imread('test.jpg')
    px=img[100,100]#某坐标对应的像素值
    print(px)
    blue = img[100,100,0]#0表示BGR通道数
    print(blue)
    img[101,101]=[235,255,255]
    print(img[101,101])
    
    #numpy
    print(img[10, 10])
    print(img.item(10,10,2))
    img.itemset((10,10,2),100)
    print(img.item(10,10,2))
    
    #获取图像属性(图像属性包括:行,列,通道,图像数据类型,像素数目等)
    print(img.shape)#img.shape可以获得图像的形状,返回值是一个包含行数/列数/通道数的元组
    #如果图像是灰度图,返回值仅有行数和列数,所以通过检查返回值可以判断是灰度图还是彩色图
    #img.size可以返回图像的像素数目
    print(img.size)
    #img.dtype返回图像的数据类型,在debug时很重要,因为OpenCV-Python代码中经常出现数据类型的不一致
    print(img.dtype)
    
    #图像ROI,对图像的特定区域操作。ROI是使用numpy索引来获得的。
    #要先知道图像尺寸,以及你要移动的图像的像素坐标,可以使用matplotlib!!
    ball =img[300:350,230:300]
    cv2.imshow('image',img)#显示图像
    img[500:550,300:370]=ball
    cv2.imshow('imageROI',img)#显示图像
    
    #拆分及合并图像通道,cv2.split()是比较耗时的操作,能用numpy就尽量使用。
    r,g,b=cv2.split(img)#拆分
    img=cv2.merge([r,g,b])#合并
    b=img[:,:,0]#拆分b通道
    img[:,:,2]=0#使用numpy索引使所有红色通道值都为0
    
    #图像扩边(填充)
    #使用cv2.copyMakeBorder()函数。这经常在卷积运算或0填充时被用到;
    from matplotlib import pyplot as plt
    blue = [0,0,255]#分别表示RGB通道;
    replicate = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_REPLICATE)
    reflect = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_REFLECT)
    reflect101 = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_REFLECT101)
    wrap = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_WRAP)
    constant = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_CONSTANT,value=blue)
    
    plt.subplot(231),plt.imshow(img,'gray'),plt.title('original')
    plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('replicate')
    plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('reflect')
    plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('reflect101')
    plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('wrap')
    plt.subplot(236),plt.imshow(constant,'gray'),plt.title('constant')
    
    plt.show()
    

    测试结果显示

    参考

    1. opencv图像基本操作

  • 相关阅读:
    偷窃转基因玉米种子引发中美打农业官司
    关于PreferenceActivity的使用和一些问题的解决(自己定义Title和取值)
    大写中文数字-財务
    【leetcode】LRU
    【AC大牛陈鸿的ACM总结贴】【ID AekdyCoin】人家当初也一样是菜鸟
    android面试题 不单单为了面试也是一次非常好的学习
    存储系统的实现-探析存储的机制和原理
    unity3d脚本编程
    ubuntu12.04 安装配置jdk1.7
    Android中一个类实现的接口数不能超过七个
  • 原文地址:https://www.cnblogs.com/happyamyhope/p/8126030.html
Copyright © 2020-2023  润新知