Opencv在图像上的算术运算

图像上的算术运算

1.图像加法

图像相加:一般用于对同一场景的多幅图像求平均,以便有效地降低(additive)随机噪声。

利用求平均的方法降低噪声信号提高信噪比的做法,只有当噪声可以用同一个独立分布的随机模型描述时才会有效。

作用:图像混合和降噪

使用函数 cv2.add() 将两幅图像进行加法运算,当然也可以直接使用 numpy,res=img1+img。两幅图像的大小,类型必须一致,或者第二个图像可以使一个简单的标量值。

cv2.add(src1, src2, mask) 

参数意义如下:

  • scr1:输入的第一幅图像
  • scr2:输入的第二幅图像
  • mask:可选,掩膜

补充:在有些图像处理的函数中有的参数里面会有mask参数,即此函数支持掩膜操作,首先何为掩膜以及有什么用,如下:

数字图像处理中的掩膜的概念是借鉴于PCB制版的过程,在半导体制造中,许多芯片工艺步骤采用光刻技术,用于这些步骤的图形“底片”称为掩膜(也称作“掩模”),其作用是:在硅片上选定的区域中对一个不透明的图形模板遮盖,继而下面的腐蚀或扩散将只影响选定的区域以外的区域。
图像掩膜与其类似,用选定的图像、图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。
数字图像处理中,掩模为二维矩阵数组,有时也用多值图像,图像掩模主要用于:
①提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。
②屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
③结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。
④特殊形状图像的制作。

区别:OpenCV 中的加法与 Numpy 的加法是有所不同的。OpenCV 的加法是一种饱和操作,而 Numpy 的加法是一种模操作。

例子:

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

这种差别在你对两幅图像进行加法时会更加明显。OpenCV 的结果会更好一点。所以我们尽量使用 OpenCV 中的函数。

例子

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

def img_show(name,img):
    """matplotlib图像显示函数
    name:字符串,图像标题
    img:numpy.ndarray,图像
    """
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    plt.imshow(img,'gray')
    plt.xticks([])
    plt.yticks([])
    plt.xlabel(name,fontproperties='FangSong',fontsize=12)
    

if __name__=="__main__":

    img1 = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
    img2 = cv2.imread("art-exhibition-art-gallery-artwork-2110937.jpg")
    print(img1.shape)
    print(img2.shape)
    img3 = img1.copy() # 复制img1
    img3 = img3[:3339,:5008] # 裁剪图像使img3与img2图像大小一致
    print(img3.shape)
    img4 = img2+img3
    img5 = cv2.add(img2,img3)
    # 图像显示
    plt.figure(figsize=(12,8),dpi=80)
    plt.subplot(221)
    img_show('img2',img2)
    plt.subplot(222)
    img_show('img3',img3)
    plt.subplot(223)
    img_show('numpy中img2+img3',img4)
    plt.subplot(224)
    img_show('Opencv中img2+img3',img5)
(3351, 5026, 3)
(3339, 5008, 3)
(3339, 5008, 3)
加法.png

2.图像混合

cv2.scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst)

可以按下面的公式对图片进行混合操作
d s t=\alpha \cdot src 1+ src 2

cv2.addWeighted(InputArray src1, double alpha, InputArray src2,double beta, double gamma,OutputArray dst, int dtype=-1)

这其实也是加法,但是不同的是两幅图像的权重不同,这就会给人一种混合或者透明的感觉。图像混合的计算公式如下:
g(x)=(1-\alpha) f_{0}(x)+\alpha f_{1}(x)
通过修改 α 的值(0 → 1),可以实现非常酷的混合。现在我们把两幅图混合在一起。第一幅图的权重是 0.6,第二幅图的权重是 0.4。函数 cv2.addWeighted() 可以按下面的公式对图片进行混合操作。
d s t=\alpha \cdot src 1+\beta \cdot src 2+\gamma
这里γ的取值为 0。

img1 = cv2.imread("fashion-fun-model-2191055.jpg")
img2 = cv2.imread("delicious-food-food-photography-2111987.jpg")
print(img1.shape)
print(img2.shape)
img3 = img1.copy()
img3 = img3[:4611,:3451]
print(img3.shape)

dst = cv2.addWeighted(img2,0.6,img3,0.4,0)

plt.figure(figsize=(8,20),dpi=80)
plt.subplot(131)
img_show('img2',img2)
plt.subplot(132)
img_show('img3',img3)
plt.subplot(133)
img_show('图像混合',dst)
(6000, 4000, 3)
(4611, 3451, 3)
(4611, 3451, 3)
图像混合.png

3.图像相减

