OpenCV StudyNote

Open CV学习

图像读取与显示

灰度图像 - 单通道

彩色图像 - 三通道 (B, G, R)

一般步骤

import cv2 as cv   					# 导入OpenCV支持(cv2是包的名称不是版本号)
import numpy as np					# 所有图像数据都是以 numpy 数组方式存储
imread(filename[,flags])			# imread 函数,读取图像
# filename 表示文件路径, []内可以不填
imshow(winname, mat)				# imshow 函数,显示图像
# winname 表示窗口标题, mat 表示图像对象
# 加载通道顺序



显示与等待时间

cv.wajitKey(0)

表示一直等待,直到任意一个键盘操作

cv.waitKey(1000)

表示等待1000ms即1s

如果不加, 图片会一闪而过

实例

import cv2 as cv
import numpy as np

def show_image():
    image = cv.imread("E:/data/lena.jpg")
    cv.imshow("input", image)
    cv.waitKey(0)
    cv.destroyAllWindows()

show_image()

OpenCV StudyNote_第1张图片

图像色彩空间转换

常用色彩空间:

OpenCV StudyNote_第2张图片

  • ​ HSV
    • 取值范围H:0 ~ 180,SV:0~255
  • ​ RGB
    • 计算机显示器的标准支持色彩系统
    • 色彩空间设备独立
    • 取值范围0~255
  • ​ YCrCb
    • •Y分量表示信息,CrCb可以被压缩

图像色彩转换

  • 从一个色彩空间转换到另外一个色彩空间

  • 信息传递与损失

  • 过程可逆与不可逆

函数与参数

cv.cvtColor(src,code[,dst[,dstCn]])->dst
# src表示输入图像, 类型CV_8U(np.uint8字节类型)、CV_32F(np.float32浮点数类型)

code表示:

cv::COLOR_BGR2RGB = 4      # 通道交换

cv::COLOR_BGR2GRAY = 6	   # 彩色到灰度

cv::COLOR_GRAY2BGR = 8	   # 灰度到彩色(信息损失不可逆)

cv::COLOR_BGR2HSV = 40     # 可以双线转换

示例:

import cv2 as cv
import numpy as np


def color_space_demo():
    image = cv.imread("lena.jpg")
    cv.imshow("lena", image)
    hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
    ycrcb = cv.cvtColor(image, cv.COLOR_BGR2YCrCb)
    cv.imshow("hsv", hsv)
    cv.imshow("ycrcb", ycrcb)
    cv.waitKey(0)
    cv.destroyAllWindows()

color_space_demo()

图像对象的创建与赋值

图像对象属性

  • 图像宽高 image.shape
  • 图像深度 image
  • 图像数据类型 image.dtype
  • 图像通道 image.shape
  • 数据类型
    • np.uint8
    • np.float32
    • np.int32
    • np.int64

Numpy 数据包函数

opencv-python中一切图像数据皆numpy array

*• numpy.array(object, dtype=None, , copy=True, order=‘K’, subok=False, ndmin=0, like=None)

  • object 数组

  • dtype 数据类型

*•numpy.zeros(shape, dtype=float, order=‘C’, , like=None)

  • 数组维度

  • dtype 数据类型

*•numpy.asarray(a, dtype=None, order=None, , like=None)

  • 数组对象

  • dtype 数据类型

•numpy.reshape(a, newshape, order=‘C’)

  • 数组维度

  • dtype 数据类型

import numpy as np
np.array([[1, 2],[3, 4]], dtype=np.uint8)

创建图像

•np.zeros ->创建一个黑色背景图像

•np.zeros_like->创建一个与输入图像大小一致的黑色背景图像

•np.ones创建一个全部像素值是1的图像

图像赋值

•图像赋值就是给numpy array数组赋值

•m = np.zeros((3, 3, 3), dtype=uint8)

•m[:] = 255

•创建数组m,然后赋值为255(白色)

•m[:] = (255,0,0)

•创建数组m,然后赋值为(255,0,0)蓝色

代码演示

def numpy_demo():
    m1 = np.array([[2,3], [4, 5]], dtype=np.uint8)
    print(m1)
    m2 = np.ones((4,4,3), dtype=np.uint8)
    print(m2)
    m2[:] = (255, 0, 0)
    print(m2)
    m3 = np.zeros((4,4,3),dtype=np.uint8)
    print(m3)
    m3[:]=255
    print(m3)
numpy_demo()

C:\use\anaconda\envs\openvino\python.exe C:/use/E/桌面/cv/opencv/test.py
[[2 3]
[4 5]]
[[[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]]

[[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]]

[[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]]

[[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]]]
[[[255 0 0]
[255 0 0]
[255 0 0]
[255 0 0]]

[[255 0 0]
[255 0 0]
[255 0 0]
[255 0 0]]

[[255 0 0]
[255 0 0]
[255 0 0]
[255 0 0]]

[[255 0 0]
[255 0 0]
[255 0 0]
[255 0 0]]]
[[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]]
[[[255 255 255]
[255 255 255]
[255 255 255]
[255 255 255]]

[[255 255 255]
[255 255 255]
[255 255 255]
[255 255 255]]

[[255 255 255]
[255 255 255]
[255 255 255]
[255 255 255]]

[[255 255 255]
[255 255 255]
[255 255 255]
[255 255 255]]]

