当前位置:网站首页>OpenCV基础图像的基本操作
OpenCV基础图像的基本操作
2022-08-06 21:49:00 【华为云】
前文
使用 Maplotlib 集合 Numpy 绘制 2D 图形
加载图像
- imread 功能是加载图像文件成为一个 Mat 对象,其中第一个参数表示图像文件名称,第二个参数表示加载的图像是什么类型,支持常见的三个参数值
- IMREAD_UNCHANDED(<0) 表示加载原图,不做任何改变
- IMREAD_GRAYSCALE(0) 表示吧原图作为灰度图像加载进来
- IMREAD_COLOR(>0) 表示把原图作为 RGB 图像加载进来
注意:OpenCV 支持 JPG、PNG、TIFF 等常见格式图像文件加载(默认读取的格式是 BGR)
# 导入 OpenCV 库import cv2 as cv# 加载图像img = cv.imread("./1.jpg")# 打印图像类型print(type(img))print(img)输出:
可以发现这是个 numpy 数据类型的,而且是三个维度的,比如 [H,W,C]
图像显示
# 导入 OpenCV 库import cv2 as cv# 加载图像img = cv.imread("./1.jpg")# 图像的显示,也可以创建多个窗口cv.imshow("image",img)# 等待时间,毫秒级,0 表示任意键终止cv.waitKey(0)cv.destroyAllWindows()输出:(按下任意键关闭该窗口)
数据读取 - 图像
# 导入 OpenCV 库import cv2 as cv# 灰色显示img = cv.imread("./1.jpg",cv.IMREAD_GRAYSCALE)# 打印信息print(img)输出:
这里打印的结果就不像上面那样有三个维度了,因为是灰色的,也就是没有彩色的,所以这里表示的只有 H 和 W
当然,这里的代码只是打印信息而已,还不能显示到窗口,显示到窗口还需要增加几句代码,如下:
# 导入 OpenCV 库import cv2 as cvimg = cv.imread("./1.jpg",cv.IMREAD_GRAYSCALE)cv.imshow("image",img)cv.waitKey(0)cv.destroyAllWindows()输出:(可以发现,图片是以灰色显示了的)
截取部分图像数据
# 导入 OpenCV 库import cv2 as cv# 加载图像img = cv.imread("./1.jpg",)# 截取部分图像cat = img[0:200, 0:200]# 显示截取的图像cv.imshow("cat",cat)cv.waitKey(0)cv.destroyAllWindows()输出
颜色通道提取
通过 cv2 的 split() 方法可以进行颜色的通道提取
# 导入 OpenCV 库import cv2 as cvimg = cv.imread("./1.jpg",)b,g,r = cv.split(img)print(b)输出:
只保留 R
上面说过 OpenCV 默认读取的格式是 BGR
# 导入 OpenCV 库import cv2 as cvimg = cv.imread("./1.jpg",)cur_img = img.copy()# 注意参数的变化cur_img[:,:,0] = 0cur_img[:,:,1] = 0cv.imshow('R',cur_img)cv.waitKey(0)cv.destroyAllWindows()
R 是 Red 的缩写,这里显示的是红色
只保留 G
# 导入 OpenCV 库import cv2 as cvimg = cv.imread("./1.jpg",)cur_img = img.copy()# 注意参数的变化cur_img[:,:,0] = 0cur_img[:,:,2] = 0cv.imshow('G',cur_img)cv.waitKey(0)cv.destroyAllWindows()
G 是 Green 的缩写,这里显示的是绿色
只保留 B
# 导入 OpenCV 库import cv2 as cvimg = cv.imread("./1.jpg",)cur_img = img.copy()# 注意参数的变化cur_img[:,:,1] = 0cur_img[:,:,2] = 0cv.imshow('B',cur_img)cv.waitKey(0)cv.destroyAllWindows()
B 是 Blue 的缩写,这里显示的是蓝色
边界填充
# 导入 OpenCV 库import cv2 as cv# 导入 maplotlibimport matplotlib.pyplot as pltimg = cv.imread("./1.jpg",)# 定义图片显示大小top_size,buttom_size,left_size,right_size = (50,50,50,50)# 复制法,也就是复制最边缘像素replicate = cv.copyMakeBorder(img,top_size,buttom_size,left_size,right_size,borderType=cv.BORDER_REPLICATE)# 反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcbajabcdefghjhgfedcbreflect = cv.copyMakeBorder(img,top_size,buttom_size,left_size,right_size,borderType=cv.BORDER_REFLECT)# 反射法,也就是以最边缘像素为轴、对称、gfedcbjabcdefghigfedcbareflect01 = cv.copyMakeBorder(img,top_size,buttom_size,left_size,right_size,borderType=cv.BORDER_REFLECT_101)# 外包装法 cdeifghjabcdefghjabcdefgwrap = cv.copyMakeBorder(img,top_size,buttom_size,left_size,right_size,borderType=cv.BORDER_WRAP)# 常量法,常数值填充constant = cv.copyMakeBorder(img,top_size,buttom_size,left_size,right_size,borderType=cv.BORDER_CONSTANT)# 设置图像位置plt.subplot(231)# 设置图像显示plt.imshow(img,'gray')# 设置标题plt.title('ORIGINAL')plt.subplot(232)plt.imshow(replicate,'gray')plt.title("REPLICATE")plt.subplot(233)plt.imshow(reflect,'gray')plt.title("REFLECT")plt.subplot(234)plt.imshow(reflect01,'gray')plt.title("REPLICATE01")plt.subplot(235)plt.imshow(wrap,'gray')plt.title("WRAP")plt.subplot(236)plt.imshow(constant,'gray')plt.title("CONSTANT")# 图像显示plt.show()
第一幅图是原始的图片,其它的都是进行过处理的
- BORDER_REPLICATE : 复制法,也就是复制最边缘像素
- BORDER_REFLECT :反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcbajabcdefghjhgfedcb(这里我也不是很明白,会的朋友请在评论区解释下,感谢)
- BORDER_REFLECT_101 : 反射法,也就是以最边缘像素为轴、对称、gfedcbjabcdefghigfedcba
- BORDER_WRAP : 外包装法 cdeifghjabcdefghjabcdefg
- BORDER_CONSTANT : 常量法,常数值填充
数值计算
import cv2 as cvimg = cv.imread("./1.jpg")img2 = img + 10img[:5,:,0]print(img)print("--------------------------")print(img2)我们来看下这段代码的输出结果:(由于输出结果有点长,这里只截取部分结果)
这是 img 的输出,注意观察它的值
这是 img2 的输出,可以发现,img2 中的每个值都加了 10 ,如果值超出 255 ,
则得到结果如:253 + 10 = 263,263 - 255 = 7,那么计算结果就为 7
图像融合
需要融合的两张图像如下:
import cv2 as cvimg = cv.imread("./1.jpg")img_cat = cv.imread("./2.jpg")result = img + img_catprint(result)输出:
说明 img 和 img_cat 的值是不相同的,所以需要转换一下
import cv2 as cvimg = cv.imread("./1.jpg")img_cat = cv.imread("./2.jpg")print(img.shape)print(img_cat.shape)
可以发现,两张图像的 H 和 W 值确实是不相等的,所以无法进行数值相加
正确计算数值
import cv2 as cvimg = cv.imread("./1.jpg")img_cat = cv.imread("./2.jpg")print(img.shape)# 设置与 img 一样的数值img_cat = cv.resize(img_cat,(721,300))print(img_cat.shape)
现在两张的数值是相等的了,可以进行图像融合了,这里其实就是使用了 resize() 方法将其扩大了
完整代码:
import cv2 as cvimport matplotlib.pyplot as pltimg = cv.imread("./1.jpg")img_cat = cv.imread("./2.jpg")# 设置与 img 一样的数值img_cat = cv.resize(img_cat,(721,300))# 设置宽度值res = cv.addWeighted(img,0.4,img_cat,0.6,0)# 图像显示plt.imshow(res)plt.show()输出:(prefect)
图像保存
图像的保存非常简单,只需要使用 imwrite() 方法即可将图像保存起来
# 导入 OpenCV 库import cv2 as cv# 读取图像img = cv.imread("./1.jpg",cv.IMREAD_GRAYSCALE)# 图像保存# 第一个参数是图像要保存的路径,第二个图像是要保存的图像cv.imwrite("./demo.jpg",img)执行上面的代码就会在当前路径下生成一整 demo.jpg 的图像
数据读取 - 视频
- cv2.VideoCapture 可以捕获摄像头,用数字来控制不同的设备,例如 0,1
- 如果是视频文件,直接指定好路径即可
举例:
(1)读取视频
video = cv2.VideoCapture("demo.mp4")(2)检查视频是否打开正确
# 检查是否打开正确if video.isOpened(): # 我们都知道视频和游戏其实都是由图像组成的,通过访问图像的帧数连贯形成的,这里也是一样 # video.read() 一帧一帧地读取 # open 得到的是一个布尔值,就是 True 或者 False # frame 得到当前这一帧的图像 open, frame = video.read()else: open = False(3)遍历每一帧图像
while open: ret, frame = video.read() # 如果读到的帧数不为空,那么就继续读取,如果为空,就退出 if frame is None: break if ret == True: # 转换为灰度图 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow("video",gray) # 这里使用 waitKey 可以控制视频的播放速度,数值越小,播放速度越快 # 这里等于 27 也即是说按下 ESC 键即可退出该窗口 if cv2.waitKey(10) & 0xFF == 27: breakvideo.release()cv2.destroyAllWindows()完整代码如下:
import cv2video = cv2.VideoCapture("./demo.mp4")# 检查是否打开正确if video.isOpened(): # 我们都知道视频和游戏其实都是由图像组成的,通过访问图像的帧数连贯形成的,这里也是一样 # video.read() 一帧一帧地读取 # open 得到的是一个布尔值,就是 True 或者 False # frame 得到当前这一帧的图像 open, frame = video.read()else: open = Falsewhile open: ret, frame = video.read() # 如果读到的帧数不为空,那么就继续读取,如果为空,就退出 if frame is None: break if ret == True: # 转换为灰度图 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow("video",gray) # 这里使用 waitKey 可以控制视频的播放速度,数值越小,播放速度越快 # 这里等于 27 也即是说按下 ESC 键即可退出该窗口 if cv2.waitKey(10) & 0xFF == 27: breakvideo.release()cv2.destroyAllWindows()运行该程序就会去读取当前路径下的 demo.mp4 文件,将视频显示在名为 video 的窗口上,如下:

