我在Vscode学OpenCV 基本的加法运算

根据上一篇我们可知__图像的属性

链接:《我在Vscode学OpenCV 处理图像》

属性— API
形状 img.shape
图像大小 img.size
数据类型 img.dtype

 shape:如果是彩色图像,则返回包含行数、列数、通道数的数组;如果是二值图像或者灰度图像,则仅返回行数和列数。通过该属性的返回值是否包含通道数,可以判断一幅图像是灰度图像(或二值图像)还是彩色图像。

 size:返回图像的像素数目。其值为“行×列×通道数”,灰度图像或者二值图像的通道数为 1。

# 用shape()属性
# shape[0]是宽度
# shape[1]是高度
# shape[2]是通道数(深度)
newimg.size 
newimg.shape # (1280, 1706, 3)
#  print(1280*1706*3) 

 dtype:返回图像的数据类型

文章目录

  • 根据上一篇我们可知__图像的属性
  • 三、 图像上的运算
    • 3.1 NumPy的运算
      • 3.1.1 先声明一个比较不好的行为
        • (1)没有限制unitx(x为需要设定的,或者其他的)
        • (2)在OpenCV中,当输出结果的值较大时,会使用科学计数法或指数形式进行表示。
      • 3.1.2 NumPy的 ' + '运算
    • 3.2 cv2.add()函数
      • 3.3 运算
        • (1)上述代码解释:
        • (2)避免错误:不超过最大的计算能力,不除以0(无效值)
    • 3.3 综合说明加法
    • 3.4 目前遇见函数再熟悉
      • (1)fig, axes = plt.subplots(nrows=1, ncols=5, figsize=(10, 8), dpi=100)*
        • 避免:
      • (2)# 用shape()属性
        • 解释
      • (3)size
        • dyte![加粗样式](https://img-blog.csdnimg.cn/20cc70d7fb284c1a955885cb4cb7a6ea.png)

三、 图像上的运算

3.1 NumPy的运算

需要两个图像相同大小
你可以使用OpenCV的cv.add0函数把两幅图像相加,或者可以简单地通过numpy操作添加两个图像,如res= img1 + img2。两个图像应该具有相同的大小和类型,或者第二个图像可以是标量值(即:可以是一个数值)。

注意:OpenCV加法和Numpy加法之间存在差异。OpenCV的加法是饱和操作,而Numpy添加是模运算。

x=np.uint8([250])
y=np.uint8([10])
print(cv.add(x,y))# [[255]]
#原因: (250+10)=260  =>255
print(x+y)# [4]
#原因:  (250+10)=260%256=4

3.1.1 先声明一个比较不好的行为

(1)没有限制unitx(x为需要设定的,或者其他的)
import numpy as np
import cv2 as cv
a=1,123,123
b=2333

print(cv.add(a, b))
print(np.add(a, b))

在Python中,逗号(,)用于分隔多个数值,但它不会像小数点(.)一样表示小数。所以在你的例子中,a被解释为一个整数1,以及两个整数123和123。而b仍然是一个整数2333。

当你使用np.add(a, b)时,Numpy会将a和b作为两个独立的元素进行相加运算。在这种情况下,由于a实际上表示的是3个元素,所以Numpy会将b重复3次,然后进行逐个元素相加的运算。

所以,结果是array([[2334, 2356, 2356]]),每个元素分别是1+2333,123+2333,123+2333。请注意,这与你之前提供的期望结果(array([[2334.],[2456.],[2456.123]]))不同。如果你想得到相同的结果,应该将a定义为一个包含一个元素的列表或数组,即a=[1, 123, 123.123]。

在这里插入图片描述

(2)在OpenCV中,当输出结果的值较大时,会使用科学计数法或指数形式进行表示。

这是为了在输出时节省空间,并使结果更易读。例如,对于一个很大的数字2334,OpenCV可能会以2.334e+03的形式进行表示,其中e+03表示10的3次方,即1000。这种表示方法可以更简洁地表示大数字,并且更容易读取和理解。
加粗样式

3.1.2 NumPy的 ’ + '运算

NumPy的加法是模运算,即当像素值溢出时,会对结果进行取模操作。

mod()是取模运算,“mod(a+b, 256)”表示计算“a+b 的和除以 256 取余数”

需要注意,这是由数组的类型 dtype=np.uint8 所规定的
在这里插入图片描述

3.2 cv2.add()函数

使用函数 cv2.add()对像素值 a 和像素值 b 进行求和运算时,会得到像素值对应图像的饱和值(最大值)。
在这里插入图片描述

形式 1:计算结果=cv2.add(图像 1,图像 2),两个参数都是图像,此时参与运算的图像大小和类型必须保持一致。
 形式 2:计算结果=cv2.add(数值,图像),第 1 个参数是数值,第 2 个参数是图像,此时
将超过图像饱和值的数值处理为饱和值(最大值)。
 形式 3:计算结果=cv2.add(图像,数值),第 1 个参数是图像,第 2 个参数是数值,此时
将超过图像饱和值的数值处理为饱和值(最大值)。

3.3 运算

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

# 1 读取图像
img1 = cv.imread("./Pic/test_img.jpg")
img2 = cv.imread("./Pic/test_img.jpg")

# 2 加法操作
img3 = cv.add(img1,img2) # cv中的加法
img4 = img1+img2 # 直接相加

# 3 图像显示
fig,axes=plt.subplots(nrows=1,ncols=5,figsize=(10,8),dpi=100)
axes[0].imshow(img3[:,:,::-1])
axes[0].set_title("cv中的加法")
axes[1].imshow(img4[:,:,::-1])
axes[1].set_title("直接相加")
axes[2].imshow(img1-img2)
axes[3].imshow(img1*img2)
axes[4].imshow(img1/img2)
plt.show()
(1)上述代码解释:
没问题!以下是代码中每个参数和函数的解释:

```python
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
  • import numpy as np:导入NumPy库,并将其别名设置为np。NumPy提供了高效的数值运算支持。

  • import cv2 as cv:导入OpenCV库,并将其别名设置为cv。OpenCV是一种常用的计算机视觉库,提供各种图像处理功能。

  • import matplotlib.pyplot as plt:从Matplotlib库中导入pyplot模块,并将其别名设置为plt。Matplotlib是一个用于在Python中可视化数据的绘图库。

img1 = cv.imread("./Pic/test_img.jpg")
img2 = cv.imread("./Pic/test_img.jpg")
  • cv.imread("./Pic/test_img.jpg"):使用OpenCV的imread()函数从"./Pic/"目录中读取名为"test_img.jpg"的图像文件。图像数据存储在变量img1img2中。
img3 = cv.add(img1, img2) # cv中的加法
img4 = img1 + img2 # 直接相加
  • cv.add(img1, img2):使用OpenCV的add()函数对img1img2进行逐元素相加操作。该函数将两幅图像对应位置的像素值相加,并返回结果图像,存储在变量img3中。

  • img1 + img2:使用NumPy的加法运算符对img1img2进行逐元素相加操作。它直接相加两幅图像对应位置的像素值,没有限制或约束,并将结果存储在变量img4中。

fig, axes = plt.subplots(nrows=1, ncols=5, figsize=(10, 8), dpi=100)
axes[0].imshow(img3[:, :, ::-1])
axes[0].set_title("cv中的加法")
axes[1].imshow(img4[:, :, ::-1])
axes[1].set_title("直接相加")
axes[2].imshow(img1 - img2)
axes[3].imshow(img1 * img2)
axes[4].imshow(img1 / img2)
plt.show()
  • plt.subplots(nrows=1, ncols=5, figsize=(10, 8), dpi=100):创建一个包含多个子图的图形对象。它创建了一个拥有1行5列的子图网格,指定了大小为(10, 8)英寸和分辨率为100点每英寸(dpi)。生成的图形对象和子图对象分别存储在变量figaxes中。

  • axes[0].imshow(img3[:, :, ::-1]):在第一个子图(axes[0])中显示图像img3img3[:, :, ::-1]用于将OpenCV的BGR颜色格式转换为RGB格式,以便与Matplotlib的imshow()函数显示。

  • axes[0].set_title("cv中的加法"):将第一个子图的标题设置为"cv中的加法"。

  • 类似地,后续的代码行使用不同的图像操作(如减法img1 - img2、乘法img1 * img2和除法img1 / img2)显示并设置其他子图的标题。

  • plt.show():显示包含所有子图的图形对象。
    ``
    在这里插入图片描述

(2)避免错误:不超过最大的计算能力,不除以0(无效值)

在这里插入图片描述
在这里插入图片描述

这个错误是由于在代码中进行图像除法操作时出现了无效值(invalid value)导致的。具体而言,被除数img2中存在某些像素值为零,从而导致了除以零的情况。

要解决这个问题,你可以添加一些额外的处理来处理除以零的情况,例如将零值像素替换为一个非零值或者跳过除以零的计算。

# 处理除以零的情况
with np.errstate(divide='ignore', invalid='ignore'):
    img_divide = np.true_divide(img1, img2)
    img_divide[~np.isfinite(img_divide)] = 0  # 将无限或无效值替换为零
axes[4].imshow(img_divide)

plt.show()

np.errstate()上下文管理器来忽略除法操作中的无效值警告,并使用np.true_divide()进行图像的除法操作。然后,通过使用np.isfinite()函数找到无限或无效值,并将它们替换为零。

这样修改后,应该能够避免除以零的错误并正常显示图像。
在这里插入图片描述

3.3 综合说明加法

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

img1=np.random.randint(0,256,size=[3,3],dtype=np.uint8)
img2=np.random.randint(0,256,size=[3,3],dtype=np.uint8)
print("+")
print("img1=\n" ,img1)
print("img2=\n",img2)

print("img1+img2=\n",img1+img2)

print("\ncv2.add")
print("cv.add(img1,img2)=\n",cv.add(img1,img2))

print("cv.add(1,img2)=\n",cv.add(1,img2))

三次运行的对比:
在这里插入图片描述

当使用加号运算符进行图像像素值相加时,如果和大于255(图像最大像素值),则会对结果进行取模处理。这可能导致本应更亮的像素变暗,因为对于超出255的像素,取模后的值会重新从较小的范围开始。

而使用cv2.add()函数计算图像像素值的和时,将和大于255的值截断为饱和值255。这种饱和操作使得图像像素值增大,整体上图像会变得更亮。

选择使用哪种方法取决于具体的需求和预期效果。如果希望保留图像的动态范围,可以使用加号运算符;如果想要增强图像的亮度,可以使用cv2.add()函数。

3.4 目前遇见函数再熟悉

(1)fig, axes = plt.subplots(nrows=1, ncols=5, figsize=(10, 8), dpi=100)*

该函数的作用是创建一个包含多个子图的图像,并返回一个包含子图的figure对象和一个包含每个子图的axes对象的numpy数组。

参数的作用如下:

  • nrows:指定子图的行数。
  • ncols:指定子图的列数。
  • figsize:指定figure的宽度和高度。
  • dpi:指定图像的分辨率。

fig是一个变量,它接收了函数plt.subplots的返回值,即包含子图的figure对象。你可以使用fig变量来对整个图像进行进一步的操作,例如保存图像、设置标题等。
axes是用于绘制子图的对象,可以在一个figure对象中包含多个axes对象来绘制不同的子图。axes的个数没有特定限制,可以根据需要添加任意数量的子图。

将排列方式更改为5行,每一行一个子图,可以调整 plt.subplots() 函数的 nrows 参数为 5, ncols 参数为 1。


# 创建一个具有5行1列的axes子图网格 fig, axes = plt.subplots(nrows=5, ncols=1)

# 在每个子图中绘制不同的内容 axes[0].plot([1, 2, 3], [4, 5, 6]) axes[1].scatter([1, 2, 3], [4, 5, 6]) axes[2].bar([1, 2, 3], [4, 5, 6]) axes[3].hist([1,
2, 3]) axes[4].plot([3, 2, 1], [6, 5, 4])

# 调整子图的间距 plt.tight_layout()

# 显示图像 plt.show() ```

在这个示例中,我们在每个子图中绘制了不同类型的图表,例如折线图、散点图、柱状图和直方图。要访问每个子图,可以使用 `axes`
对象和索引。最后,我们使用 `plt.tight_layout()` 函数来调整子图的间距,以便更好地展示各个子图。
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

# 1 读取图像
img1 = cv.imread("./Pic/test_img.jpg")
img2 = cv.imread("./Pic/test_img.jpg")

# 2 加法操作
img3 = cv.add(img1,img2) # cv中的加法
img4 = img1+img2 # 直接相加

# 3 图像显示
fig, axes = plt.subplots(nrows=5, ncols=1, figsize=(10, 8), dpi=100)
axes[0].imshow(img3[:, :, ::-1])
axes[0].set_title("cv中的加法")
axes[1].imshow(img4[:, :, ::-1])
axes[1].set_title("直接相加")
axes[2].imshow(img1 - img2)
axes[3].imshow(img1 * img2)

# 处理除以零的情况
with np.errstate(divide='ignore', invalid='ignore'):
    img_divide = np.true_divide(img1, img2)
    img_divide[~np.isfinite(img_divide)] = 0  # 将无限或无效值替换为零
axes[4].imshow(img_divide)



plt.show()

在这里插入图片描述

避免:

个数不匹配
在这里插入图片描述

(2)# 用shape()属性

# 用shape()属性
# shape[0]是宽度
# shape[1]是高度
# shape[2]是通道数(深度)
newimg.size #  print(1280*1706*3) 

newimg.shape # (1280, 1706, 3)

在Python中,shape()是一个NumPy数组对象的方法,可以用于获取数组的形状信息。因此,如果你将图像数据转换为NumPy数组,就可以使用shape()函数来获取其形状信息。

示例代码如下:

import numpy as np
from PIL import Image

# 加载图像
img = Image.open('image.jpg')

# 将图像转换为NumPy数组
img_array = np.array(img)

# 获取图像数组的形状信息
img_shape = img_array.shape

# 打印图像数组的形状信息
print(img_shape)

这样,你就可以通过shape()函数获得图像数组的形状信息,其中==img_shape将是一个元组==,包含图像的宽度、高度和通道数。

解释

在这里插入图片描述
\
在这里插入图片描述
\
在这里插入图片描述
\

  >>> x = np.array([1, 2, 3, 4])
    >>> x.shape
    (4,)
    >>> y = np.zeros((2, 3, 4))
    >>> y.shape
    (2, 3, 4)
    >>> y.shape = (3, 8)
    >>> y
    array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])
    >>> y.shape = (3, 6)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: total size of new array must be unchanged
    >>> np.zeros((4,2))[::2].shape = (-1,)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: Incompatible shape for in-place modification. Use
    `.reshape()` to make a copy with the desired shape.
  1. 首先,创建一个包含四个元素的一维数组x,然后通过x.shape获取其形状,结果是(4,),表示这是一个长度为4的一维数组。

  2. 接着,创建一个由0填充的三维数组y,其形状是(2, 3, 4),表示这是一个2x3x4的三维数组。

  3. 使用y.shape = (3, 8),将y的形状更改为(3, 8),这意味着它现在是一个3x8的三维数组。原始数据保持不变,但形状改变了。

  4. 接下来,尝试将y的形状更改为(3, 6),但这会引发一个ValueError,因为新的形状要求数组的总大小必须保持不变。在这种情况下,新形状(3, 6)的总大小(18)与原始形状(3, 8)的总大小(24)不同,所以抛出了异常。

  5. 最后一个示例尝试将形状应用于使用切片的数组np.zeros((4, 2))[::2],它会引发AttributeError,因为这种情况下的切片不允许原地修改形状。提示建议使用.reshape()方法,以便创建一个具有所需形状的副本。

