几乎所有这些操作与 Numpy 的关系都比与 OpenCV 的关系更加紧密,因此熟练 Numpy 可以帮助我们写出性能更好的代码。
Numpy 是经过优化了的进行快速矩阵运算的软件包。所以我们不推荐逐个获取像素值并修改,这样会很慢,能有矩阵运算就不要用循环。
在计算机视觉和图像处理中,图像是由像素点组成的。每个像素点包含了颜色(在彩色图像中)和亮度(在灰度图像中)的信息。通过读取和操作这些像素点,我们可以实现各种图像处理任务,比如图像增强、特征提取(边缘、角点、纹理等)、物体检测和识别。
'''
#Author :susocool
#Creattime:2024/1/15
#FileName:05-读取图片信息
#Description:读取像素点
'''
import cv2 # 导入OpenCV库
import numpy as np # 导入NumPy库,它是一个处理数组的库
img = cv2.imread('D:/Py-code/opencv/01.1-hello2/xu.png') # 使用imread函数读取图像文件
px = img[100,100] # 获取图像中(100,100)位置的像素值
print(px) # 打印该像素值
blue = img[100,100,0] # 获取该像素的蓝色通道值
print(blue) # 打印蓝色通道值
当我们使用*img[100,100]*时,我们实际上是在获取位于(100,100)位置的像素的所有颜色通道的值。在OpenCV中,这些值以BGR(蓝色、绿色、红色)的顺序返回,所以img[100,100]可能会返回一个类似于[57, 63, 68]的数组,其中57是蓝色通道的值,63是绿色通道的值,68是红色通道的值。
个人觉得的一个难点,我理解了很久。
在计算机视觉中,一张彩色图像可以看作是由三张灰度图像叠加而成的,这三张图像分别对应红色、绿色和蓝色三个颜色通道。每个颜色通道的图像都是由像素组成的,每个像素的值表示该颜色的强度。
红色、绿色和蓝色是三个独立的通道,每个通道的值都是独立的,范围从0到255。这意味着,一个通道的值不会影响其他通道的值。
当我们使用img[100,100,0]
这样的语句时,我们实际上是在获取位于(100,100)位置的像素在蓝色通道上的值。也就是说,img[100,100,0]
返回的是该像素的蓝色强度。
例如,如果img[100,100,0]
返回57,那么就表示在(100,100)这个位置,蓝色的强度是57(在0-255的范围内)。
'''
#Author :susocool
#Creattime:2024/1/15
#FileName:05-读取图片信息
#Description:修改像素值
'''
import cv2
import numpy as np
img=cv2.imread('D:/Py-code/opencv/01.1-hello2/xu.png')
img[100,100]=[255,255,255]
print(img[100,100])
图像的属性包括:行,列,通道,图像数据类型,像素数目等
img.shape 可以获取图像的形状。他的返回值是一个包含行数,列数,
通道数的元组。
行数:1823
列数:1080
通道数:3------>全彩
验证一下,发现是正确的。
如果图像是灰度图,返回值仅有行数和列数。所以通过检查这个返回值 就可以知道加载的是灰度图还是彩色图。
像素数目越高的图片,其分辨率就越高。这意味着图片的细节更丰富,图像质量更好。然而,这也意味着图片的文件大小会更大,因为需要存储更多的信息。
img.dtype 返回的是图像的数据类型。
在除虫(debug)时 img.dtype 非常重要。因为在 OpenCV Python 代码中经常出现数据类型的不一致的情况。
图像的数据类型主要决定了图像每个像素可以有的颜色范围,也就是图像的深度。常见的数据类型有:
*8位无符号整数(uint8):每个像素的值范围是0-255。这是最常见的数据类型,用于表示标准的24位彩色图像(8位红色,8位绿色,8位蓝色)。
*16位无符号整数(uint16):每个像素的值范围是0-65535。这种数据类型常用于医学图像等需要更高动态范围的应用。
*32位浮点数(float32):每个像素的值可以是任何实数。这种数据类型常用于科学计算和深度学习等需要处理实数数据的应用。
图像的数据类型非常重要,因为它决定了我们可以在图像中表示的颜色的精度和范围。例如,如果我们将一个高动态范围的图像存储为8位数据,那么图像的一些细节可能会丢失。同样,如果我们将一个低动态范围的图像存储为16位或32位数据,那么可能会浪费存储空间和计算资源。此外,不同的数据类型也需要使用不同的处理方法。例如,某些图像处理算法可能只适用于特定的数据类型,而在其他数据类型上可能会产生错误的结果。
ROI(Region of Interest,感兴趣区域)是图像处理中的一个重要概念。在图像中,ROI是你关注并想要分析的特定区域。这个区域可以是任何形状,如方框、圆、椭圆、不规则多边形等。
在进行图像处理时,我们通常会先确定ROI,然后对这个区域进行进一步的处理,如特征提取、图像分割、目标检测等。使用ROI可以帮助我们减少不必要的计算,提高处理速度和精度。
例如,在机器视觉和深度学习中,我们通常会从输入图像中提取ROI,然后只对这些ROI进行分析和识别,这样可以大大提高计算效率。
'''
#Author :susocool
#Creattime:2024/1/15
#FileName:05-RIO
#Description:
'''
import cv2
import numpy as np
img=cv2.imread('D:/Py-code/opencv/01.1-hello2/xu.png')
RIO=img[280:340,330:390] # 获取ROI
img[273:333,100:160]=RIO # 将ROI复制到新的位置
cv2.imshow('image', img)
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有窗口
有时我们需要对 BGR 三个通道分别进行操作。这是你就需要把 BGR 拆
分成单个通道。
'''
#Author :susocool
#Creattime:2024/1/15
#FileName:05-RIO
#Description:
'''
import cv2
import numpy as np
img = cv2.imread('D:/Py-code/opencv/01.1-hello2/233.jpg') # 读取图像
b,g,r = cv2.split(img) # 分离图像的蓝色、绿色和红色通道
r[:] = 0 # 将红色通道的所有值设为0
img = cv2.merge([b,g,r]) # 合并通道
cv2.imshow('image', img) # 显示图像
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有窗口
r[:] = 0将红色通道的所有值设为0,这意味着图像中的所有红色成分都被移除了。然后,我们使用cv2.merge([b,g,r])将修改后的通道合并成一个新的图像。最后,我们使用cv2.imshow(‘image’, img)显示修改后的图像。
在Python中,r[:]这种写法被称为切片(slicing)。它可以用来访问或修改数组或列表的一部分。
当你写r[:]时,你实际上是在创建一个r的副本。这个副本包含了r的所有元素。所以,当你写r[:] =0时,你实际上是将r的所有元素都设置为0。
如果你只写r =0,那么r将不再是一个数组,而是一个值为0的整数。这显然不是我们想要的结果,因为我们希望保持r作为一个数组,并修改它的所有元素。
或者,可以直接使用img[:,:,2]=0,快速使所有像素的红色通道值都为 0。
import cv2
import numpy as np
img = cv2.imread('D:/Py-code/opencv/01.1-hello2/233.jpg') # 读取图像
b,g,r = cv2.split(img) # 分离图像的蓝色、绿色和红色通道
img = cv2.merge([b,g,r]) # 合并通道
img[:,:,2]=0
cv2.imshow('image', img) # 显示图像
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有窗口
在图像周围创建一个边,就像相框一样,你可以使用 cv2.copyMakeBorder()
函数。这经常在卷积运算或 0 填充时被用到。这个函数包括如下参数:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0936e75987a443e6a2fa71392302f8e1.png
实在懒得抄了,偷个懒。OpenCV-Python: cv2.copyMakeBorder()函数详解
'''
#Author :susocool
#Creattime:2024/1/15
#FileName:05-边框处理
#Description:使用copyMakeBorder函数添加蓝色边框
'''
import cv2
import numpy as np
BLUE = [255, 0, 0] # 定义蓝色
img = cv2.imread('D:/Py-code/opencv/01.1-hello2/233.jpg') # 读取图像
# 使用copyMakeBorder函数添加蓝色边框
# (20,10,10,10)上下左右 cv2.BORDER_CONSTANT作为边框类型
constant = cv2.copyMakeBorder(img, 20, 10, 10, 10, cv2.BORDER_CONSTANT, value=BLUE)
cv2.imshow('image', constant) # 显示图像
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有窗口
例如,如果你的图像是abcdefgh,那么使用cv2.BORDER_REPLICATE添加的边框将是aaaaaaaa|abcdefgh|hhhhhhhh
'''
#Author :susocool
#Creattime:2024/1/15
#FileName:05-边框
#Description:复制最边缘的像素
'''
import cv2
import numpy as np
img = cv2.imread('D:/Py-code/opencv/01.1-hello2/233.jpg') # 读取图像
# 为了使得结果更加明显增大范围
constant = cv2.copyMakeBorder(img, 50, 80, 100, 200, cv2.BORDER_REPLICATE)
cv2.imshow('image', constant) # 显示图像
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有窗口
学习的时候犯了一个错误,就是这个类型其实是根据边缘像素来做为边框,但是我最开始想要效果明显想给他添加蓝色的范围。。。
cv2.BORDER_REFLECT_101
是OpenCV中copyMakeBorder()
函数的一种边界类型。当你选择这种边界类型时,边界将是源图像边缘像素的镜像反射,但最外层的像素不会被复制。
例如,如果你的图像是abcdefgh
,那么使用cv2.BORDER_REFLECT_101
添加的边框将是gfedcb|abcdefgh|gfedcba
。
这种边界类型在需要扩展图像边缘的情况下非常有用,例如在进行卷积或其他需要额外像素的图像处理操作时。
'''
#Author :susocool
#Creattime:2024/1/15
#FileName:05-边框
#Description:镜像边框
'''
import cv2
import numpy as np
img = cv2.imread('D:/Py-code/opencv/01.1-hello2/233.jpg') # 读取图像
# 为了使得结果更加明显增大范围
constant = cv2.copyMakeBorder(img, 50, 80, 100, 200, cv2.BORDER_REFLECT_101)
cv2.imshow('image', constant) # 显示图像
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有窗口
cv2.BORDER_WRAP
是OpenCV中copyMakeBorder()
函数的一种边界类型¹²³。当你选择这种边界类型时,边界将形成一种“包装”效果,即图像的左边界与右边界相连,上下边界相连。
例如,如果你的图像是abcdefgh
,那么使用cv2.BORDER_WRAP
添加的边框将是cdefgh|abcdefgh|abcdefg
。
这种边界类型在需要扩展图像边缘的情况下非常有用,例如在进行卷积或其他需要额外像素的图像处理操作时。
# 标题我都不知道该怎么取了QAQ
import cv2
import numpy as np
img = cv2.imread('D:/Py-code/opencv/01.1-hello2/233.jpg') # 读取图像
# 为了使得结果更加明显增大范围
constant = cv2.copyMakeBorder(img, 50, 80, 80, 80, cv2.BORDER_WRAP)
cv2.imshow('image', constant) # 显示图像
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 关闭所有窗口
可以这么理解,就是前后左右互换位置,包裹住原图。
QWQ探索到此结束,下次有心情继续。