zoukankan      html  css  js  c++  java
  • 【opencv_python学习之二】图像处理初识

    0、背景介绍

    在本篇文章中所有示例所处理的图片为下图0.1,图片名字为a.png。

    图 0.1

    下图0.2, 图片名字为b.png

    图 0.2

    下图0.3, 图片名字为c.png

    图 0.3

    1、获取并修改某点RGB值

    1.1、获取某点RGB值

    1.1.1、代码示例

    代码: 1.1.py

    import cv2
    import numpy as np
    
    # 读取图片a.png
    img = cv2.imread('a.png')
    
    # 获取(0,0)点的RGB值,并打印
    px0 = img[0, 0]
    print('坐标(0,0)点的BGR为: %s'%px0)
    blue0 = img[0,0,0]
    print('坐标(0,0)点的B值为: %s'%blue0)
    green0 = img[0,0,1]
    print('坐标(0,0)点的G值为: %s'%green0)
    red0 = img[0,0,2]
    print('坐标(0,0)点的R值为: %s
    '%red0)
    
    # 获取(75,236)点的RGB值并打印
    px100 = img[236,75]
    print('坐标(75,236)点的BGR为: %s'%px100)
    blue100 = img.item(236,75,0)
    print('坐标(75,236)点的B值为: %s'%blue100)
    green100 = img.item(236,75,1)
    print('坐标(75,236)点的G值为: %s'%green100)
    red100 = img.item(236,75,2)
    print('坐标(75,236)点的R值为: %s'%red100)
    

    1.1.2、运行结果

    运行代码1.1.py结果为:

    F:QAQpythonopencv>python 1.1.py
    坐标(0,0)点的BGR为: [255 255 255]
    坐标(0,0)点的B值为: 255
    坐标(0,0)点的G值为: 255
    坐标(0,0)点的R值为: 255
    
    坐标(75,236)点的BGR为: [213 227 245]
    坐标(75,236)点的B值为: 213
    坐标(75,236)点的G值为: 227
    坐标(75,236)点的R值为: 245
    

    1.1.3、知识点

    • img[y, x, 0/1/2] 可以查看某个点的RGB值,其中0/1/2分别对应B/G/R。
    • img.item(y, x, 0/1/2) 可以查看某个点的RGB值,其中0/1/2分别对应B/G/R。
    • 推荐使用 img.item

    1.2、修改某点RGB值

    1.2.1、代码示例

    代码: 1.2.py

    import cv2
    import numpy as np
    
    # 读取图片a.png
    img = cv2.imread('a.png')
    
    # 显示原始图片
    cv2.imshow('old picture', img)
    
    for i in range(0, 100):
    	for j in range(0, 100):
    		img[i,j] = [255,255,255]
    
    for i in range(100, 200):
    	for j in range(100, 200):
    		img.itemset((i,j,2), 255)		
    
    # 显示替换过RGB的图片
    cv2.imshow('new picture', img)
    key = cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    1.2.2、运行结果

    运行代码1.2.py,结果如图1.2,可以看到我们左上角图片出现了空白和黄色

    图 1.2

    1.2.3、知识点

    • img[y, x] = [B, G, R] 可以设置某个点的RGB值。
    • img.itemset((y, x,0/1/2), BGR) 可以设置某个点的RGB值. 0/1/2分别对应B/G/R。
    • 推荐使用 img.itemset

    2、获取图片属性

    2.1、获取宽高和通道

    2.1.1、代码示例

    代码: 2.1.py

    import cv2
    
    img = cv2.imread('a.png')
    
    print('图片竖直像素%s, 水平像素%s个, 通道有%s个'%
    	(img.shape[0], img.shape[1], img.shape[2]))
    

    2.1.2、运行结果

    D:workpythonopencv_python>python 2.1.p
    图片竖直像素510, 水平像素445个, 通道有3个
    

    使用Photoshop查看文档,如图2.1,和上面结果一致

    ![](http://git.oschina.net/diefrom/imgForMk/raw/master/opencv_python_base_deal_03.png) 图 2.1

    2.1.3、知识点

    • img.shape 可以获取图片宽、高以及通道数。

    2.2、获取像素个数

    2.2.1、代码示例

    代码: 2.2.py

    import cv2
    
    img = cv2.imread('a.png')
    
    print('文件总共像素: %s 个'%img.size)
    
    print('高(%s) * 宽(%s) * 通道数(%s) = %s'%(img.shape[0], img.shape[1], img.shape[2], 
    	int(img.shape[0]) * int(img.shape[1]) * int(img.shape[2]) ))
    

    2.2.2、运行结果

    F:QAQpythonopencv>python 2.2.py
    文件总共像素: 680850 个
    高(510) * 宽(445) * 通道数(3) = 680850
    

    2.2.3、知识点

    • img.size 可以获取文件总像素点。
      该值等于 水平像素个数*垂直像素个数*通道个数

    2.3、获取图片的data type

    2.3.1、代码示例

    代码: 2.3.py

    import cv2
    
    img = cv2.imread('a.png')
    
    print('图片date type 为: %s'%img.dtype)
    

    2.3.2、运行结果

    F:QAQpythonopencv>python 2.3.py
    图片data type 为: uint8
    

    2.3.3、知识点

    • img.dtype可以获取图片的data type。

    • 图片的data type在debug时是一个非常重要的数据。掌握好data type可以避免图像失真。

    • 关于所有data type和取值范围可以查看下表2.1。

    Data type Range
    uint8 0 to 255
    uint16 0 to 65535
    uint32 0 to 232
    float -1 to 1 or 0 to 1
    int8 -128 to 127
    int16 -32768 to 32767
    int32 -231 to 231 - 1
    表 2.1

    3、图像部分区域的获取和更改

    3.1、截取某区域后复制到另一区域

    3.1.1、代码示例

    代码: 3.1.py

    import cv2
    
    img = cv2.imread('a.png')
    
    ball = img[43:239, 231:418]
    img[0:196, 0:187] = ball
    
    cv2.imshow('img', img)
    key = cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    3.1.2、运行结果

    图 3.1

    3.1.3、知识点

    • ROI(Region Of Images) 可以用于人脸识别。

    • img[y1:y2, x1:x2] 可以获取图片的某个区域。

    • 使用 img[y1:y2, x1:x2] 可以将某个区域的图像复制到另一个区域去,比如例子中,将图片中的蝴蝶复制到左上角。这里需要注意的是,前面的参数是y轴范围,后面的参数是x轴范围。例子中的这个操作很像Photoshop中的仿制图章。

    4、图像通道操作

    4.1、调整某个通道的值

    4.1.1、代码示例

    代码: 4.1.py

    import cv2
    
    img = cv2.imread('a.png')
    
    img[:,:,0] = 200
    
    cv2.imshow('img', img)
    key = cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    代码: 4.2.py

    import cv2
    import numpy as np
    
    img = cv2.imread('a.png')
    
    b, g, r = cv2.split(img)
    b[:,:] = 200
    img = cv2.merge((b, g, r))
    
    cv2.imshow('img', img)
    key = cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    4.1.2、运行结果

    分别运行4.1.py4.2.py,结果都如下图4.1

    图 4.1

    4.1.3、知识点

    • img[:, :, 0/1/2] 可以修改某个通道的值,其中0/1/2分别对应B/G/R。
    • 在第一节我们知道 img[y, x, 0/1/2] 可以设置某个点的RGB,那么设置全部点就是设置整个通道,即 img[:, :, 0/1/2]
    • cv2.merge((b, g, r)) 可以修改图像的通道值。其中b/g/r的范围是0-255。
    • 对于 img[:, :, 0/1/2]cv2.merge((b, g, r)) 相当于Photoshop中修改某个通道的色阶,如图4.1。
    • 推荐使用img[:, :, 0/1/2]

    5、图片叠加

    5.1、图片叠加计算原理

    5.1.1、代码示例

    代码: 5.1.py

    import cv2
    import numpy as np
    
    x = np.uint8([250])
    y = np.uint8([10])
    
    print('x = %s, y = %s'%(x, y))
    print('cv2.add(x, y) = %s'%cv2.add(x,y))
    print('x+y = %s'%(x+y))
    

    5.1.2、运行结果

    F:QAQpythonopencv>python 5.1.py
    x = [250], y = [10]
    cv2.add(x, y) = [[255]]
    x+y = [4]
    

    5.1.3、知识点

    在上面的例子中

    cv2.add(x, y) = cv2.add([250], [10]) = 250 + 10 = 260
    

    由于uint8的范围是[0, 255],所以cv2.add([250], [10])的最终值为255

    x + y = [250] + [10] = ( 250 + 10 ) % 256 = 4
    

    5.2、相同大小的图片叠加

    5.2.1、代码示例

    代码: 5.2.py

    import cv2
    
    img1 = cv2.imread('a.png')
    img2 = cv2.imread('b.png')
    
    dst = cv2.addWeighted(img1,0.7,img2,0.3,0)
    cv2.imshow('dst',dst)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    5.2.2、运行结果

    图 5.1

    5.2.3、知识点

    • addWeighted可以叠加两张图片,但是这两张图片必须宽高、通道数都一样。

    • addWeighted的计算公式为

    公式 5.1

    对于上面例子
    img1(100,100)点的BGR为: [178 240 216]
    img2(100,100)点的BGR为:[255 255 255]
    合成图像(100,100)点的BGR为:[201 244 228]

    对于坐标(100,100)的点,根据以上公式则可以得出

    B: a * img1 + b * img2 + r = 0.7 * 178 + 0.3 * 255 + 0 = 201.1 = 201
    G: a * img1 + b * img2 + r = 0.7 * 240 + 0.3 * 255 + 0 = 244.5 = 244
    R: a * img1 + b * img2 + r = 0.7 * 216 + 0.3 * 255 + 0 = 227.7 = 228
    

    5.3、不同大小的图片叠加

    5.3.1 代码示例

    import cv2
    
    img1 = cv2.imread('a.png')
    img2 = cv2.imread('c.png')
    
    
    rows,cols,channels = img2.shape
    roi = img1[0:rows, 0:cols ]
    img1[0:rows, 0:cols ] = img2
    
    cv2.imshow('res',img1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    5.3.2 运行结果

    图 5.2

    5.3.3 知识点

    • 既然add相关操作都是要求shape值相同,那么就要换一种思路叠加图片。即可以将图片a.png的某个区域设置成图片c.png。

    • img[y1:y2, x1:x2] = img2可以叠加两张图片

    参考
    Basic Operations on Images
    Image data types and what they mean
    Arithmetic Operations on Images

  • 相关阅读:
    解决面试题的思路--5
    剑指offer例题分享--4
    剑指offer--3
    剑指offer--2
    【数据结构】5.2 二叉搜索树的创建查找以及插入操作
    【数据结构】5.1 顺序表的查找以及二分查找的实现
    【数据结构】4.1图的创建及DFS深度遍历(不完善)
    【密码学】RSA加密 kotlin实现方法(支持任意字节长度)
    【数据结构】3-2哈夫曼树的实现(数组实现)以及哈夫曼编码
    【密码学】公钥密码体制概述
  • 原文地址:https://www.cnblogs.com/featherw/p/7597082.html
Copyright © 2011-2022 走看看