总之,shape属性允许你更改NumPy数组的形状,但要确保新形状的总大小与原始形状的总大小一致。如果无法在原地修改形状,则需要使用.reshape()方法来创建一个新数组。

(3)size

在这里插入图片描述

dyte加粗样式

**

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/115023.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java高级互联网架构师之路:垃圾回收器的介绍

本文重点 从本文开始我们将开启垃圾回收器的介绍了,我们知道垃圾回收算法是逻辑改变,而垃圾回收器是具体的实现。我们前面介绍的垃圾回收器有7个,本文将在添加三个,但是这三个目前来看不是很常用,我们只了解一下,我们主要还是讲解这7个垃圾回收器。 十个垃圾回收器 目…

【漏洞库】XXL-JOB 默认accessToken权限绕过导致RCE

文章目录 漏洞描述漏洞编号漏洞评级影响版本漏洞复现- EXP 编写 漏洞挖掘修复建议 漏洞描述 XXL-JOB 是一款开源的分布式任务调度平台&#xff0c;用于实现大规模任务的调度和执行。 XXL-JOB 默认配置下&#xff0c;用于调度通讯的 accessToken 不是随机生成的&#xff0c;而…

如何记录每天的工作日程?电脑手机通用的日程管理软件

在工作时间有限&#xff0c;但工作任务愈加繁多的现在职场中&#xff0c;要求每一个职场人士做好高效日程管理。通过高效管理日程&#xff0c;我们可以更好地组织和安排任务&#xff0c;合理分配时间和优先级&#xff0c;这有助于我们更专注地进行工作&#xff0c;减少时间的浪…