进程已结束,退出代码0

def numpy_demo():
    black = np.zeros((512, 512, 3), dtype=np.uint8)
    black[:,0:255] = 255

    h,w,c = black.shape
    print(h,w,c)
    cv.imshow("black", black)
    cv.waitKey(0)
    cv.destroyAllWindows()

numpy_demo()

OpenCV StudyNote_第3张图片

图像像素的读写操作

像素访问与遍历

  • 像素遍历本质就是numpy数组访问

  • 假设变量image

  • 获取图像维度信息: image.shape

  • 图像访问像素: image[row, col]

  • 图像赋值像素: image[row, col] = (b,g,r)

像素读写

  • b, g, r = image[row, col]

  • image[row, col] = (255-b, 255-g, 255-r)

  • 读写像素,灰度图像:

  • pv = image[row, col]

  • image[row, col] = 255-pv

示例

def visit_pixel_demo():
    image = cv.imread("lena.jpg")
    cv.imshow("lina", image)
    h, w, c = image.shape
    for row in range(h):
        for col in range(w):
            b, g, r = image[row, col]
            # 反色
            image[row, col] = (255 - b, 255 - g, 255 - r)
    cv.imshow("visited", image)
    cv.waitKey(0)
    cv.destroyAllWindows()
visit_pixel_demo()

像素算数操作

算数操作

支持函数

  • cv.add(src1, src2[, dst[, mask[, dtype]]]) ->dst

  • cv.subtract(src1,src2[,dst[,mask[,dtype]]])->dst

  • cv.multiply(src1,src2[,dst[,scale[,dtype]]])->dst

  • cv.divide(src1, src2[, dst[, scale[, dtype]]])->dst

src1 & src2表示图像

加法,保证不越界:saturate(src1 + src2)-》0~255

超过255取255,小于0取0

  • mask参数
    • mask区域相加减,其他区域为零

实例

def arithmetic_demo():
    image1 = cv.imread("lena.jpg")
    h, w, c = image1.shape
    image2 = np.zeros_like(image1)
    image2[:,:] = (110, 0, 250)
    mask = np.zeros((h, w), dtype=np.uint8)
    mask[100:200,100:200] = 1;
    cv.imshow("img1", image1)
    cv.imshow("img2", image2)
    added = cv.add(image1, image2, mask = mask)
    cv.imshow("added", added)
    cv.waitKey(0)
    cv.destroyAllWindows()

arithmetic_demo()

OpenCV StudyNote_第4张图片

滚动条操作

事件响应函数

typedef void(* cv::TrackbarCallback) (int pos, void *userdata)
完成事件响应函数的声明与实现
// pos 滑块所在位置    userdata 用户数据
# 完成事件响应函数的声明与实现
def trackbar_callback (pos):
 print(pos)

创建窗口函数

cv.namedWindow(winname [, flags]) -> None
# 参数: winname表示窗口标题
# 参数flags支持的flag有:
# WINDOW_NORMAL – 可以调整窗口大小
# WINDOW_AUTOSIZE – 根据图像大小自动适应,不可调
# WINDOW_KEEPRATIO – 可以保持比例窗口,调整大小

调整图像亮度

•RGB值表示亮度

•RGB(0, 0,0) 黑色 - 》 RGB(255,255,255)白色

•add函数支持图像+图像与图像+常量方式

•subtract函数支持图像+图像与图像+常量方式

•通过他们可以修改图像的亮度

•动态调整,基于滚动条修改常量值,实现动态修改图像亮度并刷新显示

•创建图像窗口

•创建滚动条组件

•在窗口显示图像

•拖拉滚动条修改图像亮度

代码演示

def trackbar_callback(pos):
    print(pos)

def trackbar_demo():
    image = cv.imread("E:/data/butterfly.jpg")
    cv.namedWindow("trackbar_demo", cv.WINDOW_KEEPRATIO)
    # 创建滚动条
    cv.createTrackbar("lightness", "trackbar_demo", 0, 200, trackbar_callback)
    cv.imshow("trackbar_demo", image)
    while True:
        # 获取该窗口滚动条的位置
        pos = cv.getTrackbarPos("lightness", "trackbar_demo")
        image2 = np.zeros_like(image)
        image2[:, :] = (np.uint8(pos), np.uint8(pos), np.uint8(pos))
        # 提升亮度
        result = cv.add(image, image2)
        # 降低亮度
        # result = cv.subtract(image, image2)
        cv.imshow("trackbar_demo", result)
        c = cv.waitKey(1)
        if c == 27:
            break
    cv.waitKey(0)
    cv.destroyAllWindows()

