Opencv-Python学习笔记(三):像素运算、ROI、泛洪填充

  • 本篇记录学习图像的几种算术运算,例如加、乘、除,按位运算等。
  • 将学习以下函数:cv2.add()cv2.addWeighted(),等。
  • ROI(Region of Interest)感兴趣区域,泛洪填充,边界填充。

对图像像素级别的加减乘除

import cv2 as cv
import numpy as np


def add_demo(m1, m2):
    dst = cv.add(m1, m2)
    cv.imshow("add_demo", dst)


def subtract_demo(m1, m2):
    dst = cv.subtract(m1, m2)
    cv.imshow("subtract_demo", dst)


def divide_demo(m1, m2):
    dst = cv.divide(m1, m2)
    cv.imshow("divide_demo", dst)


def multiply_demo(m1, m2):
    dst = cv.multiply(m1, m2)
    cv.imshow("multiply_demo", dst)


if __name__ == '__main__':
    print("--------- Python OpenCV Tutorial ---------")
    src1 = cv.imread("F:/Pycharm/opencv_exercises-master/images/01.jpg")
    src2 = cv.imread("F:/Pycharm/opencv_exercises-master/images/02.jpg")
    print(src1.shape)
    print(src2.shape)

    cv.namedWindow("image1", cv.WINDOW_AUTOSIZE)  # 创建窗口, 窗口尺寸自动调整
    cv.imshow("image1", src1)
    cv.imshow("image2", src2)

    add_demo(src1, src2)  # 两个图像应具有相同的深度和类型
    subtract_demo(src1, src2)
    divide_demo(src1, src2)
    multiply_demo(src1,src2)

    cv.waitKey(0)

    cv.destroyAllWindows()

# 图像的逻辑运算,:AND,OR,NOT,XOR
def logic_demo(m1, m2):
    image = cv.imread("F:/Pycharm/opencv_exercises-master/images/Crystal.jpg")
    cv.imshow("image1", image)
    dst = cv.bitwise_not(image)  # not操作
    cv.imshow("logic_demo", dst)

图像融合

这也是图像加法,但是对图像赋予不同的权重,以使其具有融合或透明的感觉。

根据以下等式添加图像:g(x)=(1-\ alpha)f_ {0}(x)+ \ alpha f_ {1}(x)

通过改变\α0 \ rightarrow 1,可以在一个图像到另一个图像之间执行转换。

import cv2 as cv
import numpy as np


if __name__ == '__main__':
    print("--------- Python OpenCV Tutorial ---------")
    src1 = cv.imread("F:/Pycharm/opencv_exercises-master/images/01.jpg")
    src2 = cv.imread("F:/Pycharm/opencv_exercises-master/images/02.jpg")
    print(src1.shape)
    print(src2.shape)

    cv.namedWindow("image1", cv.WINDOW_AUTOSIZE)  # 创建窗口, 窗口尺寸自动调整
    cv.imshow("image1", src1)
    cv.imshow("image2", src2)

    dst = cv.addWeighted(src1, 0.7, src2, 0.3, 0)
    cv.imshow("output image", dst)

    cv.waitKey(0)

    cv.destroyAllWindows()

增强对比度亮度

def contrast_brightness_demo(image, c, b):
    h, w, ch = image.shape
    blank = np.zeros([h, w, ch], image.dtype)

    # 图像混合,c, 1-c为这两张图片的权重
    dst = cv.addWeighted(image, c, blank, 1 - c, b)
    cv.imshow("contrast_brightness_demo", dst)


    src = cv.imread("F:/Pycharm/opencv_exercises-master/images/Crystal.jpg")
    cv.imshow("input image", src)
    contrast_brightness_demo(src, 1.3, 80)

ROI(Region of Interest)感兴趣区域,泛洪填充,边界填充。

# roi 即兴趣区域,对图像提取想要的部分

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


def roi_test(src):
    face = src[100:510, 200:600]  # 提取我们感兴趣的区域
    gray = cv.cvtColor(face, cv.COLOR_BGR2GRAY)  # face彩色图片变成灰度图片并显示
    cv.imshow("gray", gray)

    back_face = cv.cvtColor(gray, cv.COLOR_GRAY2BGR)  # 将灰度图像重新转换为BGR通道,否则无法贴回原图像
    cv.imshow("back_face", back_face)

    src[100:510, 200:600] = back_face
    cv.imshow("face", src)


if __name__ == '__main__':
    src = cv.imread("../images/CrystalLiu1.jpg")  # 读入图片放进src中
    cv.namedWindow("Crystal Liu")  # 创建窗口
    cv.imshow("Crystal Liu", src)  # 将src图片放入该创建的窗口中
    roi_test(src)
    cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
    cv.destroyAllWindows()  # 关闭所有窗口

可见ROI可以让我们对原图像进行方便的操作,如果我们想在一张图片上贴图,就可以用ROI进行操作。

泛洪填充,下面介绍两种方式。

import cv2 as cv
import numpy as np



def fill_color_demo(image):
    copyImg = image.copy()
    h, w = image.shape[:2]
    mask = np.zeros([h + 2, w + 2], np.uint8)  # 一定要加2

    # 参数:原图,mask图,起始点,起始点值减去该值作为最低值,起始点值加上该值作为最高值,彩色图模式
    cv.floodFill(copyImg, mask, (30, 30), (0, 255, 255),
                 (100, 100, 100), (50, 50, 50), cv.FLOODFILL_FIXED_RANGE)
    cv.imshow("fill_color_demo", copyImg)