手写操作系统篇:实现裸机应用程序

文章目录 前言操作系统执行环境创建裸机平台项目Rust的Core库移除标准库依赖Qemu 启动流程内存布局编译流程内核的初始指令调整内核的内存布局手动加载内核可执行文件使用RustSBI提供的服务添加bootloader模块添加Makefile运行停止总体架构 前言 我们既然是手写操作系统&#…

行业追踪,2023-11-03

自动复盘 2023-11-03 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

学习小结,学而时习之,坚持学习之,温顾学习之

学习python一个多月了&#xff0c;之前也有接触过&#xff0c;还花了不少钱报班&#xff0c;看了看入门的头两节课&#xff0c;就止步了。每一种编程语言的入门感觉都差不多&#xff0c;学到现在&#xff0c;我对python的基本数据类型还是没掌握好啊&#xff0c;每次列表字典怎…

js 根据word文档模板导出内容

一、创建word导出模板 1、本地创建一个test.docx 2、将最终需要的文档内容及样式编辑完成(图1) 3、将所需动态值的位置,替换为变量参数(图2) 注: 动态值书写 图1 图2 模板值的书写要求 二、项目中使用 1、安装依赖 npm install docxtemplater-image-module-free --save n…

4+m6A+机器学习+分型,要素过多,没有思路的同学可借鉴

