数字图像处理笔记(一)(基于python与OpenCV)
一、读取图像、视频和摄像头
import cv2
# 打开图片并显示
img = cv2.imread("resources/lena.png")
cv2.imshow("Lena", img)
cv2.waitKey(0)
# 打开视频并显示
cap = cv2.VideoCapture("resources/test_video.mp4")
while True:
success, img = cap.read()
if not success:
break
cv2.imshow("video", img)
if cv2.waitKey(20) & 0xFF == ord('q'):
# 关于waitKey:https://blog.csdn.net/weixin_44049693/article/details/106271643
break
# 打开摄像头并显示
cap = cv2.VideoCapture(0) # 0对应笔记本摄像头
while True:
success, img = cap.read()
if not success:
break
cv2.imshow("video", img)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
# 打开摄像头plus版本
frameWidth = 640
frameHeight = 480
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 第二个参数可以避免在退出时报错,默认为cv2.CAP_ANY
# https://docs.opencv.org/3.4/d0/da7/videoio_overview.html
# https://www.cnblogs.com/cyssmile/p/12611843.html
cap.set(3, frameWidth) # 3 4 10没有实际意义,类似于功能号
cap.set(4, frameHeight)
cap.set(10, 150) # 设置亮度
while True:
success, img = cap.read()
cv2.imshow("Result", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release() # 释放摄像头
cv2.destroyAllWindows()
几个注意点:
- waitKe(): https://blog.csdn.net/weixin_44049693/article/details/106271643
- 摄像头关闭时要释放,同时打开摄像头时,使用接口cv2.CAP_DSHOW,经测试cv2.CAP_ANY, cv2.CAP_MSMF, cv2.CAP_V4L都会有报错。目前不知道具体的原因。
二、彩图、灰度图、二值图
1、彩图与灰度图
import cv2
import numpy as np
import time
img = cv2.imread("resources/LenaPlus.png")
img = cv2.resize(img, (500, 250))
height, width, channel = img.shape
# img[i][j] i为行,j为列
img_gray = np.zeros([height, width])
# 这里可以直接生成默认的全零矩阵,但是在显示图像之前需要把数据类型转换为 uint8
img_red = np.zeros([height, width], np.uint8)
# 也可以直接生成 uint8 的全零矩阵,后期就不需要再次变换
img_green = np.zeros([height, width], np.uint8)
img_blue = np.zeros([height, width], np.uint8)
i = 0
for row in img:
j = 0
for pixel in row:
# print(pixel) # 某个打印值:[127 117 195],对应BGR三个通道
gray = int((int(pixel[0]) + int(pixel[1]) + int(pixel[2]))/3)
img_gray[i][j] = gray
blue, green, red = pixel
img_red[i][j] = red
img_green[i][j] = green
img_blue[i][j] = blue
j += 1
i += 1
img_gray = np.uint8(img_gray)
cv2.imshow("Lena gray", img_gray)
cv2.imshow("Lena original", img)
cv2.imshow("Lena red", img_red)
cv2.imshow("Lena green", img_green)
cv2.imshow("Lena blue", img_blue)
cv2.waitKey(0)
cv2.destroyAllWindows()
打开的图像 img 可以像处理多维列表一样处理,通过对每一个像素的遍历,再对三个色彩通道的值取平均产生了一张灰度图,同时得到了三个颜色通道对应的图像,如下图:
2、灰度图二值化(比较了三个方法的运行时间)
import cv2
import numpy as np
import time
# 灰度图简单二值化
img = cv2.imread("resources/LenaPlus.png")
img = cv2.resize(img, (500, 250)) # 修改图像大小
height, width, channel = img.shape
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 遍历方法
print("二值化,遍历方法:")
img_binary = np.zeros([height, width], np.uint8)
start = time.time()
for i in range(height):
for j in range(width):
img_binary[i][j] = 255 if img_gray[i][j] > 125 else 0
cv2.imshow("Lena binary", img_binary)
end = time.time()
print("Running time: %s Seconds" % (end-start))
# 矩阵方法
print("二值化,矩阵方法:")
start = time.time()
img_bool = img_gray > 125
img_binary2 = img_bool * 255
cv2.imshow("Lena binary2", np.uint8(img_binary2))
end = time.time()
print("Running time: %s Seconds" % (end-start))
# 库函数方法
print("二值化,库函数方法:")
start = time.time()
ret, img_binary3 = cv2.threshold(img_gray, 125, 255, cv2.THRESH_BINARY)
# https://blog.csdn.net/zj360202/article/details/79165796
cv2.imshow("Lena binary3", np.uint8(img_binary3))
end = time.time()
print("Running time: %s Seconds" % (end-start))
cv2.waitKey(0)
cv2.destroyAllWindows()
遍历方法: 遍历每一个像素,大于125输出255,否则输出0
矩阵方法:
使用 img_gray > 125 进行比较,输出一个 bool 类型的矩阵。在交互窗口进行了上图测试。所以将输出的矩阵直接*255,得到二值图。
库函数方法: 参考了https://blog.csdn.net/zj360202/article/details/79165796
实验结果与各个方法运行时间见下图(图像较大时,方法2可能比方法3快):