B01 - 核心操作 - 算术运算

主要讲解图像矩阵的加法,包括矩阵相加,加权和遮罩相加

OpenCV 图像的加法?

  • 函数 cv2. add () 用于图像的加法运算。OpenCV 加法和 numpy 加法之间有区别:cv2.add () 是饱和运算(相加后如大于 255 则结果为 255),而 Numpy 加法是模运算
    1
    2
    3
    4
    5
    img1 = cv2.imread("../images/imgB1.jpg")  # 读取彩色图像(BGR)
    img2 = cv2.imread("../images/imgB3.jpg") # 读取彩色图像(BGR)
    imgAddCV = cv2.add(img1, img2) # OpenCV 加法: 饱和运算
    imgAddNP = img1 + img2 # # Numpy 加法: 模运算
    show_images([img1,img2,imgAddCV,imgAddNP])

OpenCV 图像与标量加法?

  • 函数 cv2. add () 对两张相同大小和类型的图像进行加法运算,或对一张图像与一个标量进行加法运算。OpenCV 加法和 numpy 加法之间有区别:cv2. add () 是饱和运算(相加后如大于 255 则结果为 255),而 Numpy 加法是模运算
    1
    2
    3
    4
    5
    6
    7
    img1 = cv2.imread("../images/imgB1.jpg")  # 读取彩色图像(BGR)
    img2 = cv2.imread("../images/imgB3.jpg") # 读取彩色图像(BGR)
    Value = 100 # 常数
    Scalar = np.ones((1, 3), dtype="float") * Value # 标量
    imgAddV = cv2.add(img1, Value) # OpenCV 加法: 图像 + 常数
    imgAddS = cv2.add(img1, Scalar) # OpenCV 加法: 图像 + 标量
    show_images([img1,imgAddV])

OpenCV 图像的加权加法?

  • 函数 cv2.addWeighted () 对两张相同大小和类型的图像按权重相加,可以实现图像的叠加和混合
    1
    2
    3
    4
    5
    6
    img1 = cv2.imread("../images/imgGaia.tif")  # 读取图像 imgGaia
    img2 = cv2.imread("../images/imgLena.tif") # 读取图像 imgLena
    imgAddW1 = cv2.addWeighted(img1, 0.2, img2, 0.8, 0) # 加权相加, a=0.2, b=0.8
    imgAddW2 = cv2.addWeighted(img1, 0.5, img2, 0.5, 0) # 加权相加, a=0.5, b=0.5
    imgAddW3 = cv2.addWeighted(img1, 0.8, img2, 0.2, 0) # 加权相加, a=0.8, b=0.2
    show_images([imgAddW1,imgAddW2,imgAddW3])

OpenCV 不同尺寸图像的加法?

  • 函数 cv2. add () 用于图像的加法运算,对两张相同大小和类型的图像进行加法运算,不同尺寸时需要先拿到待相加的区域,再进行相加
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    imgL = cv2.imread("../images/imgB2.jpg")  # 读取大图
    imgS = cv2.imread("../images/logoCV.png") # 读取小图 (LOGO)
    x,y = 300,50 # 叠放位置
    W1, H1 = imgL.shape[1::-1] # 大图尺寸
    W2, H2 = imgS.shape[1::-1] # 小图尺寸
    if (x + W2) > W1: x = W1 - W2 # 调整图像叠放位置,避免溢出
    if (y + H2) > H1: y = H1 - H2
    imgCrop = imgL[y:y + H2, x:x + W2] # 裁剪大图,与小图 imgS 的大小相同
    imgAdd = cv2.add(imgCrop, imgS) # cv2 加法,裁剪图与小图叠加
    alpha, beta, gamma = 0.2, 0.8, 0.0 # 加法权值
    imgAddW = cv2.addWeighted(imgCrop, alpha, imgS, beta, gamma) # 加权加法,裁剪图与小图叠加
    imgAddM = np.array(imgL)
    imgAddM[y:y + H2, x:x + W2] = imgAddW # 用叠加小图替换原图 imgL 的叠放位置
    show_images([imgAdd,imgAddW,imgAddM])

