OpenCV学习——图像基础与几何变换

OpenCV学习——图像基础与几何变换

0. 版本信息

产品 版本
Python 3.7
Anaconda 4.8.3
Jupyter 6.0.3
OpenCV 3.4.2

1. 导包

import cv2
import numpy as np
print(cv2.__version__)

2. 图像基础

2.1 图片的读取、展示、保存

  • 读取图片并展示
    # 读取相对路径为./test03.jpg的图片
    img = cv2.imread("./test03.jpg", 1)
    # 展示图片到名为picture的窗口
    cv2.imshow("picture", img)
    
    # 等待按键,如果按下的是q,那么关闭所有窗口
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()
        # cv2.destroyWindow("picture") # 关闭某个名称的窗口
    

图片1

  • 保存与压缩图片
    # jpg 设置保存图片的质量,有损压缩
    img = cv2.imread("test03.jpg", 1)
    cv2.imwrite("test03_copy_0.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 0])
    cv2.imwrite("test03_copy_10.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 10])
    cv2.imwrite("test03_copy_50.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 50])
    cv2.imwrite("test03_copy_80.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 80])
    
    # png 无损压缩,透明度,压缩比 0-10 值越低,压缩率越低
    img = cv2.imread("test03.jpg", 1)
    cv2.imwrite("test03_copy_0.png", img, [cv2.IMWRITE_PNG_COMPRESSION, 0])
    cv2.imwrite("test03_copy_3.png", img, [cv2.IMWRITE_PNG_COMPRESSION, 3])
    cv2.imwrite("test03_copy_5.png", img, [cv2.IMWRITE_PNG_COMPRESSION, 5])
    cv2.imwrite("test03_copy_8.png", img, [cv2.IMWRITE_PNG_COMPRESSION, 8])
    cv2.imwrite("test03_copy_10.png", img, [cv2.IMWRITE_PNG_COMPRESSION, 10])
    

2.2 图片的基本信息

  • 图片的维度(包含高度、宽度、像素点的三个通道值)
    print(img.shape)
    
    (512, 820, 3)
    
  • OpenCV中一个像素点的表示方式(BGR)
    # 获取其中的一个像素点
    # opencv中表示的方式为 BGR (即第一个是蓝色通道的值,第二个是绿色通道的值,第三个是红色通道的值)
    print(img[100, 150])
    
    [203 109  36]
    
  • 其他信息
    # 每个元素的数据类型 uint8 即0-255
    print(img.dtype)  
    # 图像大小 height * width * channels
    print(img.size)
    
    uint8
    1259520
    

2.3 修改图片像素点的颜色信息

  • 修改像素点
    # 方式1 修改为黑色
    img[90, 160] = [0, 0, 0]
    print(img[90, 160])
    
    # 方式2 性能更好,但需要一个一个设置
    # 红色
    img.itemset((90, 170, 0), 0)
    img.itemset((90, 170, 1), 0)
    img.itemset((90, 170, 2), 255)
    print(img[90, 170])
    
    [0 0 0]
    [  0   0 255]
    
  • 画一条线
    # 画一条线
    for i in range(0, 300):
        img[100, i] = [0, 0, 255]
        
    cv2.imshow("picture", img)
    
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()
    

图片2

2.3 拆分与合并颜色三通道

  • 拆分与合并颜色三通道
    # 拆分通道
    b, g, r = cv2.split(img)
    # 合并三通道
    img = cv2.merge((b, g, r))
    
    # 只有单通道的值,此时是灰度图
    print(b) 
    
    [[163 163 162 ... 173 173 173]
     [164 164 163 ... 175 175 175]
     [165 165 164 ... 174 175 175]
     ...
     [ 42  39  39 ...  51  52  52]
     [ 49  41  38 ...  66  67  66]
     [ 41  38  38 ...  96  95  95]]
    
  • 对应通道的灰度图
    # 单独展示蓝色通道的值(灰度图)
    cv2.imshow('blue', b)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()
        
    # 获取某个区域红色通道对应的灰度图
    red_flower_img = img[180:310, 50:180][:, :, 2]
    cv2.imshow("red_flower", red_flower_img)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()
    

图片3
图片4

  • 修改某块区域为只显示蓝色通道
    for i in range(0, 400):
        for j in range(0, 400):
            img.itemset((i, j, 1), 0)
            img.itemset((i, j, 2), 0)
            
    cv2.imshow('blue', img)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()
    

图片5

3. 绘图

3.1 线段、三角形、矩形、圆形、扇形、任意多边形

img = np.zeros((500, 500, 3), np.uint8)

# 画线段
# img, 起点, 终点, 颜色
cv2.line(img, (50, 50), (200, 200), (255, 0, 0))
# img, 起点, 终点, 颜色, 宽度
cv2.line(img, (100, 100), (300, 100), (0, 255, 0), 10)
# img, 起点, 终点, 颜色, 宽度, 线条类型
cv2.line(img, (100, 150), (300, 150), (0, 255, 0), 10, cv2.LINE_AA)

# 画三角形
points = [(400, 300), (300, 360), (240, 240)]
cv2.line(img, points[0], points[1], (0, 0, 255))
cv2.line(img, points[1], points[2], (0, 0, 255))
cv2.line(img, points[2], points[0], (0, 0, 255))

# 画矩形
# img, 左上角, 右下角, 颜色, 是否填充
cv2.rectangle(img, (360, 150), (460, 200), (100, 0, 0), -1)

# 画圆
# img, 圆心, 半径, 颜色, 粗细
cv2.circle(img, (200, 360), (30), (0, 100, 0), 3)

# 扇形
# img, 中心, 轴长, 偏转角度, 起始, 结束, 颜色, 填充
cv2.ellipse(img, (200, 400), (50, 80), 0, 0, 90, (0, 0, 100), -1)

# 任意多边形
points = np.array([[270, 180], [220, 190], [330, 150], [310, 240]])
print(points.shape)
points = points.reshape((-1, 1, 2))
print(points.shape)
print(points)
cv2.polylines(img, [points], True, (255, 255, 255))

cv2.imshow("img", img)
if cv2.waitKey() == ord("q"):
    cv2.destroyAllWindows() 

图片12

3.2 文字、图片

img = cv2.imread("./test03.jpg", 1)
height, width, channels = img.shape

# 画文字
cv2.rectangle(img, (100, 110), (300, 150), (255, 255, 255), 2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, "Sun Flower", (110, 140), font, 1, (0, 0, 0), 1)

# 复制、画图
img2 = cv2.imread("./test03.jpg", 1)[150:400, 50:300]
height2, width2, channels2 = img2.shape

for i in range(0, height2):
    for j in range(0, width2):
        img[i, 400 + j] = img2[i, j]

cv2.imshow("img", img)
if cv2.waitKey() == ord("q"):
    cv2.destroyAllWindows() 

图片13

4. 图像的几何变换

4.1 图像截取

flower_img = img[180:310, 50:180]

cv2.imshow("flower", flower_img)
if cv2.waitKey() == ord("q"):
    cv2.destroyAllWindows()

图片6

4.2 图像缩放

  • 方式1
    # 获取到高度、宽度的一半的值
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    dst_height = int(height / 2)
    dst_width = int(width / 2)
    # 进行缩放
    dst_img = cv2.resize(img, (dst_width, dst_height)) # 注意先传width,再传height
    
    cv2.imshow("dst_img", dst_img)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()
    
  • 方式2
    # 手动实现缩放
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    dst_height = int(height / 2)
    dst_width = int(width / 2)
    # 缩放
    dst_img = np.zeros((dst_height, dst_width, 3), np.uint8)
    print(dst_img.shape)
    for i in range(0, dst_height):
        for j in range(0, dst_width):
            new_i = int(i * (height / dst_height))
            new_j = int(j * (width / dst_width))
            dst_img[i, j] = img[new_i, new_j]
    
    cv2.imshow("dst_img", dst_img)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()    
    
  • 方式3
    # Affine
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    
    # 缩放
    mat_scale = np.float32([[0.5, 0, 0], [0, 0.5, 0]])
    dst_img = cv2.warpAffine(img, mat_scale, (int(width / 2), int(height / 2)))
    
    cv2.imshow("dst_img", dst_img)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()   
    

图片7

4.3 图像移动

  • 方式1
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    
    # Affine,水平右移100,垂直下移200
    matShift = np.float32([[1, 0, 100], [0, 1, 200]])
    dst_img = cv2.warpAffine(img, matShift, (width, height))
    
    cv2.imshow("dst_img", dst_img)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()  
    

图片8

  • 方式2
    # 手动实现移动,右移100
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    dst_img = np.zeros(img.shape, np.uint8)
    for i in range(0, height):
        for j in range(0, width - 100):
            dst_img[i, j + 100] = img[i, j]
            
    cv2.imshow("dst_img", dst_img)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows()
    

4.4 图像镜像

img = cv2.imread("./test03.jpg", 1)
height, width, channels = img.shape

dst_img = np.zeros((height * 2, width, channels), np.uint8)

for i in range(0, height):
    for j in range(0, width):
        dst_img[i, j] = img[i, j] # 原图
        dst_img[height * 2 - i - 1, j] = img[i, j] # 反转镜像
        
cv2.imshow("dst_img", dst_img)
if cv2.waitKey() == ord("q"):
    cv2.destroyAllWindows() 

图片9

4.5 图像旋转

  • 平面旋转
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    
    # 旋转矩阵
    # 参数:中心点,旋转角度,缩放系数
    mat_rotate = cv2.getRotationMatrix2D((width / 2, height / 2), 45, 0.5)
    dst_img = cv2.warpAffine(img, mat_rotate, (width, height))
    
    cv2.imshow("dst_img", dst_img)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows() 
    

图片10

  • 空间旋转
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    
    # 左上角、左下角、右上角
    mat_src = np.float32([[0, 0], [0, height - 1], [width - 1, 0]])
    mat_dst = np.float32([[60, 60], [150, height - 150], [width - 250, 220]])
    mat_affine = cv2.getAffineTransform(mat_src, mat_dst)
    dst_img = cv2.warpAffine(img, mat_affine, (width, height))
    
    cv2.imshow("dst_img", dst_img)
    if cv2.waitKey() == ord("q"):
        cv2.destroyAllWindows() 
    
    图片11
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章