opencv初步学习——图像处理3

这一部分我们将学习opencv中对图像大小进行调整的基本操作,以及掩模操作,我们直接进入正言

一、cv2.resize( )函数

1-1、组成与构造

该函数的作用就算用来帮助我们实现对图像大小的处理,具体的组成与构造如下:

python 复制代码
cv2.resize(src , 大小设置 , interpolation)

src即我们的原图像,我们的重点放在大小设置与interpolation上,我们的原图像如下:


1-2、大小设置

该函数的大小设置主要有两种方法,对应的参数分别是dsize与fx、fy,我们分别来说

(1)直接设定大小(dsize)

我们的代码形式如下:

python 复制代码
import cv2
img = cv2.imread("D:\\photo\\man.png")

dst = cv2.resize(img,[100,100])

cv2.imshow("one",dst)
cv2.waitKey()
cv2.destroyAllWindows()

这里我们就直接设定为100×100的大小了,通常叫做参数dsize,当然这里可以是元组的形式,也可以是列表的形式,输出的图像会被缩小到100×100的大小,这里就不放出结果图了

当然我们还有其他写法,我们可以直接先设置好缩放大小,然后在放进我们的函数中去,这样我们就可以方便我们去修改我们的缩放比例:

python 复制代码
rows,cols = img.shape[:2]
size=(int(cols*0.9) , int(rows*0.9))   这里必须要强制类型转化,想想是为什么呢
dst = cv2.resize(img , size)

解释一下shape 是 NumPy 数组的一个属性,它会返回一个元组,这个元组包含了数组各维度的大小。对于单通道图像,img.shape 返回的元组格式为 (行数, 列数);对于多通道图像,返回的元组格式为 (行数, 列数, 通道数)

(2)设定缩放大小(fx、fy)

这个的区别在于我们需要手动设置一个缩放大小,而不是设置一个具体的缩小到怎么样的大小,具体我们的代码如下:

python 复制代码
import cv2
img = cv2.imread("D:\\photo\\man.png")

dst = cv2.resize(img, None, fx=0.5, fy=0.5)

cv2.imshow("one",img)
cv2.imshow("two",dst)
cv2.waitKey()
cv2.destroyAllWindows()

这里出现新的参数,即我们的fx与fy,分别表示我们在水平方向上的缩放因子与垂直方向上的缩放因子。按照上面代码的操作我们的图像将被缩小一半,这里也不做展示了

疑惑:

Q1、那么就会有人问,为什么前面加一个None呢?

------这是告诉编译器我不用直接设置大小,而是设置缩放比例,是需要对dsize设定为None,而且这个函数对大小设置其实是有一定顺序的:

Q2、那我可不可以不写fx=、fy=呢?

------当然可以,但是如果是这样写,是不对的:

python 复制代码
dst = cv2.resize(img, None, 0.5,0.5)

你会发现编译器报错了,因为在dsize与我们fx、fy之间还有一个参数(见上图),即我们的dst,这个就是会为你自动创建一个数组出来存储这些信息,但我们在前面已经设置好了dst = ~~,故我们在这个参数也需要设置为None。

所以我们的正确写法如下:

python 复制代码
dst = cv2.resize(img, None, None, 0.5,0.5)

1-3、interpolation(插值方法)

首先我们需要知道什么是插值方法,以及为什么我们需要插值

我们在对图像进行放大和缩小的时候,我们的像素点数量也在发生变化,例如我们可以设定为100×100的像素大小,那么为了保证我们的图像在放大缩小后仍可以反映原来图像的主要信息,所以我们需要进行一系列操作来使我们的像素点的颜色变化,对新像素值进行估计,从而达到此目的,这种方法就是插值

这就更照片像素越高反映出的画面越高清丝滑;像素越低越像在看马赛克差不多的意思

我们只是简单来看看有哪些插值方法(不要求原理):

|----------------------------------|------------------------------------------------------------------------------------------------------------------------|
| 插值方法 | 具体实现 |
| ##### cv2.INTER_NEAREST(最近邻插值) | 该方法会选取距离目标像素最近的原始像素的值作为目标像素的值。例如,当图像放大时,新像素直接采用离它最近的原始像素的颜色。 特点:计算速度快图像质量相对较差,在放大图像时容易出现锯齿状边缘。 |
| ##### cv2.INTER_LINEAR(双线性插值) | 它基于目标像素周围 2x2 邻域内的四个原始像素的值,通过线性加权计算来确定目标像素的值。这种方法考虑了周围像素的影响,使得图像过渡更加平滑 特点:计算速度适中,图像质量较好,是 cv2.resize() 函数的默认插值方法 |
| ##### cv2.INTER_CUBIC(双三次插值) | 此方法基于目标像素周围 4x4 邻域内的 16 个原始像素的值,使用三次函数进行加权计算,从而得到目标像素的值。相比双线性插值,它能更精确地拟合图像的局部特征。 特点:计算量较大,速度较慢,但图像质量非常高,在放大图像时能保留更多的细节 |
| ##### cv2.INTER_AREA(区域插值 | 该方法基于图像区域的像素密度进行插值。在缩小图像时,它通过对原始图像的像素块进行平均来计算目标像素的值;在放大图像时,其效果类似于最近邻插值。 特点:在缩小图像时效果较好,能有效避免图像出现模糊和失真现象;但在放大图像时效果不佳。 |



