当前位置:   article > 正文

【Opencv-Python】数字图像处理(一) —— 图像的基本操作_cv2 imshow

cv2 imshow


图像的基本操作

1. 实验目的和要求

2. 主要设备及环境

3. 实验内容及实验结果

3.0 实验准备

3.1 图像的读取

3.2 视频的读取

3.2.1 打开视频文件:

3.2.2 打开摄像头:

3.2.3 读取视频帧:

3.3 图像的显示

3.3.1 Opencv 方式

3.3.2 matplotlib 方式

3.4 图像的保存

3.4.1 读入彩色和灰度图像文件,并显示出来,同时给出图像的基本属性。

3.4.2 读取文件夹 images 的图像 lena.bmp,并显示出来。然后将图像另存为 lena.jpg,并比较两文件大小。

3.5 图像的通道拆分与合并

3.5.1 通道拆分

结论: 

3.5.2 通道合并

3.6 图像 ROI (region of interest )(图像剪裁)

3.6.1 运行实例 

3.6.2 思考题:怎样取出、修改图像某点的像素值?

3.7 图像坐标变换

3.7.1 图像缩放

(1)result = cv2.resize(src, (160,160)), 输出 result ,观察效果。

(2)result = cv2.resize(src, None, fx=0.5, fy=0.5), 输出 result,观察效果。

3.7.2 图像的仿射变换(实现图像缩放、图像旋转和图像平移)

3.8 图像色彩空间转化

3.8.1 运行实例:

3.8.2 思考:对比上一个 print 语句的输出有何不同?为什么?

4. 实验分析与思考


1. 实验目的和要求

(1)熟悉并掌握Python在处理图像方面的能力;

(2)精通在Python中使用opencv-python库读取图像的方法,包括读取不同格式的图像,以及调整图像大小、色彩转换等操作;

(3)掌握Python获取图像信息的方法,包括获取图像的大小、颜色、高度、宽度等相关信息,以及图像的通道等;

(4)掌握在Python中使用opencv-python按照指定要求存储一幅图像的方法,包括存储为不同格式的图像等操作;

(5)掌握图像间的转化方法,包括图像坐标变换和图像的色彩空间转化。

2. 主要设备及环境

(1)计算机;

(2)Python、Pycharm及Anaconda软件;

(3)典型的灰度、彩色图像文件。

3. 实验内容及实验结果

3.0 实验准备

        首先在程序开头导入 OpenCV 模块。

import cv2

3.1 图像的读取

        函数返回一个(行数(高),列数(宽),颜色通道数)的多维阵列,表示图像数据,默认的颜色次序为 BGR。

img = cv2.imread(文件名[,参数])

其中第一个参数为图像文件的路径,第二个参数(可选)的主要形式有:

(1) cv2.IMREAD_UNCHANGED (图像不可变);

(2) cv2.IMREAD_GRAYSCALE (灰度图像);

(3) cv2.IMREAD_COLOR (读入彩色图像),这是默认参数,不填的话默认为这个。

  1. import cv2
  2. jpg = cv2.imread('D:\images\lena_noise.jpg')
  3. print(jpg.shape)

运行结果:

print(image.shape) 返回一个三元组,分别是图像的高度宽度颜色通道数。

3.2 视频的读取

        用同样的方法读取视频文件、USB 摄像头及监控摄像头的视频帧。

#打开视频文件
cap=cv2.VideoCapture('./images/1.avi')


#打开内置或 USB 摄像头,0 表示第一个摄像头
cap=cv2.VideoCapture(0)

#判断 VideoCaputre 对象是否成功打开,只有成功打开才能进行读操作

if cap.isOpened():                                      #VideoCaputre 对象成功打开
        print('已经打开了视频文件或摄像头')
else:
        print('视频文件或摄像头打开失败')

3.2.1 打开视频文件:
  1. mp4 = cv2.VideoCapture('D:/video/zoo.mp4')
  2. if mp4.isOpened(): #VideoCaputre 对象成功打开
  3. print('已经打开了视频文件')
  4. else:
  5. print('视频文件打开失败')

运行结果:

删除视频文件后运行结果:

3.2.2 打开摄像头:
  1. cap=cv2.VideoCapture(0)
  2. if cap.isOpened(): #VideoCaputre 对象成功打开
  3.      print('已经打开了摄像头')
  4. else:
  5.      print('摄像头打开失败')

