数字图像处理笔记(一)(基于python与OpenCV)

数字图像处理笔记(一)(基于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 可以像处理多维列表一样处理,通过对每一个像素的遍历,再对三个色彩通道的值取平均产生了一张灰度图,同时得到了三个颜色通道对应的图像,如下图:

数字图像处理笔记(一)(基于python与OpenCV)

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

矩阵方法:

数字图像处理笔记(一)(基于python与OpenCV)

使用 img_gray > 125 进行比较,输出一个 bool 类型的矩阵。在交互窗口进行了上图测试。所以将输出的矩阵直接*255,得到二值图。

库函数方法: 参考了https://blog.csdn.net/zj360202/article/details/79165796

实验结果与各个方法运行时间见下图(图像较大时,方法2可能比方法3快):

数字图像处理笔记(一)(基于python与OpenCV)

上一篇:python实现opencv学习二十二:人脸检测


下一篇:【车辆计数】基于光流法实现车辆检测计数matlab 源码