2011-04-18 30 views
7

Đây có thể là câu hỏi cho một diễn đàn khác, nếu có, vui lòng cho tôi biết. Tôi nhận thấy rằng chỉ có 14 người theo thẻ wavelet.Làm thế nào để mở rộng pyWavelets để làm việc với dữ liệu N-chiều?

Tôi đã ở đây một cách thanh lịch để mở rộng phân tách wavelet trong pywt (gói pyWavelets) thành nhiều thứ nguyên. Điều này sẽ chạy ra khỏi hộp nếu pywt được cài đặt. Kiểm tra 1 cho thấy sự phân hủy và phân hủy của một mảng 3D. Tất cả, người ta phải làm là tăng số lượng các kích thước và mã sẽ làm việc trong phân hủy/recomposing với 4, 6 hoặc thậm chí 18 kích thước của dữ liệu.

Tôi đã thay thế các hàm pywt.wavedec và pywt.waverec tại đây. Ngoài ra, trong fn_dec, tôi chỉ ra cách hàm wavedec mới hoạt động giống như hàm cũ.

Mặc dù vậy, có một điểm bắt buộc: Nó thể hiện các hệ số wavelet là một mảng có cùng hình dạng với dữ liệu. Kết quả là, với kiến ​​thức hạn chế về các wavelet của tôi, tôi chỉ có thể sử dụng nó cho các sóng Haar. Những người khác như DB4 cho ví dụ hệ số chảy máu trên các cạnh của giới hạn nghiêm ngặt này (không phải là một vấn đề với các đại diện hiện tại của hệ số như danh sách các mảng [CA, CD1 ... CDN ].Một bắt là tôi đã chỉ làm việc này với 2^N cạnh cuboids của dữ liệu

Về mặt lý thuyết, tôi nghĩ rằng nó có thể đảm bảo rằng "chảy máu" không xảy ra. Một thuật toán cho loại phân tách wavelet và phân hủy được thảo luận trong "số lượng recipies trong C" - bởi William Press, Saul A teukolsky, William T. Vetterling và Brian P. Flannery (Second Edition) Mặc dù thuật toán này giả định sự phản chiếu ở các cạnh chứ không phải các dạng mở rộng cạnh khác (như zpd), phương pháp này là đủ chung để làm việc cho các hình thức gia hạn khác.

Bất kỳ đề xuất nào ion trên làm thế nào để mở rộng công việc này để wavelet khác?

LƯU Ý: Truy vấn này cũng được đăng tải trên http://groups.google.com/group/pywavelets

Cảm ơn, Ajo

import pywt 
import sys 
import numpy as np 

def waveFn(wavelet): 
    if not isinstance(wavelet, pywt.Wavelet): 
     return pywt.Wavelet(wavelet) 
    else: 
     return wavelet 

# given a single dimensional array ... returns the coefficients. 
def wavedec(data, wavelet, mode='sym'): 
    wavelet = waveFn(wavelet) 

    dLen = len(data) 
    coeffs = np.zeros_like(data) 
    level = pywt.dwt_max_level(dLen, wavelet.dec_len) 

    a = data  
    end_idx = dLen 
    for idx in xrange(level): 
     a, d = pywt.dwt(a, wavelet, mode) 
     begin_idx = end_idx/2 
     coeffs[begin_idx:end_idx] = d 
     end_idx = begin_idx 

    coeffs[:end_idx] = a 
    return coeffs 

def waverec(data, wavelet, mode='sym'): 
    wavelet = waveFn(wavelet) 

    dLen = len(data) 
    level = pywt.dwt_max_level(dLen, wavelet.dec_len) 

    end_idx = 1 
    a = data[:end_idx] # approximation ... also the original data 
    d = data[end_idx:end_idx*2]  
    for idx in xrange(level): 
     a = pywt.idwt(a, d, wavelet, mode) 
     end_idx *= 2 
     d = data[end_idx:end_idx*2] 
    return a 

def fn_dec(arr): 
    return np.array(map(lambda row: reduce(lambda x,y : np.hstack((x,y)), pywt.wavedec(row, 'haar', 'zpd')), arr)) 
    # return np.array(map(lambda row: row*2, arr)) 

if __name__ == '__main__': 
    test = 1 
    np.random.seed(10) 
    wavelet = waveFn('haar') 
    if test==0: 
     # SIngle dimensional test. 
     a = np.random.randn(1,8) 
     print "original values A" 
     print a 
     print "decomposition of A by method in pywt" 
     print fn_dec(a) 
     print " decomposition of A by my method" 
     coeffs = wavedec(a[0], 'haar', 'zpd') 
     print coeffs 
     print "recomposition of A by my method" 
     print waverec(coeffs, 'haar', 'zpd') 
     sys.exit() 
    if test==1: 
     a = np.random.randn(4,4,4) 
     # 2 D test 
     print "original value of A" 
     print a 

     # decompose the signal into wavelet coefficients. 
     dimensions = a.shape 
     for dim in dimensions: 
      a = np.rollaxis(a, 0, a.ndim) 
      ndim = a.shape 
      #a = fn_dec(a.reshape(-1, dim)) 
      a = np.array(map(lambda row: wavedec(row, wavelet), a.reshape(-1, dim))) 
      a = a.reshape(ndim) 
     print " decomposition of signal into coefficients" 
     print a 

     # re-composition of the coefficients into original signal 
     for dim in dimensions: 
      a = np.rollaxis(a, 0, a.ndim) 
      ndim = a.shape 
      a = np.array(map(lambda row: waverec(row, wavelet), a.reshape(-1, dim))) 
      a = a.reshape(ndim) 
     print "recomposition of coefficients to signal" 
     print a 

Trả lời

5

Trước hết, tôi muốn chỉ cho bạn các chức năng đó đã thực hiện Single-level Multi-dimensional Transform (Source). Nó trả về một từ điển các mảng hệ số n chiều. Các hệ số được giải quyết bằng các khóa mô tả loại biến đổi (xấp xỉ/chi tiết) được áp dụng cho mỗi kích thước.

Ví dụ cho một trường hợp 2D kết quả là một cuốn từ điển với xấp xỉ và chi tiết hệ số mảng:

>>> pywt.dwtn([[1,2,3,4],[3,4,5,6],[5,6,7,8],[7,8,9,10]], 'db1') 
{'aa': [[5.0, 9.0], [13.0, 17.0]], 
'ad': [[-1.0, -1.0], [-1.0, -1.0]], 
'da': [[-2.0, -2.0], [-2.0, -2.0]], 
'dd': [[0.0, 0.0], [0.0, -0.0]]} 

đâu aa là mảng hệ số với xấp xỉ biến đổi áp dụng cho cả hai kích thước (LL) và da là các hệ số mảng với biến đổi chi tiết được áp dụng cho thứ nguyên đầu tiên và phép biến đổi xấp xỉ được áp dụng cho biến thứ hai (HL) (so sánh với dwt2 output).

Dựa trên điều đó, việc mở rộng nó đến trường hợp đa cấp là khá dễ dàng.

Đây là phần của tôi trên phần phân hủy: https://gist.github.com/934166.

tôi cũng muốn giải quyết một vấn đề bạn đề cập đến trong câu hỏi của bạn:

Có một bắt mặc dù: Nó đại diện cho các hệ số wavelet như một loạt các hình dạng tương tự như các dữ liệu.

Cách tiếp cận biểu diễn kết quả dưới dạng mảng có cùng hình dạng/kích thước như dữ liệu đầu vào theo ý kiến ​​của tôi có hại. Nó làm cho toàn bộ điều phức tạp không cần thiết để hiểu và làm việc với vì dù sao bạn phải giả định hoặc duy trì cấu trúc dữ liệu thứ cấp với các chỉ mục để có thể truy cập hệ số trong mảng đầu ra và thực hiện phép biến đổi nghịch đảo (xem tài liệu của Matlab cho wavedec/waverec)).

Ngoài ra, mặc dù nó hoạt động tốt trên giấy, nó không phải lúc nào cũng phù hợp với các ứng dụng thực tế vì những vấn đề bạn đã đề cập: phần lớn thời gian dữ liệu đầu vào không phải là 2^n và kết quả thu được bộ lọc wavelet lớn hơn là "không gian lưu trữ", do đó có thể dẫn đến mất dữ liệu và tái tạo không hoàn hảo.

Để tránh những vấn đề này, tôi khuyên bạn nên sử dụng nhiều cấu trúc dữ liệu tự nhiên hơn để đại diện cho phân cấp dữ liệu kết quả, như danh sách, từ điển và bộ dữ liệu của Python (nếu có).

+1

Ví dụ về github của bạn ... sự phân hủy là phần khó khăn hơn. Ngoài ra, tôi thấy nó dễ dàng hơn nhiều để thao tác một mảng các hệ số ND (... giống như hệ số phân loại magnitudes và trừ một hàm hạng từ các hệ số magnitudes.) Cuối cùng, tổng bình phương của các hệ số là giống như của mẫu dữ liệu nếu sử dụng khối ND của hệ số. – fodon

Các vấn đề liên quan