Z字形掃描zigzag二維矩陣python實現


在對圖像進行 dct 變換后,原圖像的高頻分量集中在左上,低頻部分集中在右下。在此情況下,將圖像將成一維,用簡單的逐行逐列效果不會很好,故需用Z字形掃描的方式進行展開。下圖給出了奇數行列和偶數行列的情況示意圖(僅供參考,行列數可以不相等,但一般圖像處理里,分塊都是8*8的小塊)。

下面給出了代碼,注釋寫得比較清楚。請結合圖像理解。幾個關鍵點:
1、在不考慮邊界時,根據行和列數和是奇數還是偶數來區分前面的方向是右上還是左下;

2、在考慮邊界時,需要轉彎,轉彎時需要判斷是哪個邊界、或者頂點位置;

在將情況討論后,發現代碼其實是可以合並的。這里為了方便理解,不進行合並

import cv2 as cv
 
''' define  : zigzag 掃描
    input   : 二維矩陣, shape: (row, col)
    output  : 列表, shape: (row*col,)
    variable: k 列表序號, i 行序號, j 列序號, row 行數, col 列數
    method  : 假設 (0, 0) 在左上角, (row-1, col-1) 在右下角的情況. 考慮非邊界的情況, 只有右上/左下兩個方向.
              以從 (0, 0) 先向右(下)為例, 則會有 i+j 為偶數時右上(左下)前進, 為奇數時左下(右上)的情況前進.
              如果遇到邊界, 某個方向收到限制, 移動允許的直線方向'''
def zigzag(data):
    row = data.shape[0]
    col = data.shape[1]
    num = row * col
    list = np.zeros(num,)
    k = 0
    i = 0
    j = 0
 
    while i < row and j < col and k < num:
        list[k] = data.item(i, j)
        k = k + 1
        # i + j 為偶數, 右上移動. 下面情況是可以合並的, 但是為了方便理解, 分開寫
        if (i + j) % 2 == 0:
            # 右邊界超出, 則向下
            if (i-1) in range(row) and (j+1) not in range(col):
                i = i + 1
            # 上邊界超出, 則向右
            elif (i-1) not in range(row) and (j+1) in range(col):
                j = j + 1
            # 上右邊界都超出, 即處於右上頂點的位置, 則向下
            elif (i-1) not in range(row) and (j+1) not in range(col):
                i = i + 1
            else:
                i = i - 1
                j = j + 1
        # i + j 為奇數, 左下移動
        elif (i + j) % 2 == 1:
            # 左邊界超出, 則向下
            if (i+1) in range(row) and (j-1) not in range(col):
                i = i + 1
            # 下邊界超出, 則向右
            elif (i+1) not in range(row) and (j-1) in range(col):
                j = j + 1
            # 左下邊界都超出, 即處於左下頂點的位置, 則向右
            elif (i+1) not in range(row) and (j-1) not in range(col):
                j = j + 1
            else:
                i = i + 1
                j = j - 1
    
    return list
 
 
if __name__ == "__main__":
    data = np.matrix([[1,2,6],[3,5,7],[4,8,9]])
    print(data)
    result = zigzag(data)
    print(result)
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM