opencv 图像加法add(), +, addWeighted(),图像减法 subtract(), - ,absdiff(),图像乘法multiply(),*,图像除法,divide(),/

dtype参数不是用numpy的uint8,float32等数据类型,而是采用OpenCV的CV_8UC1、CV_32FC1等数据类型。
图像相加
1.add()

img = cv2.imread('..\\lena.jpg')[0:512,0:512] #截取部分,保证大小一致
img2 = cv2.imread('..\\opencv-logo.png' )[0:512,0:512]
img3 = cv2.add(img,img2)
cv2.imshow('add',img3)
cv2.waitKey(0)

在OpenCV中图像的算术运算遵循“饱和运算”的规则,如果计算的结果超过了阈值范围,则就近进行截断,比如unit8类型的数据范围是【0,255】,如果2个数值直接相加的结果大于255就会赋值为255.
2.+运算符
+运算符将2个图像相加,当2个值相加大于255时,会将这个值对256求余得到新的像素值。
3.addWeighted()加权加法
第1个参数是图像1 src;
第2个参数是图像1的权值 alpha;
第3个参数为图像2 dst;
第4个参数为图像2的权值 beta;
第5个参数附加数值gamma,单个数值,即使是多通道图像也使用单个数值;
第6个参数可选,返回图像的实例,等同于函数返回结果
第7个参数可选,dtype,表示像素值的数据类型
alpha和beta的关系并不要求二者的和为1,新图像的结果可以表示为:dst(I)=saturate(src1(I)∗alpha+src2(I)∗beta+gamma)

import cv2

img = cv2.imread('..\\lena.jpg')[0:512,0:512] #截取部分,保证大小一致
img2 = cv2.imread('..\\opencv-logo.png' )[0:512,0:512] 
img3 = cv2.addWeighted(img,0.5,img2,0.2,10)
print('img[161,199]:',img[161,199])
print('img2[161,199]:',img2[161,199])
print('img3[161,199]:',img3[161,199])
cv2.imshow('addWeighted-0.5-0.2',img3)

img3 = cv2.addWeighted(img,0.2,img2,0.5,10)
print('img[161,199]:',img[161,199])
print('img2[161,199]:',img2[161,199])
print('img3[161,199]:',img3[161,199])
cv2.imshow('addWeighted-0.2-0.5',img3)
cv2.waitKey(0)

同样加权addWeighted() 也是饱和运算.

图像相减
1.subtract()2个图像相减仍然要求通道数一样,图像尺寸一样,同样遵守饱和运算,相减小于0的用0补。

import cv2
img = cv2.imread('..\\lena.jpg')[0:512,0:512] #截取部分,保证大小一致
img2 = cv2.imread('..\\opencv-logo.png' )[0:512,0:512]
img3 = cv2.subtract(img,img2)
print('img[161,199]:',img[162,200])
print('img2[161,199]:',img2[162,200])
print('img3[161,199]:',img3[162,200])
cv2.imshow('subtract(img,img2)',img3)

img3 = cv2.subtract(img2,img)
print('img2[161,199]:',img2[162,200])
print('img[161,199]:',img[162,200])
print('img3[161,199]:',img3[162,200])
cv2.imshow('subtract(img2,img)',img3)

cv2.waitKey(0)
  1. -运算符
    如果得到的结果小于0,得到的结果不会出现负数,而是在这个负数的基础上加上256。
import cv2

img = cv2.imread('..\\lena.jpg')[0:512,0:512] #截取部分,保证大小一致
img2 = cv2.imread('..\\opencv-logo.png' )[0:512,0:512]
img3 = img-img2

cv2.imshow('img-img2',img3)
img4 = img2 - img
cv2.imshow('img2 - img',img4)
cv2.waitKey(0)

3.绝对值减法absdiff()
absdiff()得到的是2个图像间像素的绝对差值,二者对调减数和被减数时效果是一样的。
4.图像与标量
img3 = cv2.add(img,50)#第1通道加一个标量值
img3 = cv2.subtract(img,(50,50,50,0))#3个通道减一个标量值
图像和标量加减运算时,多通道的标量值用一个4元组表示。
当标量值只是1个数值时,只会对多通道图像的第1个通道进行运算,如果要进行多通道运算,标量值则使用一个包含4个数值的元组表示,即使是3通道的彩色图像也要用4元组表示这个标量值。下面这个例子对图像进行第1通道和3个通道的加减运算:

图像乘法
1.multiply()
multiply()遵守饱和运算
2. * 乘法
数值类型表示范围的上限加1取模,比如uint8类型的数据对256取模。

图像除法
1.divide()
divide()有2种用法:
dst = cv2.divide( src1, src2, dst, scale, dtype):第1个和第2个位置参数都是图像对象,可选参数scale参数指定src1的放大倍数,dst=saturate(src1*scale/src2);在cv2.divide( src1, src2[, dst[, scale[, dtype]]] )中的scale参数必须是数值型数据,先用src1乘以scale再除以src2,如果src1是多通道图像,scale会作用到src1的所有通道上。

dst = cv2.divide( scale, src2, dst, dtype):第1个位置参数为数值类型,第2个位置参数为图像对象,dst=saturate(scale/src2)。要想实现scale/src2的用法,必须显式地声明形参的名称。img_ret = cv2.divide(scale=250.0,src2=img)
如果是uint8等整数类型的除法,运算后的结果会做四舍五入取整。divide()除法也遵守“饱和运算规则”。
如果要调用第2种形式的接口必须显式地写明形参变量的名称。
2. /
符号除法实际就是numpy数组的除法。
imread()读入图像默认的数据类型为uint8,符号除法得到的数据类型发生了改变,变成了float64。
当除数为0时,numpy除法打印了告警信息:divide by zero encountered in true_divide,直接计算结果为inf,但是转换为OpenCV的图像是有实际意义的0。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值