☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░
一、引言
在写该文之前,老猿就图像的一些运算已经单独边学边发了,在写这些文的过程中,发现这些运算函数共同点很多,例如大部分参数一样、部分处理方法一样等,另外还有些函数可以实现相同或近似的效果,因此在前面那些文章的基础上,将其综合为一个整体来发布,更方便大家阅读。
OpenCV中图像存储为矩阵,因此图像的运算其实就是矩阵的运算。图像的运算主要包括图像基础算术运算、图像加权运算(又称为图像融合)、按位运算等类别。这些运算可以直接通过numpy矩阵进行,也可以通过opencv的专用方法进行,但opencv的矩阵运算和numpy矩阵运算还是有些不同。例如在加法处理上,OpenCV加法是饱和运算(超过255即按255),而Numpy加法是模运算(超过255按256取模的结果作为结果)。对加法来说,颜色值越大OpenCV 的结果会更好,因此推荐使用opencv的进行算术运算。本文的内容全部基于OpenCV的方法进行介绍。
二、OpenCV图像运算语法
2.1、图像运算函数列表
OpenCV图像运算包括如下函数:
加法运算:add(src1, src2, dst=None, mask=None, dtype=None)
减法运算:subtract(src1, src2, dst=None, mask=None, dtype=None)
乘法运算:multiply(src1, src2, dst=None, scale=None, dtype=None)
除法运算:divide(src1, src2, dst=None, scale=None, dtype=None)
幂运算:pow(src, power, dst=None)
开方运算:sqrt(src, dst=None)
自然常数e为底的指数函数:exp(src, dst=None)
对数运算:log(src, dst=None)
融合权重加法:addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=None)
位与运算:bitwise_and(src1, src2, dst=None, mask=None)
位或运算:bitwise_or(src1, src2, dst=None, mask=None)
位异或运算:bitwise_xor(src1, src2, dst=None, mask=None)
位非运算:bitwise_not(src, dst=None, mask=None)
2.2、图像运算常用参数说明
src:输入图像矩阵
src1、src2:两副大小和通道数相等的输入图像或一副输入图像和一个标量(关于标量请参考《OpenCV-Python中的标量Scalar是什么》)
dst:目标图像输出,要求与输入图像大小相同,如果传值则可以直接以实参作为目标图像存储变量,否则可以用函数返回值作为目标图像存储变量,在实参非None传入的情况下,返回值与该实参值相同
scale:缩放因子,图像运算时,先执行src1*scale,再以该乘积进行后续运算
mask:图像掩膜,可选参数,为8位单通道的灰度图像,用于指定要更改的输出图像数组的元素,即输出图像像素只有mask对应位置元素不为0的部分才输出,否则该位置像素的所有通道分量都设置为0。更多关于掩膜的内容请参考《OpenCV学习02-矩阵的掩膜操作》
dtype:可选参数,输出图像数组的深度,即图像单个像素值的位数(如RGB用三个字节表示,则为24位)。在帮助文档中介绍,参数src1和src2可以有不同的图像深度(即图像像素位数,如8位、16位、24位和32位),如可以将16位图像和一个8位图像相加将输出结果保存在32位输出数组中。关于这个参数老猿研究可很长时间,因为认为如果图像深度不一样,意味着图像的通道数也不一样,通道数不一样,意味着数组大小不一样,这样的两个数组无法进行运算。后来机缘契合下自认为理解了,这里说的图像深度不是通道数*8,而是单个通道值表示的位数,即单通道不一定是8位的,也可以是16位、24位或32位的。看如下代码就明白了:
def main():
img1 = cv2.imread(r'F:\pic\shape1.png').astype(np.float32)
img2 = cv2.imread(r'F:\pic\shape2.png')
img = cv2.add(img1,img2,dtype=24)
上述代码将以两种不同表示方法读入两副图像,第一幅图像是以float32来表示图像单通道值,第二幅图像是缺省值uint8来表示图像单通道值,二者机器位数不同,但相加之后转为了24位图像,即单通道为8字节图像。
2.3、部分图像运算函数详解
针对部分重要的图像运算,老猿在前面已经单独进行了介绍,包括:
OpenCV-Python图像的加法运算cv2.add函数详解
OpenCV-Python图像的减法运算cv2.subtract函数详解以及和矩阵减法的差异对比
OpenCV-Python图像乘法运算cv2.multiply函数详解及像素值溢出归一化处理
OpenCV-Python图像除法运算cv2.divide函数及图像相除处理
OpenCV-Python图像融合cv2.addWeighted权重加法函数详解
OpenCV-Python图像位与运算bitwise_and函数详解
2.4、其他图像运算函数简介
幂运算:pow(src, power, dst=None),对图像的每个通道值计算power参数对应的幂作为结果图像的通道值,如果power为整数,则直接计算幂值,如果power为浮点数,则取通道值的绝对值参与计算,即:
开方运算:sqrt(src, dst=None),对图像的每个通道值开方作为结果图像的通道值,即:dst(I)=sqrt(src1(I))
自然常数e为底的指数函数:exp(src, dst=None),以e为底对图像的每个通道值作为幂值计算结果图像的通道值,即:
对数运算:log(src, dst=None),计算图像的每个通道值的自然对数作为结果图像的通道值,即:dst(I)=ln(src(I))
位或运算:bitwise_or(src1, src2, dst=None, mask=None),计算两副图像每个通道值或一图像通道值与一个标量的按位或的结果作为结果图像的通道值
位异或运算:bitwise_xor(src1, src2, dst=None, mask=None),计算两副图像每个通道值或一图像通道值与一个标量的按位异或的结果作为结果图像的通道值
位非运算:bitwise_not(src, dst=None, mask=None),将src图像的每个通道值按位取反作为结果图像的值。
三、相关函数的作用分析
图像的减法、除法以及异或都可以用于分析图像的差异点,但减法和异或更准确 ;
加法、权重加法以及图像或运算都可以用于合并图像,但由于运算方法与差异,效果会有不同,针对不同图像的融合选择哪种方法与图像数据及应用的目标相关;
图像的自乘、幂运算都可以用于调整图像的对比度;
非运算及异或运算可以将图像的一部分图像的视觉效果提高;
图像乘法、位与都可以用于提取图像的感兴趣部分或者屏蔽某些部分,在这方面的功能与图像掩码的效果相同,只是实现方式不同;
通过阈值处理、图像求反、与处理等可以提取图像中的结构特征
四、按位运算的简单案例
前面部分图像运算函数详解中举例介绍了图像加减乘除权重加及位与的相关功能,在此补充一个简单的按位运算的案例。代码如下:
import numpy as np
import cv2
def main():
img1 = cv2.imread(r'F:\pic\shape1.png').astype(np.float32)
img2 = cv2.imread(r'F:\pic\shape2.png')
resultImgAnd = cv2.bitwise_and(img1, img2)
resultImgOr = cv2.bitwise_or(img1, img2)
resultImgXor = cv2.bitwise_xor(img1, img2)
resultImgNot = cv2.bitwise_not(img1)
resultImgXorScalar = cv2.bitwise_xor(img1, (255,255,255,255))
cv2.imshow('img1',img1)
cv2.imshow('img2', img2)
cv2.imshow('resultImgAnd', resultImgAnd)
cv2.imshow('resultImgOr', resultImgOr)
cv2.imshow('resultImgXor', resultImgXor)
cv2.imshow('resultImgNot', resultImgNot)
cv2.imshow('resultImgXorScalar', resultImgXorScalar)
cv2.waitKey(0)
main()
运行显示的图片截屏:
五、小结
本文详细介绍了OpenCV-Python图像的加减乘除幂开方对数及位运算相关的函数及语法,并总结了相关函数的作用。OpenCV中图像存储为矩阵,因此图像的运算其实就是矩阵的运算。图像的运算主要包括图像基础算术运算、图像加权运算(又称为图像融合)、按位运算等类别。这些运算可以直接通过numpy矩阵进行,也可以通过opencv的专用方法进行,但opencv的矩阵运算是饱和运算,其运算效果比纯粹的矩阵运算效果更好。
更多OpenCV-Python介绍请参考专栏《OpenCV-Python图形图像处理 》
专栏网址:https://blog.csdn.net/laoyuanpython/category_9979286.html
关于老猿的付费专栏
老猿的付费专栏《使用PyQt开发图形界面Python应用 》(https://blog.csdn.net/laoyuanpython/category_9607725.html)专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》 (https://blog.csdn.net/laoyuanpython/category_10232926.html)详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏都适合有一定Python基础但无相关知识的小白读者学习。
付费专栏文章目录:《moviepy音视频开发专栏文章目录》(https://blog.csdn.net/LaoYuanPython/article/details/107574583)、《使用PyQt开发图形界面Python应用专栏目录 》(https://blog.csdn.net/LaoYuanPython/article/details/107580932)。
对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》(https://blog.csdn.net/laoyuanpython/category_9831699.html)从零开始学习Python。
如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。
跟老猿学Python、学OpenCV!
☞ ░ 前往老猿Python博文目录 https://blog.csdn.net/LaoYuanPython ░