<button id="ssm6u"><optgroup id="ssm6u"></optgroup></button>
  • 跳轉至

    初始化畫布

    概要

    阿凱在這篇文章中給大家講解了如何分別用numpy的方法, 與numpy與cv2結合的方法創建空白畫布, 創建白色畫布, 與創建彩色畫布. 本節實際上同時也幫大家回顧了numpy 的一些常用的功能.

    本節阿凱還介紹了cv2進行通道分割cv2.split與通道合并cv2.merge的兩個函數.

    keywords OpenCV 初始化畫布 通道分離 通道合并

    1. 創建一個空白畫布

    創建空白畫布的函數,成品如下:

    def InitCanvas(width, height, color=(255, 255, 255)):
        canvas = np.ones((height, width, 3), dtype="uint8")
        canvas[:] = color
        return canvas
    

    調用的時候傳入圖像的寬度與高度,還有畫布的顏色即可. 例如創建一個800*600 顏色為純黑色的畫布:

    canvas = InitCanvas(800, 600, color=(255,255,255))
    

    Screenshot_20180121_224305.png

    完整源碼

    src/init_canvas_v1.py

    '''
    初始化畫布
    '''
    import cv2
    import numpy as np
    
    def init_canvas(width, height, color=(255, 255, 255)):
        canvas = np.ones((height, width, 3), dtype="uint8")
        canvas[:] = color
        return canvas
    
    canvas = init_canvas(200, 200, color=(125, 40, 255))
    
    cv2.imshow('canvas', canvas)
    cv2.waitKey(0)
    
    cv2.destroyAllWindows()
    

    如果你不想深究numpy的ndarray數據結構的索引與賦值的話,下面的內容不需要閱讀.


    學霸的神奇的分割線


    我們在使用畫圖工具的時候, 第一件事情就是創建一個新的空白畫布, 我們可以指定畫布的大小, 跟顏色.

    那我們如何使用opencv來創建一個空白的畫布(值相同的圖片) ?

    還記得我們在講解image的數據結構的時候, 提到過python-opencv上的圖片,本質上就是numpy里面的ndarray的對象嗎? 創建一個畫布本質上就是創建一個同等規格的ndarray

    創建一個新的特定尺寸的ndarray我們可以使用np.zeors 函數, 我們將圖像的高度(height), 圖像的寬度(width), 以及圖像的通道數channeltuple 類型傳入np.zeros . 再次聲明是tuple類型

    另外由于不是所有的numpy類型的數值, 都可以放到opencv中進行圖像處理.

    數值取值范圍在0-255, 我們需要指定數據類型為uint8 unsigned integer 8-bit

    np.zeros((height, width, channels), dtype="uint8")
    

    所有的像素點的值, 都是0, 那么其實也就是純純的黑色. 我們新建了一個黑色背景的畫布.

    Screenshot_20180121_224305.png

    舉個例子, 我們想創建一個800 x 600 x 3 的圖片, 我們就得這么寫:

    一個BGR格式的圖像,

    # 初始化一個空畫布 300×300 三通道 背景色為黑色 
    canvas_black = np.zeros((600, 800, 3), dtype="uint8")
    

    注意 height寫在前面 圖像數據結構, 記不牢靠的同學, 請復習教程:

    有時候我們也可以偷懶, 如果我們想創建與另外一個圖像尺寸相同的畫布的時候, 我們可以使用np.zeros_like

    canvas_black = np.zeros_like(img)
    

    2. 初始化白色的畫布

    emmm, 老是黑色的背景, 總給人一種很壓抑的感覺.

    那么有沒有一種好的方法, 可以讓我自定義顏色 ?

    首先我想到的是白色, 又因為比較簡單, 三個通道的值都相同.

    ps: 其實灰色的圖片(GRAY2BGR), 三個通道的值都相同.

    那么我們創建一個全都是1的矩陣, 然后,乘上某個數值, 問題是不是就解決了.

    我們需要用到np.ones 函數

    # 初始化一個空畫布 300×300 三通道 背景色為白色 
    canvas_white = np.ones((300, 300, 3), dtype="uint8")
    

    接下來, 需要乘上一個整數, 255 (你可以填入0-255的任意值)

    canvas_white *= 255
    

    還記得阿凱在numpy教程里面,稱這種運算為什么運算么?

    這種運算稱之為 全局乘法 , 忘記的同學, 趕緊復習一下全局函數 ufunc 的概念.

    Numpy基礎

    3. 初始化彩色的畫布

    3.1 利用cv2的內置方法merge與split

    初始化畫布有兩種方法. 一種方法, 是我們初始化BGR的圖片canvas_white 之后將原來的圖片進行通道分離. 分別乘上BGR三個通道的整數值, 然后將三個通道合并在一起. 就得到我們想要的彩圖純色背景.

    那通道的分離我們需要用到的函數是cv2.split(img).

    # 將原來的三個通道抽離出來, 分別乘上各個通道的值
    (channel_b, channel_g, channel_r) = cv2.split(canvas)
    

    channel_b 藍色通道, channel_g 綠色通道, channel_r 紅色通道, 都是二維的ndarray對象.

    我們指定一種顏色, 例如 color = (100, 20, 50))

    注意, 我們這里的顏色指的BGR格式

    也就是

    B -> 100
    G -> 20
    R -> 50
    

    接下來我們分別將其乘上對應的值.

    # 顏色的值與個通道的全1矩陣相乘
    channel_b *= color[0]
    channel_g *= color[1]
    channel_r *= color[2]
    

    接下來我們將三個通道重新合并, 需要用到的函數是cv2.merge

    cv2.merge([channel_b, channel_g, channel_r])
    

    注意,三個通道的矩陣, 以list [] 的方式, 傳入merge函數.

    綜合起來, 就是我們的第一個初始化彩色背景的函數:

    src/init_canvas_v2.py

    '''
    初始化畫布
    '''
    import cv2
    import numpy as np
    
    # 初始化一個彩色的畫布 - cv2版本
    def init_canvas(width, height, color=(255, 255, 255)):
        canvas = np.ones((height, width, 3), dtype="uint8")
    
        # 將原來的三個通道抽離出來, 分別乘上各個通道的值
        (channel_b, channel_g, channel_r) = cv2.split(canvas)
        # 顏色的值與個通道的全1矩陣相乘
        channel_b *= color[0]
        channel_g *= color[1]
        channel_r *= color[2]
    
        # cv.merge 合并三個通道的值
        return cv2.merge([channel_b, channel_g, channel_r])
    
    canvas = init_canvas(200, 200, color=(125, 40, 255))
    
    cv2.imshow('canvas', canvas)
    cv2.waitKey(0)
    
    cv2.destroyAllWindows()
    

    此函數使用 cv2.split 非常耗時 所以只有在需要的時候才能做到。 否則用Numpy索引。

    3.2 利用numpy內置的索引

    使用numpy原生的方法, 性能會比opencv中的要好. 我們直接使用numpy的ndarray的索引的方法.

    例如 canvas[:,:,0] 選中的是, 所有行, 所有列, 像素元素的第一個值, 也就是, 所有B通道的值.

    然后對其進行賦值:

    canvas[:,:,0] = color[0]
    

    對numpy索引方式, 忘掉的朋友, 回顧一下教程吧.

    ndarray切片

    Numpy基礎

    在教程中搜索 切片 slicing , 兩者其實是一個東西.

    完整版本的函數如下:

    src/init_canvas_v3.py

    '''
    初始化畫布
    '''
    import cv2
    import numpy as np
    
    def init_canvas(width, height, color=(255, 255, 255)):
        canvas = np.ones((height, width, 3), dtype="uint8")
        # Blue 
        canvas[:,:,0] = color[0]
        # Green
        canvas[:,:,1] = color[1]
        # Red
        canvas[:,:,2] = color[2]
    
        return canvas
    
    canvas = init_canvas(200, 200, color=(125, 40, 255))
    
    cv2.imshow('canvas', canvas)
    cv2.waitKey(0)
    
    cv2.destroyAllWindows()
    

    實際上我們還有更快的方法, 可以實現這個功能, 這就需要你熟練掌握Numpy的使用技巧.

    我們可以直接賦值color

    canvas[:] = color
    

    完整的函數如下, 這是我們的第三個版本.

    src/init_canvas_v4.py

    '''
    初始化畫布
    '''
    import cv2
    import numpy as np
    
    def init_canvas(width, height, color=(255, 255, 255)):
        canvas = np.ones((height, width, 3), dtype="uint8")
        canvas[:] = color
        return canvas
    
    canvas = init_canvas(200, 200, color=(125, 40, 255))
    
    cv2.imshow('canvas', canvas)
    cv2.waitKey(0)
    
    cv2.destroyAllWindows()
    

    4. 綜合實驗-初始化背景

    在這個綜合實驗里, 阿凱會分別用上述的方法, 創建黑色背景, 白色背景, 彩色背景.

    Screenshot_20171211_194016.png

    '''
    初始化一個空白的畫布
    并指定畫布的顏色
    '''
    
    import cv2
    import numpy as np
    
    # 初始化一個空畫布 300×300 三通道 背景色為黑色 
    canvas_black = np.zeros((300, 300, 3), dtype="uint8")
    cv2.imshow("canvas_black", canvas_black)
    
    # 初始化一個空畫布 300×300 三通道 背景色為白色 
    canvas_white = np.ones((300, 300, 3), dtype="uint8")
    canvas_white *= 255
    
    cv2.imshow("canvas_white", canvas_white)
    
    '''
    初始化一個彩色的畫布 - cv2版本
    此函數使用 cv2.split 非常耗時 所以只有在需要的時候才能做到。 否則用Numpy索引。
    
    '''
    def InitCanvasV1(width, height, color=(255, 255, 255)):
        canvas = np.ones((height, width, 3), dtype="uint8")
    
        # 將原來的三個通道抽離出來, 分別乘上各個通道的值
        (channel_b, channel_g, channel_r) = cv2.split(canvas)
        # 顏色的值與個通道的全1矩陣相乘
        channel_b *= color[0]
        channel_g *= color[1]
        channel_r *= color[2]
    
        # cv.merge 合并三個通道的值
        return cv2.merge([channel_b, channel_g, channel_r])
    
    '''
    初始化一個彩色的畫布 - numpy版本
    使用numpy的索引 賦值
    '''
    def InitCanvasV2(width, height, color=(255, 255, 255)):
        canvas = np.ones((height, width, 3), dtype="uint8")
        # Blue 
        canvas[:,:,0] = color[0]
        # Green
        canvas[:,:,1] = color[1]
        # Red
        canvas[:,:,2] = color[2]
    
        return canvas
    
    '''
    初始化終極版本
    
    熟練掌握 numpy 才可以提高工作效率哦
    '''
    def InitCanvasV3(width, height, color=(255, 255, 255)):
        canvas = np.ones((height, width, 3), dtype="uint8")
        canvas[:] = color
        return canvas
    
    # 初始化一個彩色的畫布
    canvas_color = InitCanvasV2(300, 300, color=(100, 20, 50))
    cv2.imshow("canvas_color", canvas_color)
    
    # 等待e鍵按下 關閉所有窗口
    while cv2.waitKey(0) != ord('e'):
        continue
    cv2.destroyAllWindows()
    

    5. 作業-CH2.1

    阿凱這里教大家如何創建一個三通道的畫布, 那么灰度圖的畫布你會創建么?

    Screenshot_20180122_135055.png

    阿凱給你提供一個代碼模板, 請填入關鍵的函數.

    import numpy as np
    import cv2
    
    # 初始化灰度圖的畫布
    def createGrayscaleCanvas(width, height, color=255):
        '''
        請在這里填入代碼
        '''
        return canvas
    
    # 創建一個顏色為125的灰度圖
    canvas = createGrayscaleCanvas(500, 500, color=125)
    # 展示畫布
    cv2.imshow("canvas", canvas)
    # 中斷
    cv2.waitKey(0)
    # 關閉窗口
    cv2.destroyAllWindows()
    

    韩国精品无码一区二区三区,精品无码一区二区三区AV,欧洲丰满美熟女乱又伦AV,亚洲午夜久久久影院伊人