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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章