系列内容: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.1-打印图片大小和维度

对比图,如图3.2所示:

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所示:

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所示:

3.4-图片发白原因是有多个和为255

图片的像素值加上数字后打印(x=x\%256)

原图如图3.5所示:

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所示:

3.6-数字为100时

数字为150时(dog += 150)如图3.7所示:

3.7-数字为150时

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.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所示:

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所示:

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所示:

3.11-参数为(0.3,0.7,0)时结果

(2)参数为(0.3,0.7,-100)结果,如图3.12所示:

3.12-参数为(0.3,0.7,-100)结果

(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所示:

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所示:

3.14-非操作运行结果(1)

非操作运行结果(2),如图3.15所示:

3.15-非操作运行结果(2)

2.与操作

与操作示例,如图3.16所示:

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所示:

3.17-与操作运行结果(1)

与操作运行结果(2),如图3.18所示:

3.18-与操作运行结果(2)

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所示:

3.19-或操作运行结果(1)

或操作运行结果(2),如图3.20所示:

3.20-或操作运行结果(2)

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所示:

3.21-异或操作运行结果(1)

异或操作运行结果(2),如图3.22所示:

3.22-异或操作运行结果(2)

异或操作运行结果(3),如图3.23所示:

3.23-异或操作运行结果(3)
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