Opencv图像基础操作

作者: 陨星落云 | 来源:发表于2019-07-08 22:53 被阅读1次

    图像基础操作

    1. 图像在numpy.ndarray中的结构
      首先我们需要创建一幅2×2的3颜色通道图像:
    #创建一幅2×2的3颜色通道图像,其中数字代表像素,np.uint8是numpy数据类型[0,255]
    img = np.array([[[0,1,2],[3,4,5]],[[6,7,8],[9,10,11]]],np.uint8)
    #查看图像numpy.ndarray中的结构
    print(img)
    #查看图像的行、列、颜色通道(BGR)
    print(img.shape)
    #在蓝色通道中,第1行第1列的像素
    print(img[0,0,0])
    #在蓝色通道中,第1行第2列的像素
    print(img[0,1,0])
    #在蓝色通道中,第2行第1列的像素
    print(img[1,0,0])
    #在绿色通道中,第1行第1列的像素
    print(img[0,0,1])
    #在红色通道中,第1行第1列的像素
    print(img[0,0,2])
    #3通道中,第1行第1列的像素
    print(img[0,0])
    
    [[[ 0  1  2]
      [ 3  4  5]]
    
     [[ 6  7  8]
      [ 9 10 11]]]
    (2, 2, 3)
    0
    3
    6
    1
    2
    [0 1 2]
    

    其中在蓝通道B中,0,3代表第一行,6,9代表第二行,如下图所示

    绘图4.jpg.jpeg

    2.图像属性

    图像的属性包括:行,列,通道,图像数据类型,像素数目等

    在opencv中,图像不是传统的RGB颜色通道,而是按BGR顺序存储的。

    img_BGR = cv2.imread('citrus-fruit-colorful-delicious-2146386.jpg') 
    print(type(img_BGR)) # numpy.ndarray类型可以用numpy对图像进行各种操作
    print(img_BGR.dtype) # 图像数据类型,一张图片的像素值范围是[0,255], 因此默认类型是unit8
    print(img_BGR.shape[0]) # 行
    print(img_BGR.shape[1]) # 列
    print(img_BGR.shape[2]) # 通道
    print(img_BGR.size) # 像素数目
    print(img_BGR.max()) # 最大像素值
    print(img_BGR.min()) # 最小像素值
    print(img_BGR.mean()) #素值平均值
    
    <class 'numpy.ndarray'>
    uint8
    4864
    3648
    3
    53231616
    255
    0
    211.1315848273327
    

    3.获取并修改像素值

    根据像素的行和列的坐标获取他的像素值。

    img = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
    px = img[100,100] # BGR3个通道中,第100行第100列的像素
    print(px)
    blue = img[100,100,0]# B通道中,第100行第100列的像素
    print(blue)
    
    [215 215 199]
    215
    

    修改像素值

    img = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
    img[100,100]=[255,255,255]
    print(img[100,100])
    
    [255 255 255]
    

    例子:使大于150的像素等于255(即使灰色像素变为白色)

    img = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
    # 使大于150的像素等于255
    img[img>150]=255
    cv2.imwrite('img150.jpg',img)
    
    img150.jpg

    4.图像 ROI

    有时你需要对一幅图像的特定区域进行操作。例如我们要检测一副图像中眼睛的位置,我们首先应该在图像中找到脸,再在脸的区域中找眼睛,而不是直接在一幅图像中搜索。这样会提高程序的准确性和性能。

    ROI 也是使用 Numpy 索引来获得的。

    例子:获取图像区域像素(即裁剪)

    img = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
    px = img[700:2700,1200:3900] # 获取第700-2700行、第1200-3900列的像素
    cv2.imwrite('cut.jpg',img)
    
    
    1111.jpg.jpeg

    例子:选择橘子的部分并把他拷贝到原图像的其他区域。

    img = cv2.imread("citrus-fruit-colorful-delicious-2146386.jpg")
    #print(img.shape)
    px = img[3000:4800,0:3600]
    img[0:1800,0:3600]=px
    cv2.imwrite('roi.jpg',img)
    
    roi.jpg.jpeg

    5.拆分图像通道

    有时我们需要对 BGR 三个通道分别进行操作。这是你就需要把 BGR 拆分成单个通道。

    例子:只保留绿色通道

    img = cv2.imread("beautiful-branch-bright-2275453.jpg")
    #b,g,r=cv2.split(img) # 不推荐使用,原因耗时
    img[:,:,0] = 0
    #img[:,:,1] = 0
    img[:,:,2] = 0
    cv2.imwrite('g.jpg',img)
    
    g.jpg

    6.为图像扩边(填充)

    如果你想在图像周围创建一个边,就像相框一样,你可以使用 cv2.copyMakeBorder()函数。这经常在卷积运算或 0 填充时被用到。

    copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]])
    

    这个函数参数意义如下:

    • src:表示图像的numpy.ndarray对象

    • top,bottom,left,right :上下左右边界各填充多少

    • borderType:

      BORDER_REPLICATE:复制法,也就是复制最边缘像素。

      BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb

      BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba

      BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg

      BORDER_CONSTANT:常量法,常数值填充。

    • value:当为BORDER_CONSTANT时,需要填充颜色可以是0或255(黑白),也可以是(0,0,255)BGR

    img = cv2.imread("beautiful-branch-bright-2275453.jpg")
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    
    top_size,bottom_size,left_size,right_size = (300,300,300,300)
    
    replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
    
    reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)
    
    reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
    
    wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
    
    constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=(0,0,255))# 这里(0,0,255)为RGB,为蓝色
    
    plt.figure(figsize=(12,5),dpi=100)
    plt.subplot(231), plt.imshow(img, 'gray'), plt.axis('off'), plt.title('ORIGINAL')
    plt.subplot(232), plt.imshow(replicate, 'gray'), plt.axis('off'), plt.title('REPLICATE')
    plt.subplot(233), plt.imshow(reflect, 'gray'), plt.axis('off'), plt.title('REFLECT')
    plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.axis('off'), plt.title('REFLECT_101')
    plt.subplot(235), plt.imshow(wrap, 'gray'), plt.axis('off'), plt.title('WRAP')
    plt.subplot(236), plt.imshow(constant, 'gray'), plt.axis('off'), plt.title('CONSTANT')
    

    由于是使用 matplotlib 绘制,所以交换 R 和 B 的位置,OpenCV 中是按 BGR,matplotlib 中是按 RGB 排列,因此,使用cv2.cvtColor(img,cv2.COLOR_BGR2RGB)将BGR转换为RGB。

    边界填充.png

    参考资料:《数字图像处理》《OpenCV-Python 中文教程》

    相关文章

      网友评论

        本文标题:Opencv图像基础操作

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