def fill_binary():
    image = np.zeros([400, 400, 3], np.uint8)
    image[100:300, 100:300, :] = 255
    cv.imshow("fill_binary", image)

    mask = np.ones([402, 402, 1], np.uint8)  # 一定要加2
    mask[101:301, 101:301] = 0

    cv.floodFill(image, mask, (200, 200),
                 (100, 2, 255), cv.FLOODFILL_MASK_ONLY)
    # 用这种方式进行填充时一定要注意mask一定初始化为1,显填充的地方初始化为0
    cv.imshow("filled binary", image)


if __name__ == '__main__':
    src = cv.imread("../images/CrystalLiu1.jpg")  # 读入图片放进src中
    cv.namedWindow("Crystal Liu")  # 创建窗口
    cv.imshow("Crystal Liu", src)  # 将src图片放入该创建的窗口中
    fill_color_demo(src)
    fill_binary()
    cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
    cv.destroyAllWindows()  # 关闭所有窗口

边界填充

def make_border(image):
    """
    :param image:输入图像
    top, bottom, left, right 对应边界的像素数目。
    borderType 要添加那种类型的边界,类型如下:
    – cv2.BORDER_CONSTANT 常量法 添加有颜色的常数值边界,需要一个参数(value)边界颜色
    – cv2.BORDER_REFLECT  反射法 边界元素的镜像。比如: fedcba|abcdefgh|hgfedcb
    – cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT 反射法 以最边缘元素为轴 对称。例如: gfedcb|abcdefgh|gfedcba
    – cv2.BORDER_REPLICATE 复制法 重复前面或最后一个元素。例如: aaaaaa| abcdefgh|hhhhhhh
    – cv2.BORDER_WRAP 外包装法: cdefgh| abcdefgh|abcdefg
    """
    BLUE = [255, 0, 0]

    replicate = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_REPLICATE)
    reflect = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_REFLECT)
    reflect101 = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_REFLECT_101)
    wrap = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_WRAP)
    constant = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_CONSTANT, value=BLUE)

    plt.subplot(231), plt.imshow(image, '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()

完整的工程代码:

# roi 即兴趣区域,对图像提取想要的部分

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


def roi_test(src):
    face = src[100:510, 200:600]
    gray = cv.cvtColor(face, cv.COLOR_BGR2GRAY)  # face彩色图片变成灰度图片
    cv.imshow("gray", gray)
    back_face = cv.cvtColor(gray, cv.COLOR_GRAY2BGR)
    cv.imshow("back_face", back_face)
    src[100:510, 200:600] = back_face
    cv.imshow("face", src)


def fill_color_demo(image):
    copyImg = image.copy()
    h, w = image.shape[:2]
    mask = np.zeros([h + 2, w + 2], np.uint8)  # 一定要加2

    # 参数:原图,mask图,起始点,起始点值减去该值作为最低值,起始点值加上该值作为最高值,彩色图模式
    cv.floodFill(copyImg, mask, (30, 30), (0, 255, 255),
                 (100, 100, 100), (50, 50, 50), cv.FLOODFILL_FIXED_RANGE)
    cv.imshow("fill_color_demo", copyImg)


def fill_binary():
    image = np.zeros([400, 400, 3], np.uint8)
    image[100:300, 100:300, :] = 255
    cv.imshow("fill_binary", image)

    mask = np.ones([402, 402, 1], np.uint8)  # 一定要加2
    mask[101:301, 101:301] = 0

    cv.floodFill(image, mask, (200, 200),
                 (100, 2, 255), cv.FLOODFILL_MASK_ONLY)
    # 用这种方式进行填充时一定要注意mask一定初始化为1,显填充的地方初始化为0
    cv.imshow("filled binary", image)


def make_border(image):
    """
    :param image:输入图像
    top, bottom, left, right 对应边界的像素数目。
    borderType 要添加那种类型的边界,类型如下:
    – cv2.BORDER_CONSTANT 常量法 添加有颜色的常数值边界,需要一个参数(value)边界颜色
    – cv2.BORDER_REFLECT  反射法 边界元素的镜像。比如: fedcba|abcdefgh|hgfedcb
    – cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT 反射法 以最边缘元素为轴 对称。例如: gfedcb|abcdefgh|gfedcba
    – cv2.BORDER_REPLICATE 复制法 重复前面或最后一个元素。例如: aaaaaa| abcdefgh|hhhhhhh
    – cv2.BORDER_WRAP 外包装法: cdefgh| abcdefgh|abcdefg
    """
    BLUE = [255, 0, 0]

    replicate = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_REPLICATE)
    reflect = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_REFLECT)
    reflect101 = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_REFLECT_101)
    wrap = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_WRAP)
    constant = cv.copyMakeBorder(image, 50, 50, 50, 50, cv.BORDER_CONSTANT, value=BLUE)

    plt.subplot(231), plt.imshow(image, '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()


if __name__ == '__main__':
    # src = cv.imread("F:/Pycharm/opencv_exercises-master/images/CrystalLiu1.jpg")  # 读入图片放进src中
    # cv.namedWindow("Crystal Liu")  # 创建窗口
    # cv.imshow("Crystal Liu", src)  # 将src图片放入该创建的窗口中
    # roi_test(src)
    # fill_color_demo(src)
    # fill_binary()
    img = cv.imread("F:/Pycharm/opencv_exercises-master/images/opencv_logo.png")
    make_border(img)
    cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
    cv.destroyAllWindows()  # 关闭所有窗口
发布了29 篇原创文章 · 获赞 83 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/l59565455/article/details/102239389