今天给同学们分享一篇生信文章“Diagnostic, clustering, and immune cell infiltration analysis of m6A regulators in patients with sepsis”&#xff0c;这篇文章发表在Sci Rep.期刊上&#xff0c;影响因子为4.6。 结果解读&#xff1a; 脓毒症中m6A调节因子的转录改变 …

[PyTorch][chapter 61][强化学习-免模型学习1]

前言&#xff1a; 在现实的学习任务中&#xff0c;环境 其中的转移概率P,奖赏函数R 是未知的&#xff0c;或者状态X也是未知的 称为免模型学习&#xff08;model-free learning&#xff09; 目录&#xff1a; 1: 蒙特卡洛强化学习 2&#xff1a;同策略-蒙特卡洛强化学习 3&am…

非关系型数据库Redis的安装【Linux】及常用命令

前言 Redis&#xff08;Remote Dictionary Server&#xff09;是一种开源的内存数据库管理系统&#xff0c;它以键值存储方式来存储数据&#xff0c;并且支持多种数据结构&#xff0c;如字符串、哈希、列表、集合、有序集合等。Redis最初由Salvatore Sanfilippo开发&#xff0c…

Java配置47-Spring Eureka 未授权访问漏洞修复

文章目录 1. 背景2. 方法2.1 Eureka Server 添加安全组件2.2 Eureka Server 添加参数2.3 重启 Eureka Server2.4 Eureka Server 升级版本2.5 Eureka Client 配置2.6 Eureka Server 添加代码2.7 其他问题 1. 背景 项目组使用的 Spring Boot 比较老&#xff0c;是 1.5.4.RELEASE…

React使用富文本CKEditor 5,上传图片并可设置大小

上传图片 基础使用&#xff08;标题、粗体、斜体、超链接、缩进段落、有序无序、上传图片&#xff09; 官网查看&#xff1a;https://ckeditor.com/docs/ckeditor5/latest/installation/integrations/react.html 安装依赖 npm install --save ckeditor/ckeditor5-react cked…

【window系统】win10家庭版没有hyper-V的选项 问题解决办法

目录 事件起因环境和工具操作过程参考内容结束语 事件起因 在给我的新电脑安装docker和对应的Linux环境时 在 控制面版-程序-启用该或关闭Windows功能 时 没有找到对应网上那种教程里的Hyper-V的功能的选项&#xff0c;查找了一下&#xff0c;说是win10家庭版没有这个功能 专…

速学数据结构 | 循环队列怎么写才最高效?只需要掌握这些技巧

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《Linux深造日志》《C干货基地》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 &#x1f4cb; 前言一、什么是循环队列&#xff1f;二、如何实现循环队列&#xff1f;2.1 循环队列的结构2.2 循环…

SpringBoot集成MyBatis-Plus

SpringBoot集成MyBatis-Plus 文章目录 SpringBoot集成MyBatis-Plusapplication.ymlpom.xmlpojomapperserviceserviceimplconfigutilsweb 懒得打一遍&#xff0c;直接copy&#xff1a; SpringBoot集成MyBatis-Plus application.yml # 端口 server:port: 8080 # 数据源 spring:…