trackbar_demo()

OpenCV StudyNote_第5张图片

键盘响应操作

键盘响应事件

cv.waitKey( [, delay]	) ->retval

delay如果没有声明或者delay=0,表示一直阻塞
delay大于0,表示阻塞指定毫秒数
retval返回的对应键盘键值,注意:在不同的操作系统中可能会有差异!
典型的retval = 27是ESC按键

响应不同的键盘操作

通过python的选择语句

推荐使用if-elif-else;switch-case方式python3.10支持

if <expr>:
    <statement(s)>
elif <expr>:
    <statement(s)>
elif <expr>:
    <statement(s)>
    ...
else:
    <statement(s)>

示例

image = cv.imread("E:/data/butterfly.jpg")
cv.namedWindow("keyboard_demo", cv.WINDOW_AUTOSIZE)
cv.imshow("keyboard_demo", image)
while True:
    c = cv.waitKey(10)
    # 按ESC退出
    if c == 27:
        break
    # 按0回复原图BGR显示
    elif c == 48:
        cv.imshow("keyboard_demo", image)
    # 按1显示HSV图像
    elif c == 49:
        hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
        cv.imshow("keyboard_demo", hsv)
    # 按2显示YCrCb
    elif c == 50:
        ycrcb = cv.cvtColor(image, cv.COLOR_BGR2YCrCb)
        cv.imshow("keyboard_demo", ycrcb)
    # 按3显示RGB图像
    elif c == 51:
        rgb = cv.cvtColor(image, cv.COLOR_BGR2RGB)
        cv.imshow("keylboard_demo", rgb)
cv.waitKey(0)
cv.destroyAllWindows()

自带颜色表操作

查找表(LUT)

空间换时间,避免重复计算,节约计算时间

OpenCV StudyNote_第6张图片

Gamma校正

G a m m a = k ∗ E r = 255 ∗ E l o g ( p ( x , y ) / 255 ) ∗ g a m m a Gamma =k*E^r=255*E ^ {log(p(x,y)/255)*gamma} Gamma=kEr=255Elog(p(x,y)/255)gamma

•公式p(x, y)表示输入图像像素值, gamma取值范围0.05~5之间

•像素值取值范围在0~255之间,每一个值对应一个输出值,这样映射关系,可以先建立查找表LUT

•根据输入得像素值作为index,在LUT中直接映射读取得到gamma校正之后得值

•对256x256大小的图像,计算量对比:

•不应用找表计算gamma - 65536次,

•应用查找表计算gamma – 256次

cv.applyColorMap(src, colormap[, dst]) ->dst
# 第一个参数输入图像
# 第二个参数是颜色表
# dst返回图像

OpenCV StudyNote_第7张图片

示例

def lut_demo():
    cv.namedWindow("lut-demo", cv.WINDOW_NORMAL)
    lut = [[255, 0, 255], [125, 0, 0], [127, 255, 200], [200,127, 127], [0, 255, 255]]
    m1 = np.array([[2, 1, 3, 0], [2, 2, 1, 1], [3, 3, 4, 4], [4,4,1,1]])
    m2 = np.zeros((4, 4, 3), dtype=np.uint8)
    for i in range(4):
        for j in range(4):
            index = m1[i, j]
            m2[i, j] = lut[index]
    cv.imshow("lut-demo", m2)
    cv.waitKey(0)
    cv.destroyAllWindows()

    lut2 = np.zeros((256), dtype=np.uint8)
    gamma = 0.7
    for i in range(256):
        print(i, "--", np.log(i / 255.0))
        lut2[i] = int(np.exp(np.log(i/255.0) * gamma) * 255.0)

    print(lut2)

    image = cv.imread("E:/data/butterfly.jpg")
    dst = cv.LUT(image, lut2)
    cv.imshow("butterfly-gamma", dst)

    cv.imshow("input", image)
    cv.namedWindow("butterfly-gamma", cv.WINDOW_AUTOSIZE)
    h, w, c = image.shape
    for row in range(h):
        for col in range(w):
            b, g, r = image[row, col]
            image[row, col] = (lut2[b], lut2[g], lut2[r])
    cv.imshow("butterfly-gamma", image)
    # 自定义查找表
    lut3 = np.zeros((256, 1, 3), dtype=np.uint8)
    for i in range(256):
        print(i, "--", np.log(i / 255.0))
        c = int(np.exp(np.log(i/255.0) * gamma) * 255.0)
        lut3[i, 0] = [c, c, c]
    print(lut3)
    dst = cv.LUT(image, lut3)
    cv.imshow("butterfly-gamma", dst)

    # 系统查找表
    dst = cv.applyColorMap(image, cv.COLORMAP_PINK)
    cv.imshow("butterfly-pink", dst)

    cv.waitKey(0)
    cv.destroyAllWindows()

lut_demo()

OpenCV StudyNote_第8张图片

你可能感兴趣的:(Python,opencv,计算机视觉,python)