基本的图片核心操作

  • 本节主要介绍一些基本的图片核心操作

一. 学习目标

  • 获取图片的像素值并修改图片的像素值
  • 获取图片属性
  • 选择 ROI
  • 合并和分离图片

二. 获取和修改图片的像素值

  • 首先我们载入一张图片
>>> import numpy as np
>>> import cv2 as cv
>>> img = cv.imread('./test_image/lenacolor.png')	 # 注意图片路径
  • 然后我们可以通过行和列坐标访问像素值。对于 BGR 图片,返回值为一个 B,G,R 值矩阵。对于灰度图片,则返回相应的灰度值。
>>> px = img[100,100]
>>> print( px )
[ 78  68 178]

# 仅访问一个 blue 像素
>>> blue = img[100,100,0]
>>> print(blue)
78
  • 通过相同的方式,我们也可以修改像素值
>>> img[100,100] = [255,255,255]
>>> print(img[100, 100])
[255 255 255]
  • 注意
    Numpy 是一个用于快速数组计算的优化库。如果只是简单地访问每个像素值并修改它们,这个过程将会变得非常缓慢,是不可取的。

三. 获取图片属性

  • 图片属性包括图片的行数,列数,通道数,图片数据的类型以及像素数等。
  • 我们可以通过图片的 shape 属性获得图片的行数,列数以及通道数(当读取的图片为彩色图片时,才有通道数;如果读取的是灰度图片,则只能获得图片的行数和列数)
>>> print(img.shape)
(512, 512, 3)
  • 通过图片的 size 属性获取图片的像素数目
>>> print(img.size)
786432
  • 通过图片的 dtype 属性获取图片数据类型
>>> print(img.dtype)
uint8

四. 分离图像通道

  • 有时候,我们需要分离图片的 B, G, R 通道。在这种情况下,我们可以使用 cv.split() 函数将 BGR 图片转换为单通道。
>>> b, g, r = cv.split(img)
>>> print("b shape is", b.shape, "\ng shape is", g.shape, "\nr shape is", r.shape)
b shape is (512, 512)
g shape is (512, 512)
r shape is (512, 512)
  • 也可以使用 numpy 操作
>>> b = img[:,:,0]
>>> print("b shape is",b.shape)
b shape is (512, 512)
  • 注意
    cv.split() 会花费大量的时间,所以只有你需要用到的时候才去使用。最好用 numpy 索引。

五. 为图像制作边框

  • 如果想为图片制作边框,我们可以使用 cv.copyMakeBorder() 函数。
  • 它的主要参数有:
  • src : 输入图像
  • top, bottom, left, right : 在指定边缘的像素点宽度
  • borderType : 想要添加的边缘类型。它有下列类型:
  • cv.BORDER_CONSTANT : 添加一个固定颜色的边框
  • cv.BORDER_REFLECT :边界将是边界元素的镜像反射
  • cv.BORDER_REFLECT_101 or cv.BORDER_DEFAULT : 与上面相同,仅有稍微不同
  • cv.BORDER_REPLICATE :最后一个像素点将被复制
  • cv.BORDER_WRA
  • value : 边界颜色,如果边界类型为 cv.BORDER_CONSTANT,则需用到。
  • 下面我们就用具体的代码,来演示一下各边框的效果
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 读取图片
img1 = cv.imread("./test_image/OpenCVLogo.jpg")

# 为图片添加不同类型的边框
replicate = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REPLICATE)
reflect = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT)
reflect101 = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT_101)
wrap = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_WRAP)
BLUE = [255,0,0]
constant= cv.copyMakeBorder(img1,10,10,10,10,cv.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()
  • 运行结果:
  • 注意:在使用 Matplotlib,颜色通道发生了改变。