运行结果:

3.2.3 读取视频帧:

ret, frame = cap.read()   # 读取一帧视频

其中 ret 是布尔值,如果读取帧是正确的则返回 True,如果文件读取到结尾,它的返回值就为 False。frame 就是每一帧的图像,是个三维矩阵。

  1. import cv2
  2. # 打开视频
  3. mp4 = cv2.VideoCapture('D:/video/zoo.mp4')
  4. if mp4.isOpened(): #VideoCaputre 对象成功打开
  5.     print('已经打开了视频文件')
  6. else:
  7.     print('视频文件打开失败')
  8.     exit()
  9. while True:
  10.     # 读取一帧视频
  11.     ret, frame = mp4.read()  # 读取一帧视频
  12.     if not ret:
  13.         break  # 如果无法读取帧,则跳出循环
  14.     # 显示原始帧
  15.     cv2.imshow('frame', frame)  # 显示原始帧
  16.     # 如果按下 'q' 键,则退出循环
  17.     if cv2.waitKey(1) & 0xFF == ord('q'):  # 如果按下 'q' 键,则退出循环
  18.         break
  19.     # 释放摄像头并关闭所有窗口
  20. mp4.release()
  21. cv2.destroyAllWindows()

运行结果:

3.3 图像的显示

3.3.1 Opencv 方式

cv2.imshow(窗口名, img)


cv2.waitKey(0)

#等待显示,如果没有这句的话,图片就会显示一下立马消失
#0 表示无限制的等待(按任意键就退出),大于 0(如 5)表示等待 5ms 自
#动关闭窗口


cv2.destroyAllWindows()      #从内存将窗口清除

  1. jpg = cv2.imread('D:\images\lena_noise.jpg')
  2. cv2.namedWindow("demo1")
  3. cv2.imshow("demo1",jpg)
  4. cv2.waitKey(delay = 0)#等待显示,如果没有这句的话,图片就会显示一下立马消失
  5. #0 表示无限制的等待(按任意键就退出),大于 0(如 5)表示等待 5ms 自动关闭窗口
  6. cv2.destroyAllWindows() #从内存将窗口清除

运行结果:

3.3.2 matplotlib 方式

from matplotlib import pyplot as plt             #首先导入 pyplot 模块


rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#将 opencv 用的的 BGR 通道顺序变为 plt 用
#的 RGB 顺序 


plt.imshow(rgb)
plt.xticks([]), plt.yticks([])
plt.show()

  1. import cv2
  2. jpg = cv2.imread('D:\images\lena_noise.jpg')
  3. from matplotlib import pyplot as plt #首先导入 pyplot 模块
  4. rgb = cv2.cvtColor(jpg, cv2.COLOR_BGR2RGB) #将 opencv 用的的 BGR 通道顺序变为 plt 用的 RGB 顺序
  5. plt.imshow(rgb)
  6. plt.xticks([]), plt.yticks([])
  7. plt.show()

运行结果:

3.4 图像的保存

cv2.imwrite(文件名, img)

3.4.1 读入彩色和灰度图像文件,并显示出来,同时给出图像的基本属性。
  1. import cv2
  2. img = cv2.imread("D:/images/mother_baby.tif ")
  3. print('color image shape: ', img.shape) #打印出彩色图像的形状信息
  4. print('color image size: ', img.size) #打印出彩色图像的大小
  5. print('color image 数据类型: ', img.dtype) #图像数据的类型
  6. print('\n')
  7. #获取图像高、宽:
  8. #rows, cols = img.shape[:2]
  9. rows = img.shape[0]
  10. cols = img.shape[1]
  11. print('color image width: ', cols)
  12. print('color image height: ', rows)
  13. print('\n')  #换行
  14. img_gray = cv2.imread("D:/images/lena_gray_256.tif", cv2.IMREAD_UNCHANGED)
  15. print('gray image shape: ', img_gray.shape)
  16. print('gray image size: ', img_gray.size)
  17. print('gray image 数据类型: ', img_gray.dtype)
  18. print('\n')
  19. rows_gray = img_gray.shape[0]
  20. cols_gray = img_gray.shape[1]
  21. print('gray image width: ', cols_gray)
  22. print('gray image height: ', rows_gray)
  23. # 显示图像
  24. cv2.imshow("color image ", img)
  25. cv2.imshow("gray image ", img_gray)
  26. # 等待显示
  27. cv2.waitKey(0)
  28. cv2.destroyAllWindows()