OpenCV 图像的掩膜加法?

  • “图像掩膜”,是用特定的图像或函数对另一图像进行覆盖或遮蔽,以控制图像处理的区域或图像处理的过程。图像掩模常用于提取感兴趣区域(ROI)、提取结构特征,或制作特殊形状的图像
  • 函数 cv2.add () 用于图像的加法运算,可以使用掩模图像进行遮蔽
    1
    2
    3
    4
    5
    6
    7
    8
    9
    img1 = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)
    img2 = cv2.imread("../images/imgB3.jpg") # 读取彩色图像(BGR)
    Mask = np.zeros((img1.shape[0], img1.shape[1]), dtype=np.uint8) # 返回与图像 img1 尺寸相同的全零数组
    xmin, ymin, w, h = 180, 190, 200, 200 # 矩形裁剪区域 (ymin:ymin+h, xmin:xmin+w) 的位置参数
    Mask[ymin:ymin+h, xmin:xmin+w] = 255 # 掩模图像,ROI 为白色,其它区域为黑色
    print(img1.shape, img2.shape, Mask.shape)
    imgAddMask1 = cv2.add(img1, img2, mask=Mask) # 带有掩模 mask 的加法
    imgAddMask2 = cv2.add(img1, np.zeros(np.shape(img1), dtype=np.uint8), mask=Mask) # 提取 ROI
    show_images([Mask,imgAddMask1,imgAddMask2])

OpenCV 图像的圆形遮罩?

  • 函数 cv2.add () 用于图像的加法运算,可以使用掩模图像进行遮蔽
    1
    2
    3
    4
    5
    6
    7
    8
    9
    img1 = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)
    img2 = cv2.imread("../images/imgB3.jpg") # 读取彩色图像(BGR)
    Mask1 = np.zeros((img1.shape[0], img1.shape[1]), dtype=np.uint8) # 返回与图像 img1 尺寸相同的全零数组
    Mask2 = Mask1.copy()
    cv2.circle(Mask1, (285, 285), 110, (255, 255, 255), -1) # -1 表示实心
    cv2.ellipse(Mask2, (285, 285), (100, 150), 0, 0, 360, 255, -1) # -1 表示实心
    imgAddMask1 = cv2.add(img1, np.zeros(np.shape(img1), dtype=np.uint8), mask=Mask1) # 提取圆形 ROI
    imgAddMask2 = cv2.add(img1, np.zeros(np.shape(img1), dtype=np.uint8), mask=Mask2) # 提取椭圆 ROI
    show_images([Mask,imgAddMask1,imgAddMask2])

OpenCV 图像的按位运算?

  • 函数 cv2. bitwise 提供了图像的位运算,对图像的像素点值按位操作,快速高效、方便灵活
    1
    2
    3
    4
    5
    6
    img1 = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)
    img2 = cv2.imread("../images/imgB2.jpg") # 读取彩色图像(BGR)
    imgAnd = cv2.bitwise_and(img1, img2) # 按位 与(AND)
    imgOr = cv2.bitwise_or(img1, img2) # 按位 或(OR)
    imgNot = cv2.bitwise_not(img1) # 按位 非(NOT)
    imgXor = cv2.bitwise_xor(img1, img2) # 按位 异或(XOR)

OpenCV 图像的叠加?

  • 实现图像的叠加,需要综合运用图像阈值处理、图像掩模、位操作和图像加法的操作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    img1 = cv2.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)
    img2 = cv2.imread("../images/logoCV.png") # 读取 CV Logo
    x, y = (0, 10) # 图像叠加位置
    W1, H1 = img1.shape[1::-1]
    W2, H2 = img2.shape[1::-1]
    if (x + W2) > W1: x = W1 - W2
    if (y + H2) > H1: y = H1 - H2
    print(W1,H1,W2,H2,x,y)
    imgROI = img1[y:y+H2, x:x+W2] # 从背景图像裁剪出叠加区域图像
    img2Gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # img2: 转换为灰度图像
    ret, mask = cv2.threshold(img2Gray, 175, 255, cv2.THRESH_BINARY) # 转换为二值图像,生成遮罩,LOGO 区域黑色遮盖
    maskInv = cv2.bitwise_not(mask) # 按位非(黑白转置),生成逆遮罩,LOGO 区域白色开窗,LOGO 以外区域黑色
    # mask 黑色遮盖区域输出为黑色,mask 白色开窗区域与运算(原图像素不变)
    img1Bg = cv2.bitwise_and(imgROI, imgROI, mask=mask) # 生成背景,imgROI 的遮罩区域输出黑色
    img2Fg = cv2.bitwise_and(img2, img2, mask=maskInv) # 生成前景,LOGO 的逆遮罩区域输出黑色
    imgROIAdd = cv2.add(img1Bg, img2Fg) # 前景与背景合成,得到裁剪部分的叠加图像
    imgAdd = img1.copy()
    imgAdd[y:y+H2, x:x+W2] = imgROIAdd # 用叠加图像替换背景图像中的叠加位置,得到叠加 Logo 合成图像

参考: