OpenCV(六)——对于图片的算术运行、图片的叠加操作、多通道图像拆分为多个单通道图像

本文主要是介绍OpenCV(六)——对于图片的算术运行、图片的叠加操作、多通道图像拆分为多个单通道图像,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在OpenCV中,可以对于图片进行算法运算。我们知道,图像的本质其实就是矩阵,因此对于图像的算数运算本质上就是对于矩阵的算术运算。在OpenCV可以对图像进行算术运算的操作有加、减、乘、除等操作。

图像的加、减、乘、除操作

两张图像可以进行算术运算操作,即对两图像的矩阵进行加减操作。例如,文件夹中有两张图片:

现在想把这两张图像加起来,首先先获取两张图片的行数和列数:

import cv2
import matplotlib.pyplot as plt
import numpy as npimg1=cv2.imread(r'D:\Photo\1.jpeg')
img2=cv2.imread(r'D:\Photo\2.jpeg')
print(img1.shape)
print(img2.shape)

运行结果如下所示:

(500, 500, 3)
(500, 667, 3)

 可以看到两张图片的行数相等,但是列数第二张图片的列数较大,因此在如果两个图像要进行算术运算操作,需要行数和列数需要保持一致,因此只能将图像截取。

(1)将上面两张图片进行相加操作:

import cv2
import matplotlib.pyplot as plt
import numpy as npimage_dog=cv2.imread(r'D:\Photo\1.jpeg')
image_cat=cv2.imread(r'D:\Photo\2.jpeg')
image_cat=cv2.resize(image_cat,(500,500))
image_new=image_cat+image_dog
cv2.imshow('image_new',image_new)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果如下所示:

可以看到,图片的所运行出来的结果就是每一个像素进行叠加,运行出来的结果为上图所示。

(2)同样,也可以进行相减的操作,只需要将上面代码中的image_new=image_cat-image_dog即可。即为:

image_new=image_cat-image_dog

运行结果如下所示:

(3)同样,也可以进行相乘的操作,只需要将上面代码中的image_new=image_cat*image_dog即可。

image_new=image_cat*image_dog

运行结果如下所示:

由于相乘结果数值相差较大,因此所得到的结果比较混乱。 

(4)图像的算数操作同样可以对数进行操作,例如将图像所对应的矩阵里的数全部除以2,代码为:

import cv2
import matplotlib.pyplot as plt
import numpy as npimg_dog=cv2.imread(r'D:\Photo\1.jpeg')
res=img_dog//2
plt.imshow(res)

运行结果为:

通过图片可以看出图片整体变暗了,原因是图片对应的矩阵的值变为原来的一半。 

图片的叠加

(1)图片不可以这样简单地进行算数运算,同时也可以进行叠加(即为图像的加权融合),在OpenCV使用cv2.addWeigthed()进行叠加。在cv2.addWeighted()中,至少需要输入四个参数,即为第一个需要加权融合的图片,第一个图片所占的权重,第二个需要加权融合的图片,第二个图片所占的权重,例如:

import cv2
import matplotlib.pyplot as plt
import numpy as npimg_dog=cv2.imread(r'D:\Photo\1.jpeg')
img_cat=cv2.imread(r'D:\Photo\2.jpeg')
img_cat=cv2.resize(img_cat,(500,500))
res=cv2.addWeighted(img_cat,0.5,img_dog,0.5,0)
plt.imshow(res)

运行效果如下所示:

(2)此时两张图片的权重各占0.5,如果修改权重,将image_cat改为0.7,image_dog改为0.3,那么只需修改代码:

res=cv2.addWeighted(img_cat,0.7,img_dog,0.3,0)

运行效果为:

可以看到,当image_cat为0.7,image_dog为0.3的时候,可以看到猫的图片占据了主导地位。

(3)需要说明的是,图片的叠加可以用图片的算术操作完成,例如加权融合的权重为0.5时,下面两句代码效果等效:

res=cv2.addWeighted(img_1,0.5,img_2,0.5,0)
res=img_1//2+img_1//2

用上面的例子进行验证:

import cv2
import matplotlib.pyplot as plt
import numpy as npimg_dog=cv2.imread(r'D:\Photo\1.jpeg')
img_cat=cv2.imread(r'D:\Photo\2.jpeg')
img_cat=cv2.resize(img_cat,(500,500))
res1=cv2.addWeighted(img_cat,0.5,img_dog,0.5,0)
res2=img_cat//2+img_dog//2
cv2.imshow('res1',res1)
cv2.imshow('res2',res2)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行效果如下所示:

可以看到完全相同,所以对图片进行融合的时候两种方法都可以。

多通道图像拆分为多个单通道图像

在OpenCV中利用cv2.split()将多个颜色通道图像(例如BGR格式的彩色图像)拆分为多个单独的灰色图像,每个灰度图像代表原图像的一个颜色通道。

注:split()函数需要完成三个任务:

  • 通道分离:它可以将一个三通道的BGR图像分离成三个单通道的灰度图像,分别是蓝色、绿色和红色通道。
  • 数据结构:split()函数可以接受两种类型的输出参数,一种是Mat数组,另一种是std::vector<Mat>。在Python中,通常使用numpy数组来接收分离后的通道。
  • 使用方式:当你有一个Mat对象表示的图像时,可以调用split()函数并传入该对象以及一个用于存放结果的数组或向量。这样,原图像的每个通道就会被提取出来并存储在指定的位置。

例如:

import cv2
import matplotlib.pyplot as plt
import numpy as np#颜色通道提取
img=cv2.imread(r'D:\Photo\1.jpeg')
b,g,r=cv2.split(img)
print('b通道\n')
print(b)
print('g通道\n')
print(g)
print('r通道\n')
print(r)

 运行结果为:

b通道[[186 186 186 ...  30  41  34][186 186 186 ...  39  46  36][186 186 186 ...  39  41  29]...[160 161 165 ...  37  59 101][160 161 163 ...  42  39  62][154 155 157 ...  62  40  52]]
g通道[[118 118 118 ...  51  61  54][118 118 118 ...  59  66  56][118 118 118 ...  59  61  49]...[177 178 181 ...  73  95 137][177 178 180 ...  76  72  96][171 172 173 ...  96  74  85]]
r通道[[ 70  70  70 ...  45  55  48][ 70  70  70 ...  53  60  51][ 70  70  70 ...  53  55  44]...[188 189 192 ...  81 103 145][188 189 191 ...  84  81 104][182 183 184 ... 104  82  93]]

通过上面结果可以看到一张RGB图像分成了三个通道,每个通道有不同的数据内容。而不同颜色通道的图片是什么样子的呢?下面我们分别展示B、G、R通道:

import cv2
import matplotlib.pyplot as plt
import numpy as npimg=cv2.imread(r'D:\Photo\1.jpeg')
#只保留R通道
cur_img1=img.copy()
cur_img1[:,:,0]=0
cur_img1[:,:,1]=0
#只保留G通道
cur_img2=img.copy()
cur_img2[:,:,0]=0
cur_img2[:,:,2]=0
#只保留B通道
cur_img3=img.copy()
cur_img3[:,:,1]=0
cur_img3[:,:,2]=0
cv2.imshow('R通道',cur_img1)
cv2.imshow('G通道',cur_img2)
cv2.imshow('B通道',cur_img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果如下所示:

上面通道所展示的结果是B通道、G通道、R通道所呈现的内容。

这篇关于OpenCV(六)——对于图片的算术运行、图片的叠加操作、多通道图像拆分为多个单通道图像的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/797207

相关文章

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Python利用PIL进行图片压缩

《Python利用PIL进行图片压缩》有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所以本文为大家介绍了Python中图片压缩的方法,需要的可以参考下... 有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所有可以对文件中的图

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

java获取图片的大小、宽度、高度方式

《java获取图片的大小、宽度、高度方式》文章介绍了如何将File对象转换为MultipartFile对象的过程,并分享了个人经验,希望能为读者提供参考... 目China编程录Java获取图片的大小、宽度、高度File对象(该对象里面是图片)MultipartFile对象(该对象里面是图片)总结java获取图片

Java实战之自助进行多张图片合成拼接

《Java实战之自助进行多张图片合成拼接》在当今数字化时代,图像处理技术在各个领域都发挥着至关重要的作用,本文为大家详细介绍了如何使用Java实现多张图片合成拼接,需要的可以了解下... 目录前言一、图片合成需求描述二、图片合成设计与实现1、编程语言2、基础数据准备3、图片合成流程4、图片合成实现三、总结前

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

Python利用自带模块实现屏幕像素高效操作

《Python利用自带模块实现屏幕像素高效操作》这篇文章主要为大家详细介绍了Python如何利用自带模块实现屏幕像素高效操作,文中的示例代码讲解详,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、获取屏幕放缩比例2、获取屏幕指定坐标处像素颜色3、一个简单的使用案例4、总结1、获取屏幕放缩比例from