【OpenCV】(三)图像的算数与位运算
系列内容:OpenCV概述与环境配置,OpenCV基础知识和绘制图形,图像的算数与位运算,图像视频的加载和显示,图像基本变换,滤波器,形态学,图像轮廓,图像直方图,车辆统计项目,特征检测和匹配,图像查找和拼接,虚拟计算器项目,信用卡识别项目,图像的分割与修复,人脸检测与车牌识别,目标追踪,答题卡识别判卷与文档ocr扫描识别,光流估计
(一)图像的算数运算
1.add
(1)概述
OpenCV使用add来执行图像的加法运算。
图片就是矩阵,图片的加法运算就是矩阵的加法运算,这就要求加法运算的两张图shape必须是相同的。
(2)示例代码:
图片叠加:
import cv2
import numpy as np
# 图片加载
cat = cv2.imread('./cat.jpg')
dog = cv2.imread('./dog1.jpg')
# 加法要求两个图片大小一致
print(cat.shape)
print(dog.shape)
# 把猫的照片变小
# 注意,opencv中resize中传递新的宽度和高度,先宽度后高度,所以是先列后行,和shape输出反了
new_cat = cv2.resize(cat, (dog.shape[1], dog.shape[0]))
# 和单个数字运算,超过255,会被截断,统一变成255
print(new_cat[0:5, 0:5] + 100) # 这里只是打印相加后的值,并未修改原图,若要修改需赋值
cv2.imshow('cat_dog', np.hstack((new_cat, dog)))
# 加法,加法的效果是加起来如果超过255,统一变成255
new_img = cv2.add(new_cat, dog)
print(new_img[0:5, 0:5])
cv2.imshow('cat_dog', np.hstack((new_cat, dog, new_img)))
cv2.waitKey(0)
cv2.destroyAllWindows()
打印图片大小和维度,如图3.1所示:
对比图,如图3.2所示:
裁剪图片大小后相加:
import cv2
import numpy as np
# 图片加载
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
# 加法要求两个图片大小一致
print(cat.shape)
print(dog.shape)
# 在做加法之前需要把图片的形状变得完全一样才行
# 可以通过ndarray的切片方式取出完全一样的形状
# 猫更大,所以从猫里切出狗的形状
new_cat = cat[0:234, :338] # 更准确的切片表达,取前234行和前338列
print(new_cat.shape)
# 注意,opencv中resize中传递新的宽度和高度,先宽度后高度,所以是先列后行,和shape输出反了
# 此处代码原意图是调整大小但未实际使用resize,而是切片
# new_cat = cv2.resize(cat, (dog.shape[1], dog.shape[0]))
new_img = cv2.add(new_cat, dog)
cv2.imshow('new_img', new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
裁剪图片大小后相加,如图3.3所示:
详细说明:从三个照片中取出像素点,观察矩阵数,可以发现有多个和为255:
import cv2
import numpy as np
# 图片加载
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
# 加法要求两个图片大小一致
print(cat.shape)
print(dog.shape)
# 在做加法之前需要把图片的形状变得完全一样才行
# 可以通过ndarray的切片方式取出完全一样的形状
# 猫更大,所以从猫里切出狗的形状
new_cat = cat[0:234, :338]
print(new_cat.shape)
# 注意,opencv中resize中传递新的宽度和高度,先宽度后高度,所以是先列后行,和shape输出反了
# add的规则就是两个图对应位置的元素相加,如果超过255,全部变成255
print(new_cat[:3, :3])
print('----------')
print(dog[:3, :3])
print('----------')
new_img = cv2.add(new_cat, dog)
print(new_img[:3, :3])
cv2.imshow('new_img', new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
图片发白原因是有多个和为255,如图3.4所示:
图片的像素值加上数字后打印(x=x\%256)
原图如图3.5所示:
数字为100时:
import cv2
import numpy as np
# 图片加载
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
# 加法要求两个图片大小一致
print(cat.shape)
print(dog.shape)
# 在做加法之前需要把图片的形状变得完全一样才行
# 可以通过ndarray的切片方式取出完全一样的形状
# 猫更大,所以从猫里切出狗的形状
new_cat = cat[0:234, :338]
print(new_cat.shape)
# 注意,opencv中resize中传递新的宽度和高度,先宽度后高度,所以是先列后行,和shape输出反了
# add的规则就是两个图对应位置的元素相加,如果超过255,全部变成255
print(dog[:3, :3])
# 图片还可以和单个数字进行运算
# 每个和100进行加法运算,超过255的数字,变成x%255
dog += 100
print(dog)
数字为100时(即dog += 100)如图3.6所示:
数字为150时(dog += 150)如图3.7所示:
2.substract
说明:减完后小于0,按0存入,故图片偏黑
import cv2
import numpy as np
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
print(cat.shape)
print(dog.shape)
new_cat = cat[0:234, :338]
print(new_cat.shape)
new_img = cv2.subtract(new_cat, dog)
cv2.imshow('new_img', new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
猫和狗相减结果,如图3.8所示:
3.multiply
# 图片加载
import cv2
import numpy as np
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
# 加法要求两个图片大小一致
print(cat.shape)
print(dog.shape)
# 在做加法之前需要把图片的形状变得完全一样才行
# 可以通过ndarray的切片方式取出完全一样的形状
# 猫更大,所以从猫里切出狗的形状
new_cat = cat[0:234, :338]
print(new_cat.shape)
# 注意,opencv中resize中传递新的宽度和高度,先宽度后高度,所以是先列后行,和shape输出反了
new_img = cv2.multiply(new_cat, dog)
cv2.imshow('new_img', new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
猫和狗相乘结果,如图3.9所示:
4.divide
# 图片加载
import cv2
import numpy as np
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
# 加法要求两个图片大小一致
print(cat.shape)
print(dog.shape)
# 在做加法之前需要把图片的形状变得完全一样才行
# 可以通过ndarray的切片方式取出完全一样的形状
# 猫更大,所以从猫里切出狗的形状
new_cat = cat[0:234, :338]
print(new_cat.shape)
# 注意,opencv中resize中传递新的宽度和高度,先宽度后高度,所以是先列后行,和shape输出反了
new_img = cv2.divide(new_cat, dog)
cv2.imshow('new_img', new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
猫和狗相除结果,如图3.10所示:
5.图像的融合
说明:
此时,不再是简单的加减法,相当于拿图片做了线性运算:
new_img=img1*w1+img2*w2+bias
其中,alpha是第一个权重参数,deta是第二个权重参数,gamma是偏差
(1)参数为(0.3,0.7,0)时
new_img=cv2.addWeighted(new_cat,0.3,dog,0.7,0)
# 此时,不再是简单的加减法,相当于拿图片做了线性运算:
# new_img = img1*w1 + img2*w2 + bias
import cv2
import numpy as np
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
new_cat = cat[0:234, :338]
new_img = cv2.addWeighted(new_cat, 0.3, dog, 0.7, 0)
cv2.imshow('new_img', new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
参数为(0.3,0.7,0)时结果,如图3.11所示:
(2)参数为(0.3,0.7,-100)结果,如图3.12所示:
(3)横向对比图
# 此时,不再是简单的加减法,相当于拿图片做了线性运算:
# new_img = img1*w1 + img2*w2 + bias
import cv2
import numpy as np
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
new_cat = cv2.resize(cat, (dog.shape[1], dog.shape[0])) # 修正尺寸参数顺序,先宽后高,这里取dog的宽高
# 相当于 res = new_cat*0.4 + dog*0.6 + 0
res = cv2.addWeighted(new_cat, 0.4, dog, 0.6, 0)
cv2.imshow('cat_dog', np.hstack((new_cat, dog, res)))
cv2.waitKey(0)
cv2.destroyAllWindows()
横向对比图,如图3.13所示:
(二)OpenCV的位运算
OpenCV的逻辑运算--与,或,非,异或
OpenCV的逻辑运算就是对应位置元素进行与或非,异或
1.非操作
bitwise_not(img)非操作的效果就相当于是用255-img
# 非操作
import cv2
import numpy as np
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
cat_not = cv2.bitwise_not(cat)
cat_not_not = cv2.bitwise_not(cat_not)
cv2.imshow('not', np.hstack((cat, cat_not, cat_not_not)))
print(cat[:3, :3])
print(cat_not[:3, :3])
print(cat_not_not[:3, :3])
cv2.waitKey(0)
cv2.destroyAllWindows()
非操作运行结果(1),如图3.14所示:
非操作运行结果(2),如图3.15所示:
2.与操作
与操作示例,如图3.16所示:
# 与操作
import cv2
import numpy as np
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
# 非操作,相当于255 - cat
new_cat = cat[0:234, :338]
# 两个图片对应位置的元素进行与操作
cat_and = cv2.bitwise_and(new_cat, dog)
cat_and_and = cv2.bitwise_and(cat_and, dog)
cv2.imshow('not', np.hstack((cat, cat_and, cat_and_and)))
print(cat[:3, :3])
print(cat_and[:3, :3])
print(cat_and_and[:3, :3])
cv2.waitKey(0)
cv2.destroyAllWindows()
与操作运行结果(1),如图3.17所示:
与操作运行结果(2),如图3.18所示:
3.或操作
# 或操作
import cv2
import numpy as np
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
# 非操作, 相当于255 - cat
new_cat = cat[0:234, :338]
# 两个图片对应位置的元素进行或操作
cat_or = cv2.bitwise_or(new_cat, dog)
cat_or_or = cv2.bitwise_or(new_cat, cat_or)
cv2.imshow('not', np.hstack((new_cat, dog, cat_or_or))) # 原样保留展示组合
print(cat[:3, :3])
print(cat_or[:3, :3])
print(cat_or_or[:3, :3])
cv2.waitKey(0)
cv2.destroyAllWindows()
或操作运行结果(1),如图3.19所示:
或操作运行结果(2),如图3.20所示:
4.异或
# 异或操作
import cv2
import numpy as np
cat = cv2.imread('./cat2.jpg')
dog = cv2.imread('./dog1.jpg')
# 非操作, 相当于255 - cat
new_cat = cat[0:234, :338]
# 两个图片对应位置的元素进行异或操作
cat_xor = cv2.bitwise_xor(new_cat, dog)
# cat_xor_xor = cv2.bitwise_xor(new_cat, cat_xor)
cv2.imshow('not', np.hstack((new_cat, dog, cat_xor)))
print(cat[:3, :3])
print(cat_xor[:3, :3])
# print(cat_xor_xor[:3, :3])
cv2.waitKey(0)
cv2.destroyAllWindows()
异或操作运行结果(1),如图3.21所示:
异或操作运行结果(2),如图3.22所示:
异或操作运行结果(3),如图3.23所示:
更多推荐
所有评论(0)