🌈据说,看我文章时 关注、点赞、收藏 的 帅哥美女们 心情都会不自觉的好起来。
前言:
🧡作者简介:大家好我是 user_from_future ,意思是 “ 来自未来的用户 ” ,寓意着未来的自己一定很棒~
✨个人主页:点我直达,在这里肯定能找到你想要的~
👍专栏介绍:OpenCV从入门到放弃 ,一个学习OpenCV的专栏~
想看往期历史文章,可以浏览此博文: 历史文章目录
,后续所有文章发布都会同步更新此博文~
图像的变换
一张图,能在我们手里放大缩小,在远程控制的时候,有个叫 画面自适应 的选项,能让我们的画面你图像自动铺满屏幕。在这些背后,我们没有学之前能如何调整图像大小呢?
在没有学图像变换之前,我们一般只能将图片的宽高缩小,比如:
这里有一个猫和一个狗:
他们的大小分别如下:
上面的数字代表了图像的 高 、 宽 、 通道数 。
明显猫更大,所以我们需要裁剪一下:
这样两张图片的形状大小就完全一致了,我们来看看猫的裁剪前后:
被裁剪的只剩猫头了~
这样的感觉,很不好,于是我们接下来就学一个图像的变换,让他变成合适的大小却不丢失内容~
现在猫很丝滑的缩小了,这里要注意,OpenCV中应用的长宽数字和读取图像出来的 ndarray 的长宽数字是相反的, ndarray 是先行后列,OpenCV中应用的是先列(宽)后行(高)
,这里写反就不对了~
resize
用法
你以为这个方法就这么简单吗?NoNoNo,他里面涉及到一个算法:插值算法,放大缩小之后肯定要重新计算像素,这个算法就是用来处理这个的。
该方法的属性如下:resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst
属性名 | 属性解释 | 属性值 | 备注 |
---|---|---|---|
src | 原图 | ndarray() | - |
dsize | 缩放后的大小 | (宽,高) | 如果为(0, 0) ,则使用fx 和fy |
fx | 沿x轴缩放的系数 | 正数 | dsize = (0, 0) 时生效 |
fy | 沿y轴缩放的系数 | 正数 | dsize = (0, 0) 时生效 |
interpolation | 插值算法 | cv2.INTER_NEAREST cv2.INTER_LINEAR cv2.INTER_CUBIC cv2.INTER_AREA | 邻近插值 【默认】双线性插值[ 2x2 ]三次插值[ 4x4 ]区域插值[ 8x8 ] |
其中插值算法所示的四种值,从上到下效果越来越好,但同时耗费的时间越来越多,实际情况需要自己衡量好,一般默认的算法够用。
图像的算术运算
方法名 | 方法解释 | 方法参数 | 方法范围 | 方法效果 | ndarray 效果 | 运用场景 | 参数顺序 |
---|---|---|---|---|---|---|---|
add | 图像加法 | src1 :图片1src2 :图片2 | ≤255超出变255 | 变白 | (+=)%256 模运算 | 图片叠加 | 无要求 |
subtract | 图像减法 | src1 :图片1src2 :图片2 | ≥0低于变0 | 变暗 | (-=) | - | 有要求 |
multiply | 图像乘法 | src1 :图片1src2 :图片2 | ≤255超出变255 | 全白 | (*=) | - | 无要求 |
divide | 图像除法 | src1 :图片1src2 :图片2 | ≥0低于变0 | 全黑 | (/=) | - | 有要求 |
一小段代码带你了解他们之间的区别:
import numpy as np
from cv2 import cv2
cat = cv2.resize(cv2.imread('./cat.jpeg'), (308, 222))
dog = cv2.resize(cv2.imread('./dog.png'), (308, 222))
cv2.imshow('cat-dog', np.hstack((cv2.add(cat, dog), cv2.subtract(cat, dog), cv2.multiply(cat, dog), cv2.divide(cat, dog))))
cv2.imshow('dog-cat', np.hstack((cv2.add(dog, cat), cv2.subtract(dog, cat), cv2.multiply(dog, cat), cv2.divide(dog, cat))))
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
明显加法和乘法对参数顺序没有要求,其他则有,然后加法还能看出点猫狗叠加的影子,其他不是恐怖片就是啥也不是。
图像的融合——addWeighted
用法
刚才的加法的确叠加了,但由于加起来很容易超过255,所以本来比较白的地方叠加在一起就会非常亮,这很不好,于是就有了图像融合方法,目的是通过加权和偏置来调节图像色彩和亮度。
这里我们使用 cv2.addWeighted
来加权融合图像,该方法的属性如下:addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]]) -> dst
属性名 | 属性解释 | 属性值 | 备注 |
---|---|---|---|
src1 | 原图1 | ndarray() | - |
alpha | 原图1的加权系数 | 正数 | 一般在0-1 之间且与beta 和为0 |
src2 | 原图2 | ndarray() | - |
beta | 原图2的加权系数 | 正数 | 一般在0-1 之间且与alpha 和为0 |
gamma | 合成后图像的偏置 | 整数或浮点数 | 调节亮度,一般为0 |
不够直观?没关系,来段代码感受一下:
import numpy as np
from cv2 import cv2
cat = cv2.resize(cv2.imread('./cat.jpeg'), (616, 444))
dog = cv2.imread('./dog.png')
cv2.imshow('cat+dog', np.hstack((cv2.addWeighted(cat, 0.5, dog, 0.5, 0), cv2.addWeighted(cat, 0.8, dog, 0.2, 0), cv2.addWeighted(cat, 0.2, dog, 0.8, 0))))
cv2.imshow('cat+dog~', np.hstack((cv2.addWeighted(cat, 0.5, dog, 0.5, 0), cv2.addWeighted(cat, 0.5, dog, 0.5, 50), cv2.addWeighted(cat, 0.5, dog, 0.5, -50))))
cv2.waitKey(0)
cv2.destroyAllWindows()
上面三张图分别代表不同系数的组合,下面三张图代表不同偏置(亮度)的组合:
感受到应该写怎样的参数了吗?我猜你是感受到了~
图像的位运算
方法名 | 方法解释 | 方法参数 | 方法效果 | 相当于 | 参数顺序 |
---|---|---|---|---|---|
bitwise_and | 图像与运算 | src1 :图片1src2 :图片2 | 变暗(数字变小) | img1 & img2 | 无要求 |
bitwise_or | 图像或运算 | src1 :图片1src2 :图片2 | 变亮(数字变大) | img1 / img2 | 无要求 |
bitwise_not | 图像非运算 | src :图片 | 黑白互换 | 255 ^ img 255 -= img | 无要求 |
bitwise_xor | 图像异或运算 | src1 :图片1src2 :图片2 | 变黑(色彩斑斓) | img1 ^ img2 | 无要求 |
仍然是一小段代码带你了解他们之间的区别:
import numpy as np
from cv2 import cv2
cat = cv2.resize(cv2.imread('./cat.jpeg'), (308, 222))
dog = cv2.resize(cv2.imread('./dog.png'), (308, 222))
cv2.imshow('cat-dog', np.hstack((cv2.bitwise_and(cat, dog), cv2.bitwise_or(cat, dog), cv2.bitwise_not(cat), cv2.bitwise_xor(cat, dog))))
cv2.imshow('dog-cat', np.hstack((cv2.bitwise_and(dog, cat), cv2.bitwise_or(dog, cat), cv2.bitwise_not(dog), cv2.bitwise_xor(dog, cat))))
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
有什么作用自己感受吧~ 反正我是觉得都怪怪的用不到~
补充说明
图像的算术运算和位运算中,都可以使用参数 mask=mask
与 掩码 进行 与运算 。
题外话
import numpy as np
from cv2 import cv2
love = cv2.resize(cv2.imread('./love.jpg'), (400, 400))
hurt = cv2.resize(cv2.imread('./hurt.jpg'), (400, 400))
cv2.imshow('show', np.hstack([love, hurt, cv2.addWeighted(love, 0.5, hurt, 0.5, 126), cv2.bitwise_or(love, hurt)]))
cv2.waitKey(0)
cv2.destroyAllWindows()
右边两个图是由左边两个图融合而成,你第一眼看到的是什么呢?