前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV-Python学习(6)—— OpenCV 图像算术操作

OpenCV-Python学习(6)—— OpenCV 图像算术操作

作者头像
Rattenking
发布2022-10-24 15:59:28
5360
发布2022-10-24 15:59:28
举报
文章被收录于专栏:RattenkingRattenking

1. 知识点

  1. 算术操作;
  2. 像素算术操作。

2. NumPy算术操作 和 OpenCV像素运算

2.1 加法
2.1.0 cv.add 函数
代码语言:javascript
复制
cv.add(src1,src2[,dst[,mask[,dtype]]])
2.1.1 代码测试
  1. 读取图片butterfly和lena;
  2. 获取两张图片[0,100]位置的像素值;
  3. 使用加法、np.add、cv.add进行算术操作。
代码语言:javascript
复制
import cv2 as cv
import numpy as np

def sums_add():
  img1 = cv.imread('./images/butterfly.jpg')
  img2 = cv.imread('./images/lena.jpg')
  print('img1',img1[0,100])
  print('img2',img2[0,100])
  print('加法',img2[0,100] + img1[0,100])
  print('np.add',np.add(img2[0,100], img1[0,100]))
  print('cv.add',cv.add(img2[0,100], img1[0,100]))
if __name__ == "__main__":
  sums_add()
2.1.2 测试结果
在这里插入图片描述
在这里插入图片描述
2.2 减法
2.2.0 cv.subtract 函数
代码语言:javascript
复制
cv.subtract(src1,src2[,dst[,mask[,dtype]]])
2.2.1 代码测试
代码语言:javascript
复制
import cv2 as cv
import numpy as np

def sums_subtract():
  img1 = cv.imread('./images/butterfly.jpg')
  img2 = cv.imread('./images/lena.jpg')
  print('img1',img1[0,100])
  print('img2',img2[0,100])
  print('减法',img2[0,100] - img1[0,100])
  print('np.subtract',np.subtract(img2[0,100], img1[0,100]))
  print('cv.subtract',cv.subtract(img2[0,100], img1[0,100]))
if __name__ == "__main__":
  sums_subtract()
2.2.2 测试结果
在这里插入图片描述
在这里插入图片描述
2.3 乘法
2.3.0 cv.multiply函数
代码语言:javascript
复制
cv.multiply(src1,src2[,dst[,scale[,dtype]]])
2.3.1 代码测试
代码语言:javascript
复制
import cv2 as cv
import numpy as np

def sums_multiply():
  img1 = cv.imread('./images/butterfly.jpg')
  img2 = cv.imread('./images/lena.jpg')
  print('img1',img1[0,100])
  print('img2',img2[0,100])
  print('乘法',img2[0,100] * img1[0,100])
  print('np.multiply',np.multiply(img2[0,100], img1[0,100]))
  print('cv.multiply',cv.multiply(img2[0,100], img1[0,100]))
if __name__ == "__main__":
  sums_multiply()
2.3.2 测试结果
在这里插入图片描述
在这里插入图片描述
2.4 除法
2.4.0 cv.divide 函数
代码语言:javascript
复制
cv.divide(src1,src2[,dst[,scale[,dtype]]])
2.4.1 代码测试
代码语言:javascript
复制
import cv2 as cv
import numpy as np

def sums_divide():
  img1 = cv.imread('./images/butterfly.jpg')
  img2 = cv.imread('./images/lena.jpg')
  print('img1',img1[0,100])
  print('img2',img2[0,100])
  print('除法',img2[0,100] * img1[0,100])
  print('np.divide',np.divide(img2[0,100], img1[0,100]))
  print('cv.divide',cv.divide(img2[0,100], img1[0,100]))
if __name__ == "__main__":
  sums_divide()
2.4.2 测试结果
在这里插入图片描述
在这里插入图片描述
2.5 注意

注意:

  1. OpenCV加法和Numpy加法之间有区别。OpenCV加法是饱和运算,而Numpy加法是模运算。
  2. 保证不越界,cv.add、cv.subtract、cv.multiply、cv.divide取值范围 [0,255]

3. 图像像素运算

3.1 实例
  1. 读取要图像像素运算的原图片 opencv-logo-white;
  2. 复制一个和原图形状一致的矩阵,数组元素以 0 来填充;由于图像像素运算两个图像必须是一样大小,所以直接复制一个形状一致的矩阵。
  3. 修改矩阵每个元素的颜色为 (110,0,250);
  4. 图像像素加法运算【cv.add】,由于保证不越界,因此相加大于255的值最后的值都是255,如果三通道都是255就是白色;
  5. 图像像素减法运算【cv.subtract】,由于保证不越界,因此相减小于0的值最后的值都是0,如果三通道都是0就是黑色;
  6. 图像像素乘法运算【cv.multiply】,由于保证不越界,因此相乘大于255的值最后的值都是255,如果三通道都是255就是白色,由于复制图片的颜色是(110,0,250),所以除黑色外的颜色就是(255,0,255);
  7. 图像像素除法运算【cv.divide】,由于保证不越界,同时元素的dtype=np.uint8,所以原图像除以(110,0,250),所有元素值都基本是(0,0,0)【黑色】。
代码语言:javascript
复制
import cv2 as cv
import numpy as np