运行结果:

3.4.2 读取文件夹 images 的图像 lena.bmp,并显示出来。然后将图像另存为 lena.jpg,并比较两文件大小。
  1. import cv2
  2. # 读取图像
  3. img = cv2.imread("D:/images/lena.bmp")
  4. # 另存为 lena.jpg
  5. cv2.imwrite("D:/images/lena.jpg", img)
  6. # 打印原始图像大小
  7. print('lena bmp size: ', img.size)
  8. # 打印jpg图像大小
  9. jpg_lena = cv2.imread("D:/images/lena.jpg")
  10. print('lena jpg size: ', jpg_lena.size)
  11. # 显示原始图像
  12. cv2.imshow('BMP Image', img)
  13. # 显示jpg图像
  14. cv2.imshow('JPG Image', jpg_lena)
  15. # 等待显示
  16. cv2.waitKey(0)
  17. cv2.destroyAllWindows()

运行结果:

3.5 图像的通道拆分与合并

3.5.1 通道拆分

        拆分后,输出 b,g,r 三幅图像。看看哪幅图像最亮,并解释原因。

方法一:

b, g, r = cv2.split(img)

方法二:

b = img[:, :, 0]

g = img[:, :, 1]

r = img[:, :, 2]

方法三:

b = cv2.split(img)[0]

g = cv2.split(img)[1]

r = cv2.split(img)[2]

  1. import cv2
  2. import numpy as np
  3. # 创建一个彩色图像
  4. img = cv2.imread('D:/images/lena.bmp')
  5. # 使用cv2.split()分割图像
  6. b, g, r = cv2.split(img)
  7. # 保存为图像
  8. cv2.imwrite('blue_channel.jpg', b)
  9. cv2.imwrite('green_channel.jpg', g)
  10. cv2.imwrite('red_channel.jpg', r)
  11. # 分别显示三个通道的图像
  12. cv2.imshow('Blue Channel', b)
  13. cv2.imshow('Green Channel', g)
  14. cv2.imshow('Red Channel', r)
  15. # 打印每个通道的亮度(即像素值范围)
  16. print('Blue Channel brightness:', np.max(b))
  17. print('Green Channel brightness:', np.max(g))
  18. print('Red Channel brightness:', np.max(r))
  19. # 等待键盘输入并关闭窗口
  20. cv2.waitKey(0)
  21. cv2.destroyAllWindows()

输出结果:

结论: 

        哪幅图像最亮取决于图像的内容和颜色分布。在图像中,红色通道是最亮的,其次,蓝色通道比绿色通道亮,因为空气对蓝色光的散射强。

3.5.2 通道合并

m = cv2.merge([b, g, r])

  1. import cv2
  2. # 创建一个彩色图像
  3. img = cv2.imread('D:/images/lena.bmp')
  4. # 使用cv2.split()分割图像
  5. b, g, r = cv2.split(img)
  6. # 保存为图像
  7. cv2.imwrite('blue_channel.jpg', b)
  8. cv2.imwrite('green_channel.jpg', g)
  9. cv2.imwrite('red_channel.jpg', r)
  10. # 分别显示三个通道的图像
  11. cv2.imshow('Blue Channel', b)
  12. cv2.imshow('Green Channel', g)
  13. cv2.imshow('Red Channel', r)
  14. # 将通道合并
  15. merged_img = cv2.merge([b, g, r])
  16. # 显示合并后的图像
  17. cv2.imshow('Merged Image', merged_img)
  18. # 关闭窗口
  19. cv2.waitKey(0)
  20. cv2.destroyAllWindows()

输出结果:

3.6 图像 ROI (region of interest )(图像剪裁)

img = cv2.imread("图像文件名")

subimg=img[r1:r2, c1:c2]

# 输出 subimg,观察效果。

3.6.1 运行实例 
  1. import cv2
  2. # 读取图像
  3. img = cv2.imread('D:/images/lena.bmp')
  4. # 截取子图像
  5. subimg = img[50:150, 100:200]
  6. # 显示子图像
  7. cv2.imshow('Subimage', subimg)
  8. # 等待键盘输入,然后关闭窗口
  9. cv2.waitKey(0)
  10. cv2.destroyAllWindows()