当然,上面的程序是将原视频设置为灰色的,想要显示的是原视频,只需要修改上述代码中的两个部分就行了
- 注释掉设置灰色的部分
- 将原视频显示在窗口上

边栏推荐
- 口服产品上市叠加成人市场发展,生长激素赛道发展突破口显现
- AVL树插入新节点后调整的四种情况(左单旋、右单旋、双旋)
- 利用类加载器获取文件路径报错空指针异常
- random number from min to max
- Mel滤波器:模拟人耳对不同频率语音的感知【人类对频率的感知不是线性的】【对低频信号的感知要比高频信号敏感;对1kHz以下,与频率成线性关系;对1kHz以上,与频率成对数关系】【频率越高,感知力越弱】
- pinia 基于插件pinia-plugin-persist的 持久化
- 3. 栈基本概念、【顺序栈、共享栈 和 链栈】代码实现
- Qt报错:undefined reference to xxxxx
- Axure9 basic interactions (2)
- 自注意力机制
猜你喜欢
随机推荐
HCIP笔记(七)
从To C到To B、To G,多多云科技如何实现转型
Cmake 重构旧Makefile 工程记录
自注意力机制
利用类加载器获取文件路径报错空指针异常
ASW3642 pin√pin替代TS3DV642方案,可使用原小板只需简单调整外围|ASW3642 HDMI二切一双向切换器方案
【ECCV2022】OSFormer: One-Stage Camouflaged Instance Segmentation with Transformers
uniapp Jiugongge lottery controllable probability effect demo (sorting)
BUU刷题记6
QT:实现一个W P S的界面以及操作,每一步都有图解,一步一步设置和解析
HCIP笔记(九)
Qt报错:undefined reference to xxxxx
Django项目的创建、Admin后台系统以及数据库迁移
MMDtection3D
Embedded Sharing Collection 30
xp系统怎么升级win7系统版本
OSPF综合实验
package DotaChessSelfPlay is not in GOROOT以及 relative import paths are not supported in module mode
Before start of result set报错(已解决)
win32 overview and framework