二、掩模

ps:勉励大家一句话:书山有路勤为径,学海无涯苦作舟,因为编者也学得很累了,但怎么能够放弃呢。

ok言归正传,首先我们需要知道什么是掩模,我们需要掩模来干什么

在手术的时候,我们常常看见医生会铺一层防菌布(绿色那一个),然后在需要手术的部位开一个口子来进行手术,这样做可以不干扰到其他部位(比如突然喷了)。掩模也是这个道理,我们对需要处理的图像部分掩模,这样在后面的操作中就可以提醒程序这个地方要动,其他地方不要动

举一个例子来说明:

图像选自《计算机视觉40例从入门到深度学习》(李立宗)

中间即我们的掩模图像,右图是使用掩模图像对原始图像进行掩模运算的图像

那么我们就要思考如何才能到达这种目的

1-1、乘法运算

在图像处理中我们的乘法运算遵循如下原理:

1、任意数字与 1 相乘,结果是数字 N 自身。

2、 任意数字与 0 相乘,结果为 0

那么我们可以构造出一个只含有0与1的掩模图像,随后将这个掩模图像与原始图像相乘,即得到我们的结果图像(被1所乘的部分),但是我们需要保证掩模图像的大小与原始图像的大小是相等的。接下来我们来自己构建一个掩模图像并相乘


1-2、构建掩模图像

首先我们需要知道我们的原始图像是一个彩色图像,那么我们首先需要构建一个三维数组,然后把我们的原始图像的大小信息与通道数

python 复制代码
import cv2
import numpy as np

img = cv2.imread("D:\\photo\\man.png",1)

a,b,c = img.shape

mask = np.zeros((a,b,c), dtype = np.uint8)

这里的c即我们的通道数

那么接下来我们将需要掩模的部位全部设置为1,随后相乘即可:

python 复制代码
mask[100:500,200:500] = 1

result = img * mask

cv2.imshow("one",img)
cv2.imshow("two",mask*255)  这里设置为255是由于本来1就是深黑色,与周围分不清,这里将其变为白色
cv2.imshow("three",result)

cv2.waitKey()
cv2.destroyAllWindows()

我们的原始图像如下:

我们的掩模图像如下:

我们的最终图像如下:

这样我们完成了掩模处理

1-3、逻辑运算

这里不是真的在讲逻辑运算,我们知道根据按位与运算的规则,任意数值与数值 1 进行与运算,结果都等于其自身,那么对于opencv中的8位无符号二进制来说,任何数值与1111 1111(即255)进行与运算都是本身。

那么我们在构建掩模图像的时候可以按照逻辑运算来构造(不是乘法运算),即将需要掩模的部位设置为 255即可,其他设置为0,代码如下:

python 复制代码
import cv2 
import numpy as np 
o=cv2.imread("lenacolor.png",1) 
h,w,c=o.shape 
m=np.zeros((h,w,c),dtype=np.uint8) 
m[100:400,200:400]=255 
m[100:500,100:200]=255 
result=cv2.bitwise_and(o,m) 
cv2.imshow("original",o) 
cv2.imshow("mask",m) 
cv2.imshow("result",result) 
cv2.waitKey() 
cv2.destroyAllWindows() 

其中**result = cv2.bitwise_and(o , m)**这个操作就是在进行按位与操作

1-4、函数下的掩模

在opencv中的很多函数都有一个掩模参数,即如果我们加上一个掩模参数,那么函数操作的部分都会在掩模部分进行

但有一个有意思的点是这个掩模区域的设置要求不怎么严格(并不需要设置为1或者255),只要是非零真值即可,其他部分设置为0.这里不做示例

相关推荐
jndingxin7 分钟前
OpenCV图像拼接(2)特征查找与图像匹配之基于仿射变换的图像匹配的一个类cv::detail::AffineBestOf2NearestMatcher
人工智能·opencv·计算机视觉
勇敢牛牛_9 分钟前
【Rust交叉编译】在x86_64架构下交叉编译aarch64-linux-musl版的rust-opencv
linux·opencv·rust·aarch64
怪我冷i11 分钟前
LogicFlow介绍
人工智能·学习·大模型
Suckerbin11 分钟前
PHP前置知识-HTML学习
前端·学习·html
cyr___18 分钟前
Unity教程(二十二)技能系统 分身技能
学习·游戏·unity·游戏引擎
且听风吟5671 小时前
E902基于bash与VCS的仿真环境建立
笔记·学习
蹦蹦跳跳真可爱5891 小时前
Python----计算机视觉处理(Opencv:图像镜像旋转)
人工智能·python·opencv·计算机视觉
巷9551 小时前
OpenCV图像处理:分割、合并、打码、组合与边界填充
人工智能·opencv·计算机视觉
习惯就好zz1 小时前
Kotlin标准函数库学习
java·学习·kotlin
AndrewHZ1 小时前
【图像处理】ISP(Image Signal Processor) 图像处理器的用途和工作原理?
图像处理·人工智能·深度学习·算法·智能手机·影像系统·isp