本期将了解图像的基础运算,包含算数运算和位运算等。我们所使用的图像处理技术其实都是靠一些简单的基础运算来完成的,例如加法运算、位运算等,这些简单运算是我们后续研究更复杂的图像处理的基础。
完成本期内容,你可以:
- 了解算数运算、位运算的基本原理
- 掌握算数运算、位运算的使用
- 掌握位运算在图像处理中常见的使用场景
若要运行案例代码,你需要有:
-
操作系统:Ubuntu 16 以上 或者 Windows10
-
工具软件:VScode 或者其他源码编辑器
-
硬件环境:无特殊要求
-
核心库:python 3.6.13, opencv-contrib-python 3.4.11.39,opencv-python 3.4.2.16
点击下载源码
加法运算
加法运算
加运算就是两幅图像对应像素的灰度值或彩色分量进行相加。主要有两种用途,一种是消除图像的随机噪声,主要做是讲同一场景的图像进行相加后再取平均;另一种是用来做特效,把多幅图像叠加在一起,再进一步进行处理。
OpenCV中提供的加法运算的函数是cv2.add()。
函数原型: add_img = cv2.add(img1, img2);
add_img为运算后的图像。
参数描述如下:
参数 | 描述 |
---|---|
img1,img2 | 需要进行运算的图片 |
加权和运算
OpenCV通过计算加权和的方式, 按照不同的权重取两幅图像的像素之和, 最后组成新图像。加权和不会像纯加法运算那样让图像丢失信息, 而是在尽量保留原有图像信息的基础上把两幅图像融合到一起。
OpenCV中提供的加权和运算的函数是cv2.addWeighted()。
函数原型: dst = cv2.addWeighted(src1, alpha, src2, beta, gamma, dst, dtype);
dst 为运算后的图像。
参数描述如下:
参数 | 描述 |
---|---|
src1 | 表示进行加权操作的第一个图像对象,即输入图片1 |
alpha | double型,表示第一个图像的加权系数,即图片1的融合比例 |
src2 | 表示进行加权操作的第二个图像对象,即输入图片2 |
beta | double型,表示第二个图像的加权系数,即图片2的融合比例。很多情况下,有关系 alpha+beta=1.0 |
gamma | 可选参数,double型,表示一个作用到加权和后的图像上的标量,可以理解为加权和后的图像的偏移量,融合后添加的数值,调节亮度 |
dst | 可选参数,表示两个图像加权和后的图像,尺寸和图像类型与src1和src2相同,即输出图像 |
dtype | 可选参数,默认值-1。当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth() |
位运算
与运算
图像的与运算就是将两幅二值图像的对应像素进行逻辑与操作,如果处理的图像不是二值图像,那么要先进行二值化处理。可以用来求得两幅尺寸相同的图像的相交区域。
OpenCV中提供的用于与运算的函数是cv2.bitwise_and()。
函数原型: and_img = cv2.bitwise_and(img1, img2);
and_img为运算后的图像
参数描述如下:
参数 | 描述 |
---|---|
img1,img2 | 需要进行运算的图片 |
-
如果某个像素与纯白色像素做与运算,结果仍然是原像素的原值。
00101011 & 11111111=00101011
-
如果某个像素与纯黑色像素做与运算,结果为纯黑像素。
00101011 & 00000000=00000000
-
结论:如果原图像与掩模进行与运算, 原图像仅会保留掩模中白色区域所覆盖的内容,其他区域全部变成黑色。
或运算
或运算和与运算操作方法类似,只是将两幅图像的对应像素该位进行或运算即可,同样的,如果处理的图像不是二值图像,则应该首先对图像进行二值化。
OpenCV中提供的用于或运算的函数是cv2.bitwise_or()。
函数原型: or_img = cv2.bitwise_or(img1, img2)
or_img为运算后的图像
参数描述如下:
参数 | 描述 |
---|---|
img1,img2 | 需要进行运算的图片 |
-
如果某个像素与纯白色像素做或运算,结果仍然是纯白元素。
00101011 | 11111111=11111111
-
如果某个像素与纯黑色像素做或运算,结果仍然是某元素的原值。
00101011 & 00000000=00101011
-
结论:如果原图像与掩模进行或运算, 原图像仅会保留掩模中黑色区域所覆盖的内容,其他区域全部变成白色。
取反运算
取反运算是按照二进制位进行判断的,如果同一位的数字是0,则运算结果的相同位数字取1,如果同一位的数字是1,则运算结果的相同位数字取0。
OpenCV中提供的用于取反运算的函数是cv2.bitwise_not()。
函数原型: not_img = cv2.bitwise_not(img, mask)
not_img为运算后的图像
参数描述如下:
参数 | 描述 |
---|---|
img1 | 需要进行运算的图片 |
mask | 可选参数,掩膜 |
异或运算
异或运算是按照二进制位进行判断的,如果两个运算数同一位上的数字相同,则运算结果字取0,否则取1。
OpenCV中提供的用于异或运算的函数是cv2.bitwise_xor()。
函数原型: xor_img = cv2.bitwise_xor(img1, img2)
xor_img为运算后的图像
参数描述如下:
参数 | 描述 |
---|---|
img1,img2 | 需要进行运算的图片 |
-
如果某个像素与纯白色像素做异或运算,结果为原像素的取反结果。
00101011 | 11111111=11010100
-
如果某个像素与纯黑色像素做异或运算,结果仍然是某元素的原值。
00101011 & 00000000=00101011
-
结论:如果原图像与掩模进行异或运算, 掩膜白色区域所覆盖的内容呈现取反效果,黑色区域覆盖的内容保持不变。
具体步骤
1. 创建项目结构
创建项目名为使用图像运算进行图片美化
,项目根目录下新建code
文件夹储存代码,新建dataset
文件夹储存数据,项目结构如下:
使用图像运算进行图片美化 # 项目名称
├── code # 储存代码文件
├── dataset # 储存数据文件
注:如项目结构已存在,无需再创建。
2. 使用图像运算给小女孩染发
- 在
code
文件夹下创建dyw_hair.py
文件; - 读取
dataset
文件夹下的一张小女孩图片,名称为girl.png
,并进行展示 ; - 创建一个尺寸和小女孩图片相同的纯棕色图像,棕色的BGR为
(42,42,128)
; - 将小姑娘的头发染成棕色;
- 无限等待用户输入按键,按下按键后销毁所有窗口。
代码实现
import cv2
import numpy as np
# 读取图片
img1 = cv2.imread('../dataset/girl.png')
cv2.imshow('img1', img1)
# 获得原图尺寸,创建棕色图片
img2 = np.zeros(img1.shape, np.uint8)
img2[:] = (42, 42, 128)
cv2.imshow('img2', img2)
# 将小姑娘的头发染成棕色
add_img = cv2.add(img1, img2)
cv2.imshow('add', add_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. 为小女孩的图片加上背景
- 在
code
文件夹下创建add_background.py
文件; - 读取
dataset
文件夹下的一张小女孩图片,名称为girl.png
,并进行展示 ; - 读取
dataset
文件夹下的back.png
图片作为背景图片,并进行展示 ; - 给小女孩的图片加上背景;
- 无限等待用户输入按键,按下按键后销毁所有窗口。
代码实现
import cv2
# 读取图像
img1 = cv2.imread('../dataset/girl.png')
cv2.imshow('img1', img1)
# 读取背景图
back = cv2.imread('../dataset/back.png')
# 给小女孩的图片加上背景
and_img = cv2.bitwise_and(img1,back)
cv2.imshow('and', and_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像的运算虽然简单,但我们所使用的图像数量技术其实都是靠一些简单的基础运算来完成的,这些简单运算是我们后续研究更复杂的图像处理的基础,因此我们需要重点学习练习一下图像的基础运算的知识。
点击下载源码