def sums_image():
  image1 = cv.imread("./images/opencv-logo-white.png")
  image2 = np.zeros_like(image1)
  image2[:] = (110,0,250)
  cv.imshow('image1', image1)
  cv.imshow('image2', image2)
  
  # 图像像素加法运算
  add_img = cv.add(image1, image2)
  cv.imshow('add_img', add_img)

  # 图像像素减法运算
  subtract_img = cv.subtract(image1, image2)
  cv.imshow('subtract_img', subtract_img)

  # 图像像素乘法运算
  multiply_img = cv.multiply(image1, image2)
  cv.imshow('multiply_img', multiply_img)

  # 图像像素除法运算
  divide_img = cv.divide(image1, image2)
  cv.imshow('divide_img', divide_img)

  cv.waitKey(0)
  cv.destroyAllWindows()

if __name__ == "__main__":
  sums_image()
3.2 实例结果
在这里插入图片描述
在这里插入图片描述

4. NumPy 算术运算进行图像操作

4.1 实例
代码语言:javascript
复制
import cv2 as cv
import numpy as np

def numpy_image():
  image1 = cv.imread("./images/opencv-logo-white.png")
  image2 = np.zeros_like(image1)
  image2[:] = (110,0,250)
  cv.imshow('image1', image1)
  cv.imshow('image2', image2)
  
  # 图像像素加法运算
  add_img = np.add(image1, image2)
  cv.imshow('add_img', add_img)

  # 图像像素减法运算
  subtract_img = np.subtract(image1, image2)
  cv.imshow('subtract_img', subtract_img)

  # 图像像素乘法运算
  multiply_img = np.multiply(image1, image2)
  cv.imshow('multiply_img', multiply_img)

  # 图像像素除法运算
  divide_img = np.divide(image1, image2)
  cv.imshow('divide_img', divide_img)

  cv.waitKey(0)
  cv.destroyAllWindows()

if __name__ == "__main__":
  numpy_image()
4.2 实例结果
在这里插入图片描述
在这里插入图片描述
4.3 总结
  1. OpenCV和Numpy的加法运算不同,OpenCV的加法运算是饱和运算,而Numpy的加法运算是模运算。
  2. 饱和运算最大的特点是不讲究溢出位,执行结果与底层关系不大;假设变量的类型是8位无符号整型,那么最大数是255,如果在数学上相加的结果大于255,那么饱和运算返回结果就是255。
  3. 模运算考虑溢出位,执行结果需要向计算机底层原理——二进制的方面思考;假设变量的类型是8位无符号整型,那么最大数是255(对应二进制11111111),如果在数学上相加的结果大于255,那么就会发生溢出,仅仅保留容器范围内的二进制位。
  4. 由于饱和运算和模运算的不同,可以看到做相同操作后,两种运算得到的图像差距较大!

5. NumPy 数据类型

名称

说明

bool_

布尔型数据类型(True 或者 False)

int_

默认的整数类型(类似于 C 语言中的 long,int32 或 int64)

intc

与 C 的 int 类型一样,一般是 int32 或 int 64

intp

用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)

int8

字节(-128 to 127)

int16

整数(-32768 to 32767)

int32

整数(-2147483648 to 2147483647)

int64

整数(-9223372036854775808 to 9223372036854775807)

uint8

无符号整数(0 to 255)

uint16

无符号整数(0 to 65535)

uint32

无符号整数(0 to 4294967295)

uint64

无符号整数(0 to 18446744073709551615)

float_

float64 类型的简写

float16

半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位

float32

单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位

float64

双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位

complex_

complex128 类型的简写,即 128 位复数

complex64

复数,表示双 32 位浮点数(实数部分和虚数部分)

complex128

复数,表示双 64 位浮点数(实数部分和虚数部分)

总结

  1. OpenCV加法和Numpy加法之间有区别。OpenCV加法是饱和运算,而Numpy加法是模运算。
  2. 饱和运算最大的特点是不讲究溢出位,执行结果与底层关系不大;假设变量的类型是8位无符号整型,那么最大数是255,如果在数学上相加的结果大于255,那么饱和运算返回结果就是255。
  3. 模运算考虑溢出位,执行结果需要向计算机底层原理——二进制的方面思考;假设变量的类型是8位无符号整型,那么最大数是255(对应二进制11111111),如果在数学上相加的结果大于255,那么就会发生溢出,仅仅保留容器范围内的二进制位。
  4. 保证不越界,cv.add、cv.subtract、cv.multiply、cv.divide取值范围 [0,255]。
  5. 由于图像像素运算两个图像必须是一样大小。
  6. 注意:OpenCV 元素的 dtype 是 np.uint8【无符号整数(0 to 255)】;Numpy 直接定义整数元素的 dtype 是 np.int32【整数(-2147483648 to 2147483647)】。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 知识点
  • 2. NumPy算术操作 和 OpenCV像素运算
    • 2.1 加法
      • 2.1.0 cv.add 函数
      • 2.1.1 代码测试
      • 2.1.2 测试结果
    • 2.2 减法
      • 2.2.0 cv.subtract 函数
      • 2.2.1 代码测试
      • 2.2.2 测试结果
    • 2.3 乘法
      • 2.3.0 cv.multiply函数
      • 2.3.1 代码测试
      • 2.3.2 测试结果
    • 2.4 除法
      • 2.4.0 cv.divide 函数
      • 2.4.1 代码测试
      • 2.4.2 测试结果
    • 2.5 注意
    • 3. 图像像素运算
      • 3.1 实例
        • 3.2 实例结果
        • 4. NumPy 算术运算进行图像操作
          • 4.1 实例
            • 4.2 实例结果
              • 4.3 总结
              • 5. NumPy 数据类型
              • 总结
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档