输出结果:

3.6.2 思考题:怎样取出、修改图像某点的像素值?

        导入图像,将它转化为数组形式,对每一个像素点的像素值进行调整和修改并输出。

3.7 图像坐标变换

3.7.1 图像缩放
(1)result = cv2.resize(src, (160,160)), 输出 result ,观察效果。
  1. import cv2
  2. # 加载图像
  3. src = cv2.imread('D:/images/lena.bmp')
  4. # 缩放图像
  5. result = cv2.resize(src, (160, 160))
  6. # 保存缩放后的图像
  7. cv2.imwrite('resized_image.jpg', result)
  8. # 显示图像
  9. cv2.imshow('result', result)
  10. # 等待键盘输入,然后关闭窗口
  11. cv2.waitKey(0)
  12. cv2.destroyAllWindows()

输出结果:

(2)result = cv2.resize(src, None, fx=0.5, fy=0.5), 输出 result,观察效果。
  1. import cv2
  2. # 加载图像
  3. src = cv2.imread('D:/images/lena.bmp')
  4. # 修改图像
  5. result = cv2.resize(src, None, fx=0.5, fy=0.5)
  6. # 保存修改后的图像
  7. cv2.imwrite('resized_image.jpg', result)
  8. # 显示图像
  9. cv2.imshow('result', result)
  10. # 等待键盘输入,然后关闭窗口
  11. cv2.waitKey(0)
  12. cv2.destroyAllWindows()

输出结果:

3.7.2 图像的仿射变换(实现图像缩放、图像旋转和图像平移)

         编写程序来使用 cv2.warpAffine() 函数(先读入图像,然后用该函数对图像做各种变换,最后显示各种变换后的图像效果)。

  1. import cv2
  2. import numpy as np
  3. # 读入图像
  4. img = cv2.imread('D:/images/lena.bmp')
  5. # 定义变换矩阵
  6. M = np.float32([[1, 0, 100], [0, 1, 50]])
  7. # 进行变换
  8. dst = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
  9. # 显示原图和变换后的图像
  10. cv2.imshow('Original Image', img)
  11. cv2.imshow('Affine Transformed Image', dst)
  12. cv2.waitKey(0)
  13. cv2.destroyAllWindows()

输出结果:

3.8 图像色彩空间转化

dst = cv2.cvtColor(src, 参数)

其中常用的参数有:

cv2.COLOR_BGR2GRAY

cv2.COLOR_BGR2RGB

cv2.COLOR_BGR2HSV

cv2.COLOR_RGB2BGR

cv2.COLOR_GRAY2BGR

3.8.1 运行实例:
  1. import cv2
  2. img = cv2.imread("D:/images/lena.bmp")
  3. print('image shape: ', img.shape)
  4. # 图像颜色转换
  5. gray_img= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  6. print('gray image shape: ', gray_img.shape)
  7. # 显示图像
  8. cv2.imshow("src", img)
  9. cv2.imshow("result", gray_img)
  10. # 等待显示
  11. cv2.waitKey(0)
  12. cv2.destroyAllWindows()

输出结果:

3.8.2 思考:对比上一个 print 语句的输出有何不同?为什么?

        原始图像的形状通常为 (height, width, channels),其中channels通常为3(对应RGB)。灰度图像的形状为 (height, width),因为灰度图像只有一个通道。

4. 实验分析与思考

       在实验中遇到预想之外的问题(比如得到的图像处理效果与预期不同),自己找到原因,并想到办法加以解决。

        (1)运行时,配置环境未选择anaconda,所以报错,选择后解决;

        (2)img= cv2.imread('D:\images\lena_noise.jpg') 报错,因为返回值不是img,应该是jpg,修改成jpg之后运行成功;

        (3)print(image.shape)返回一个三元组,分别是图像的高度,宽度和颜色通道数;

        (4)变量“jpg”没有被定义,要在调用cv2.cvtColor(jpg, cv2.COLOR_BGR2RGB)之前读取一张图片并将其存储在变量“jpg”中;

        报错:

        添加语句后:


  如果觉得作者写得还不错的话, 点赞 / 收藏 / 评论 / 转发 四连支持一下吧~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/678731
推荐阅读
相关标签