图像相减即在两幅图像之间对应像素做减法运算。图像相减可以检测出两幅图像的差异信息,因此这项技术在工业、医学、气象以及军事等领域中都有广泛的应用。
主要应用:
(1)去除一幅图像中不需要的图案,如缓慢变化的背景阴影,周期性噪声等;
(2)检测同一场景的两幅图像之间的变化
(3)运动检测

cv2.subtract(src1, src2, mask)

参数意义参见cv2.add()。

img1 = cv2.imread("lenaNoise.png")
img2 = cv2.imread("lena.jpg")

img3 = cv2.subtract(img1,img2)

plt.figure(figsize=(10,8),dpi=80)
plt.subplot(231)
img_show('lenaNoise',img1)
plt.subplot(232)
img_show('lena',img2)
plt.subplot(233)
img_show('图像相减',img3)
subtract.png

4.乘法运算

可以用来实现掩模处理,即屏蔽掉图象的某些部分。此外由于时域的卷积和相关运算与频域的乘积运算对应,因此乘法运算有时也被用来做为一种技巧来实现卷积或相关处理。

cv2.multiply(src1, src2)

5.除法运算

可用于校正成像设备的非线性影响,在特殊形态的图像(如断层扫描等医学图像)处理中用到。也可用于校正照明不足或者传感器的非线性影响造成的偏差。

cv2.divide(src1, src2)

6.按位运算

按位操作有:AND,OR,NOT,XOR 等。

  • 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
cv2.bitwise_and(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray()) # dst = src1 & src2
cv2.bitwise_or(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray()) # dst = src1 | src2
cv2.bitwise_xor(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray()) # dst = src1 ^ src2
cv2.bitwise_not(InputArray src, OutputArray dst,InputArray mask=noArray()) # dst = ~src

当我们提取图像的一部分,选择非矩形 ROI 时这些操作会很有用(下一章你就会明白)。下面的例子就是教给我们如何改变一幅图的特定区域。我想把 OpenCV 的标志放到另一幅图像上。如果我使用加法,颜色会改变,如果使用混合,会得到透明效果,但是我不想要透明。如果它是矩形我可以使用 ROI。但是它不是矩形。但是我们可以通过下面的按位运算实现:

img1 = cv2.imread("delicious-food-food-photography-2111987.jpg")
img2 = cv2.imread("opencv-logo.png")

# 创建一个ROI,并放在左上角
rows,cols,channels = img2.shape
roi = img1[0:rows,0:cols]

# 创建一个mask,并创建一个inverse mask
img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
ret,mask = cv2.threshold(img2gray,175,255,cv2.THRESH_BINARY) #阈值处理,后面内容会详细介绍
mask_inv = cv2.bitwise_not(mask)

# logo的白色区域为感兴趣的区域ROI
# 取roi中与mask中不为零的值对应的像素的值,其他值为0
# 注意这里必须有mask=mask或者mask=mask_inv,其中mask=不能忽略
img1_bg = cv2.bitwise_and(roi,roi,mask=mask)
# 取roi中与mask_inv中不为零的值对应的像素的值,其他值为0。
# Take only region of logo from logo image.
img2_fg = cv2.bitwise_and(img2,img2,mask=mask_inv)

# 将logo中的ROI放到主图像中
dst = cv2.add(img1_bg,img2_fg)
img3 = img1.copy()
img3[0:rows,0:cols] = dst

# 显示图像
plt.figure(figsize=(20,8),dpi=80)
plt.subplot(241)
img_show('img1',img1)
plt.subplot(242)
img_show('img2',img2)
plt.subplot(243)
img_show('roi',roi)
plt.subplot(244)
img_show('mask',mask)
plt.subplot(245)
img_show('mask_inv',mask_inv)
plt.subplot(246)
img_show('img2_fg',img1_bg)
plt.subplot(247)
img_show('img2_fg',img2_fg)
plt.subplot(248)
img_show('图像混合',img3)
位caozuo.png

7.其他算数运算

cv2.sqrt(InputArray src, OutputArray dst) # 计算每个矩阵元素的平方根
cv2.pow(InputArray src, double power, OutputArray dst) # src的power次幂
cv2.exp(InputArray src, OutputArray dst) # dst = e**src(**表示指数的意思)
cv2.log(InputArray src, OutputArray dst) # dst = log(abs(src))

更多详情请参考opencv官网。

参考资料:
网址:
https://blog.csdn.net/Gavinmiaoc/article/details/80856246
https://blog.csdn.net/u011028345/article/details/77278467
书籍:《数字图像处理》《OpenCV-Python-Toturial-中文版》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,873评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,483评论 1 306
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,525评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,595评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,018评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,958评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,118评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,873评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,643评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,813评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,293评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,615评论 3 262
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,306评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,170评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,968评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,107评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,894评论 2 278