期中成绩怎么发布?

作为一名老师&#xff0c;期中考试结束后&#xff0c;你可能正在为如何发布成绩而烦恼。传统的纸质方式不仅耗时而且容易出错&#xff0c;那么有没有一种方式可以让学生自助查询成绩呢&#xff1f;答案是肯定的。下面就为你介绍几种实用的方法&#xff0c;让成绩发布变得轻松又…

默认路由配置

默认路由&#xff1a; 在末节路由器上使用。&#xff08;末节路由器是前往其他网络只有一条路可以走的路由器&#xff09; 默认路由被称为最后的关卡&#xff0c;也就是静态路由不可用并且动态路由也不可用&#xff0c;最后就会选择默认路由。有时在末节路由器上写静态路由时…

性能优于BERT的FLAIR:一篇文章入门Flair模型

文章目录 What is FLAIR&#xff1f;FLAIR ModelContextual String Embedding for Sequence Labelingexample FLAIR Application AreaSentiment AnalysisNamed Entity RecognitionText Classification FLAIR一、什么是FLAIR&#xff1f;二、FLAIR Library的优势是什么&#xff…

日本it培训学费 想去日本做IT,需要具备哪些技术?

日本的IT行业历史比较悠久&#xff0c;业务以上层前端业务为主&#xff0c;如设计和构建软件。日本IT公司组织庞大&#xff0c;行业内部有着严格的分工和部署&#xff0c;工作会被细分化&#xff0c;分配给个人的工作量不会太大&#xff0c;难度也不会很高&#xff0c;所以日本…

【JAVA学习笔记】59 - JUnit框架使用、本章作业

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter15/src/com/yinhai/homework JUnit测试框架 1.基本介绍 1. JUnit是一个Java语言的单元测试框架 2.多数Java的开发环境都已经集成了JUnit作为单元测试的工具 2.如何使用 创建方法后&#x…