Python實現im2col和col2im函數

今天來講說im2col和col2im函數,這是MATLAB中兩個內置函數,常常用於數字圖像處理中。其中im2col函數在《MATLAB中的im2col函數》一文中已經進行了簡單的介紹。python

通常來講:web

  1. 如是將圖像分割成塊的時候用的im2col參數爲'distinct',那麼用col2im函數時參數也是'distinct',便可將轉換後的數組復原。
  2. 若是將圖像分割成塊的時候用的im2col參數爲'sliding',我目前還不知道MATLAB中使用內置函數是如何復原的。

今天,來看看Python中是如何實現這兩個函數的(sliding類型)。數組

  1. 對於im2col的實現,咱們沿着原始矩陣逐行計算,將獲得的新的子矩陣展開成列,放置在列塊矩陣中。
  2. 對於col2im的實現,咱們沿着列塊矩陣逐行計算,將獲得的行展成子矩陣,而後將子矩陣放置在最終結果對應的位置(每次當前值進行相加),同時記錄每一個位置的值放置的次數。最後,將當前位置的值除以放置的次數,便可獲得結果(原始矩陣)。
def im2col(mtx, block_size):
    mtx_shape = mtx.shape
    sx = mtx_shape[0] - block_size[0] + 1
    sy = mtx_shape[1] - block_size[1] + 1
    # 若是設A爲m×n的,對於[p q]的塊劃分,最後矩陣的行數爲p×q,列數爲(m−p+1)×(n−q+1)。
    result = np.empty((block_size[0] * block_size[1], sx * sy))
    # 沿着行移動,因此先保持列(i)不動,沿着行(j)走
    for i in range(sy):
        for j in range(sx):
            result[:, i * sx + j] = mtx[j:j + block_size[0], i:i + block_size[1]].ravel(order='F')
    return result


def col2im(mtx, image_size, block_size):
    p, q = block_size
    sx = image_size[0] - p + 1
    sy = image_size[1] - q + 1
    result = np.zeros(image_size)
    weight = np.zeros(image_size)  # weight記錄每一個單元格的數字重複加了多少遍
    col = 0
    # 沿着行移動,因此先保持列(i)不動,沿着行(j)走
    for i in range(sy):
        for j in range(sx):
            result[j:j + p, i:i + q] += mtx[:, col].reshape(block_size, order='F')
            weight[j:j + p, i:i + q] += np.ones(block_size)
            col += 1
    return result / weight

測試代碼:dom

if __name__ == '__main__':
    mtx = np.around(np.random.rand(5, 5) * 100)
    print('原始矩陣:')
    print(mtx)

    a1 = im2col(mtx, (2, 3))
    print('im2col(分塊大小2x3):')
    print(a1)
    b1 = col2im(a1, (5, 5), (2, 3))
    print('col2im復原:')
    print(b1)

    a2 = im2col(mtx, (3, 3))
    print('im2col(分塊大小3x3):')
    print(a2)
    b2 = col2im(a2, (5, 5), (3, 3))
    print('col2im復原:')
    print(b2)

運行結果:函數

原始矩陣:
[[ 48.  38.  38.  59.  38.]
 [ 38.  11.  25.  52.  44.]
 [ 60.  69.  49.  93.  66.]
 [ 88.   8.  47.  14.  47.]
 [ 96.  37.  56.  86.  54.]]
im2col(分塊大小2x3):
[[ 48.  38.  60.  88.  38.  11.  69.   8.  38.  25.  49.  47.]
 [ 38.  60.  88.  96.  11.  69.   8.  37.  25.  49.  47.  56.]
 [ 38.  11.  69.   8.  38.  25.  49.  47.  59.  52.  93.  14.]
 [ 11.  69.   8.  37.  25.  49.  47.  56.  52.  93.  14.  86.]
 [ 38.  25.  49.  47.  59.  52.  93.  14.  38.  44.  66.  47.]
 [ 25.  49.  47.  56.  52.  93.  14.  86.  44.  66.  47.  54.]]
col2im復原:
[[ 48.  38.  38.  59.  38.]
 [ 38.  11.  25.  52.  44.]
 [ 60.  69.  49.  93.  66.]
 [ 88.   8.  47.  14.  47.]
 [ 96.  37.  56.  86.  54.]]
im2col(分塊大小3x3):
[[ 48.  38.  60.  38.  11.  69.  38.  25.  49.]
 [ 38.  60.  88.  11.  69.   8.  25.  49.  47.]
 [ 60.  88.  96.  69.   8.  37.  49.  47.  56.]
 [ 38.  11.  69.  38.  25.  49.  59.  52.  93.]
 [ 11.  69.   8.  25.  49.  47.  52.  93.  14.]
 [ 69.   8.  37.  49.  47.  56.  93.  14.  86.]
 [ 38.  25.  49.  59.  52.  93.  38.  44.  66.]
 [ 25.  49.  47.  52.  93.  14.  44.  66.  47.]
 [ 49.  47.  56.  93.  14.  86.  66.  47.  54.]]
col2im復原:
[[ 48.  38.  38.  59.  38.]
 [ 38.  11.  25.  52.  44.]
 [ 60.  69.  49.  93.  66.]
 [ 88.   8.  47.  14.  47.]
 [ 96.  37.  56.  86.  54.]]
相關文章
相關標籤/搜索