美文网首页OpenCV
OpenCV-Python教程:7.图片上的基本操作

OpenCV-Python教程:7.图片上的基本操作

作者: xxxss | 来源:发表于2017-06-15 14:13 被阅读396次

    ·访问像素值并修改它们
    ·访问图片属性
    ·设置ROI
    ·分割和合并图片

    基本上本节所有的操作都是和Numpy相关的而不是OpenCV

    访问和修改像素值

    让我们加载一张彩色图片:

    >>>import cv2
    >>>import numpy as np
    >>>img = cv2.imread('messi5.jpg')

    你可以通过行和列坐标访问一个像素值。对于BGR图片,它会返回一个蓝,绿,红值的数组。对于灰度图片,只会返回对应的深度。

    >>>px = img[100,100]
    >>>print px[157 166 200]

    # accessing only blue pixel
    >>>blue = img[100,100,0]
    >>>print blue
    157

    你可以修改这个像素值:

    >>>img[100,100] = [255,255,255]
    >>>print img[100,100]
    [255 255 255]

    警告:
    Numpy是一个优化的库,能够快速计算数组。所以如果一个个访问每个像素并修改它的值是很慢的,也不推荐

    注意:
    一般来说,都是选择数组的一片区域,比如头5行或者最后三列。对于某个像素点的访问,Numpy数组方法,array.item() 和array.itemset()更好。但是它总是返回标量。所以如果你想访问所有的B, G, R值,你需要分开调用array.item()

    更好的访问和编辑方式:

    # accessing RED value
    >>>img.item(10,10,2)
    59

    # modifying RED value
    >>>img.itemset((10,10,2), 100)
    >>>img.item(10,10,2)
    100

    访问图片属性

    图片属性包括行数,列数,通道数,图片数据类型,像素数等。

    图片的形状可以通过img.shape获得,它会放回一个包含行数,列数的通道数的元组(如果图片是彩色的):

    >>>print img.shape
    (342, 548, 3)

    注意:
    如果图片是灰度的,返回的元组只包含行数和列数。所以检查是否加载的图片是灰度的还是彩色的可以通过这个来做

    所有的像素数可以通过img.size来访问:

    >>>print img.size
    562248

    图片数据类型可以通过img.dtype获得:

    >>>print img.dtype
    uint8

    注意:
    img.dtype在调试的时候很重要,因为大量OpenCV-Python代码里的错误都是有错误的数据类型导致的。

    图片ROI

    有时候,你会需要处理图片的特定区域。对于图片的眼部识别,首先对整个图片进行面部识别,找到脸以后,在脸的区域内找眼睛。这个方法能够提高准确度(因为眼睛总是在脸上的:D)性能上也好(因为我们找的区域更小)

    ROI是通过Numpy的索引来获得的,这里我们选择球,然后把它复制到图片的另一个区域:

    >>>ball = img[280:340,330:390]
    >>>img[273:333,100:160] = ball

    分割和合并图片


    图片的B, G, R通道可以被分割成他们各自的片,各个通道可以被合并成BGR图片。

    >>>b,g,r = cv2.split(img)
    >>>img=cv2.merge((b,g,r))

    或者

    >>>b = img[:,:,0]

    假设你想把所有的红色像素变成0,你不用这么分割,你可以简单的使用Numpy索引,这样更快

    >>>img[:,:,2]=0

    警告:
    cv2.split()是一个成本很高的操作(执行时间),所以只在必要的时候使用。Numpy索引要更有效率,能用就用。

    制作图片的边框

    如果你想要在图片周围生成边框,类似于相框,你可以使用cv2.copyMakeBorder()函数。但是它还能用于卷积,0内边距等。这个函数有下面这些参数:

    ·src - 输入图片
    ·top, bottom, left, right - 各个方向的边框像素宽度
    ·borderType - 标志位,定义要加什么样的边框,可以是下列类型:
            ·cv2.BORDER_CONSTANT - 添加固定的彩色边。值需要在后面的参数提供。
            ·cv2.BORDER_REFLECT - 边框是镜像的,像这样:fedcba/abcdefgh/hgfedcb
            ·cv2.BORDER_REFLECT_101或cv2.BORDER_DEFAULT - 和上面一样,但是有点变化,像这样:gfedcb/abcdefgh/gfedcba
            ·cv2.BORDER_REPLICATE - 最后的元素是重复的,像这样:aaaaaa/abcdefgh/hhhhhhh
            ·cv2.BORDER_WRAP - 没法解释,看上去是这样: cdefgh/abcdefgh/abcdefg

    ·value - 如果边的类型是cv2.BORDER_CONSTANT 这个值就是边的颜色。

    下面是个列子,展示了所有这些边框的类型:

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

    BLUE = [255,0,0]

    img1 = cv2.imread('opencv_logo.png')

    replicate = cv2.copyMakeBorder(img1,10,10,10,10, cv2.BORDER_REPLICATE)
    reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
    reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
    wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
    constant=cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)

    plt.subplot(231),plt.imshow(img1,'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('REFLECT_101')
    plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
    plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')

    plt.show()

    END

    相关文章

      网友评论

        本文标题:OpenCV-Python教程:7.图片上的基本操作

        本文链接:https://www.haomeiwen.com/subject/okoxjttx.html