zoukankan      html  css  js  c++  java
  • OpenCV4【5】-图像基本运算

    图像运算有很多种,包括 加法、减法、乘法、除法、位运算、平方根、对数、绝对值等;

    加减乘除等 需保持 图像 shape 和 dtype 一致,或者第二个图像是个标量值;

    dst = cv.add(src1, src2[, dst[, mask[, dtype]]])
    dst = cv2.subtract(src1, src2, dst, mask, dtype)
    dst = cv2.multiply(src1, src2, dst, scale, dtype)        dst = scale * src1 * src2
    dst = cv2.divide(src1, src2, dst, scale, dtype)          dst = scale * src1 / src2

    注意 OpenCV运算 和 Numpy运算 之间有区别:OpenCV运算是饱和运算,而Numpy运算是模运算

    OpenCV功能将提供更好的结果,最好坚持使用OpenCV功能

    图像加法

    以加法为例解释 饱和运算 和 模运算

    ## opencv  VS  numpy
    # def add(src1, src2, dst=None, mask=None, dtype=None):
    x = np.uint8([10])
    y = np.uint8([250])
    z1 = x + y          # 250 + 10 = 260 % 256 = 4      8位无符号整型,最大 256
    z2 = cv.add(x, y)   # 250 + 10 = 260 => 255
    print(z1, z2)       # [4] [[255]]

    第二个数为 标量值 示例

    # 加 标量值
    xx = np.random.randint(0, 100, size=(2, 2), dtype=np.uint8)
    print(xx)
    # [[ 8 22]
    #  [28 11]]
    yy = 10
    zz = cv.add(xx, yy)
    print(zz)
    # [[18 32]
    #  [38 21]]

    图像融合

    图像融合 的本质也是 图像加法,只是 赋予了图像 不同的权重;它给人一种混合或透明的感觉

    计算公式:dst=α⋅img1+β⋅img2+γ

    # def addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=None):
    img11 = cv.imread('imgs/2.png')[:300, :350]
    img22 = cv.imread('imgs/3.png')[:300, :350]         # img11  img22 shape 一致
    print(img11.shape, img11.dtype, img22.shape, img22.dtype)
    img33 = cv.addWeighted(img11, 0.3, img22, 0.7, 0)
    cv.imshow('t', img33)
    cv.waitKey(0)

    效果图

    图像乘法

    不太常用,也没看懂怎么算的

    x = np.random.randint(0, 10, size=(3, 3), dtype=np.uint8)
    y = np.random.choice([0, 255], size=(3, 3)).astype(np.uint8)
    z1 = cv.multiply(x, y)
    z2 = cv.multiply(x, x)
    print(x)
    # [[  8 150  28]
    #  [139  24 219]
    #  [208 171  67]]
    print(y)
    # [[255 255 255]
    #  [  0   0   0]
    #  [  0   0 255]]
    print(z1)
    # [[255 255 255]
    #  [  0   0   0]
    #  [  0   0 255]]
    print(z2)
    # [[64  0  9]
    #  [49  9 49]
    #  [49 81 49]]

    位运算

    这个比较常用,也比较复杂

    基础函数

    先简单了解几个函数,在 位运算 中 会用到      【更详细的功能 后续 会 专门讲解】

    固定阈值二值化

    def threshold(src, thresh, maxval, type, dst=None)

    src: 输入图,只能输入单通道图像,通常来说为灰度图
    thresh: 阈值
    maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
    type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
    dst: 输出图

    上下阈值二值化

    def inRange(src, lowerb, upperb, dst=None)

    介于 low 和 up 之间 为 255,否则为 0

    示例

    xx = np.random.randint(0, 255, size=(5, 5), dtype=np.uint8)
    print(xx)
    # [[  8 150  28 139  24]
    #  [219 208 171  67  55]
    #  [ 67  71 103 223 123]
    #  [105  87  47 173 108]
    #  [ 79   0 193 134 176]]
    ## def threshold(src, thresh, maxval, type, dst=None):   # 小于 thresh 为 0,大于 thresh 为 maxval
    yy, zz = cv.threshold(xx, 100, 200, cv.THRESH_BINARY)
    print(zz)
    # [[  0 200   0 200   0]
    #  [200 200 200   0   0]
    #  [  0   0 200 200 200]
    #  [200   0   0 200 200]
    #  [  0   0 200 200 200]]
    
    ## def inRange(src, lowerb, upperb, dst=None):       # 介于 low 和 up 之间 为 255,否则为 0
    ss = cv.inRange(xx, 100, 150)
    print(xx)
    # [[  8 150  28 139  24]
    #  [219 208 171  67  55]
    #  [ 67  71 103 223 123]
    #  [105  87  47 173 108]
    #  [ 79   0 193 134 176]]
    print(ss)
    # [[  0 255   0 255   0]
    #  [  0   0   0   0   0]
    #  [  0   0 255   0 255]
    #  [255   0   0   0 255]
    #  [  0   0   0 255   0]]

    掩膜 mask

    掩膜的概念来源于PCB制版的过程,在半导体制造中,许多芯片工艺步骤采用光刻技术,用于这些步骤的图形“底片”称为掩膜(也称作“掩模”),

    其作用是:在硅片上 选定的区域 用一个 不透明的图形模板 遮盖,继而下面的 腐蚀或扩散 将只影响 选定的区域以外 的区域。

    图像掩膜与其类似,用选定的 图形、图像或物体 对 待处理的 图像 进行遮挡,来控制图像处理的区域或者处理过程

    数字图像处理中,掩膜多为 二维矩阵,也可为 多值图像,图像掩膜主要用于:

    1. 提取感兴趣区域ROI:掩膜图像 与 待处理图像 相乘,感兴趣区内图像值保持不变,其余置0

    2. 屏蔽作用:用掩膜对图像上某些区域进行屏蔽,使其不参与处理,或者仅对屏蔽区域进行处理

    3. 结构特征提取:用相似性计算或者图像匹配方法 检测和提取 图像中与 掩膜 相似的 结构特征

    4. 特殊形状图像的制作

    位运算函数

    bitwise_and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=1,1&0=0,0&1=0,0&0=0

    bitwise_or 是对二进制数据进行“或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1|1=1,1|0=0,0|1=0,0|0=0

    bitwise_xor是对二进制数据进行“异或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“异或”操作,1^1=0,1^0=1,0^1=1,0^0=0

    bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,~1=0,~0=1

    示例

    ## def bitwise_and(src1, src2, dst=None, mask=None):
    x = np.uint8([[0, 0], [255, 255]])
    print(x)
    # [[  0   0]
    #  [255 255]]
    y = np.uint8([[0, 255], [0, 255]])
    print(y)
    # [[  0 255]
    #  [  0 255]]
    print(cv.bitwise_not(x))        # 取反, 0变成255, 255变成0
    # [[255 255]
    #  [  0   0]]
    print(cv.bitwise_and(x, x))     #
    # [[  0   0]
    #  [255 255]]
    print(cv.bitwise_and(x, y))     #
    # [[  0   0]
    #  [  0 255]]
    print(cv.bitwise_or(x, x))
    # [[  0   0]
    #  [255 255]]
    print(cv.bitwise_or(x, y))      #
    # [[  0 255]
    #  [255 255]]
    print(cv.bitwise_xor(x, x))
    # [[0 0]
    #  [0 0]]
    print(cv.bitwise_xor(x, y))     # 异或,不同为255,相同为0
    # [[  0 255]
    #  [255   0]]

    掩膜-位运算-实例

    以郁金香图片为例,原图大小为1024×768,先压缩一下,利用opencv的inRange()函数,制作掩模,再用bitwise_and()函数,提取感兴趣区域

    # set blue thresh
    lower_yellow = np.array([11, 43, 46])
    upper_yellow = np.array([25, 255, 255])
    
    frame = cv.imread("imgs/mask2.png")  # 读取图像
    cv.imshow("who", frame)
    
    # compress
    cp = cv.resize(frame, (300, 300), interpolation=cv.INTER_AREA)
    cv.imwrite("tulips_1.jpg", cp)
    # change to hsv model
    hsv = cv.cvtColor(cp, cv.COLOR_BGR2HSV)
    # get mask
    mask = cv.inRange(hsv, lower_yellow, upper_yellow)  # 获取黄色 ROI, inRange 介于 low 和 up 之间 为 1
    cv.imshow('Mask', mask)
    # detect blue
    res = cv.bitwise_and(cp, cp, mask=mask)             # 只对 mask 进行计算,这里就是 提取 mask 区域,其他区域置0
    cv.imshow('Result', res)
    cv.waitKey(0)
    cv.destroyAllWindows()

    效果图

    参考资料:

    https://blog.csdn.net/sinat_21258931/article/details/61418681  python-opencv函数总结之(一)threshold、adaptiveThreshold、Otsu 二值化

    https://blog.csdn.net/qq_42444944/article/details/91988092   python-opencv中的cv2.inRange函数

    https://blog.csdn.net/weixin_26882891/article/details/113009845  python图像相乘运算_opencv-python-学习笔记六(图像的基本运算)

    https://blog.csdn.net/youandme520/article/details/107844995  bitwise_and、bitwise_not等图像基本运算及掩膜

    https://blog.csdn.net/weixin_41115751/article/details/84568029  python_opencv图像算术运算(cv2.bitwise_and(),cv2.bitwise_not())按位运算

    https://blog.csdn.net/zhouzongzong/article/details/93028651  【OpenCV + Python】之bitwise_and、bitwise_not,bitwise_xor等图像基本运算(opencv位操作)

  • 相关阅读:
    图片处理中的Dithering技术
    网络I/O模型
    并发编程(二)
    并发编程(一)
    socket编程(二)
    socket编程(一)
    异常处理
    软件开发规范
    面向对象进阶
    多态与封装
  • 原文地址:https://www.cnblogs.com/yanshw/p/15378913.html
Copyright © 2011-2022 走看看