2012-04-04 46 views
5

Tôi đã tạo một mã python để làm mịn một tín hiệu đã cho bằng cách sử dụng phép biến đổi Weierstrass, về cơ bản là sự hòa tan của một gaussian chuẩn hóa với một tín hiệu.Làm thế nào để loại bỏ các hiệu ứng ranh giới phát sinh do không đệm trong fip scipy/numpy?

Mã này là như sau:


#Importing relevant libraries 
from __future__ import division 
from scipy.signal import fftconvolve 
import numpy as np 

def smooth_func(sig, x, t= 0.002): 
    N = len(x) 
    x1 = x[-1] 
    x0 = x[0]  


# defining a new array y which is symmetric around zero, to make the gaussian symmetric. 
    y = np.linspace(-(x1-x0)/2, (x1-x0)/2, N) 
    #gaussian centered around zero. 
    gaus = np.exp(-y**(2)/t)  

#using fftconvolve to speed up the convolution; gaus.sum() is the normalization constant. 
    return fftconvolve(sig, gaus/gaus.sum(), mode='same') 

Nếu tôi chạy mã này để nói một chức năng bước, nó làm trơn nhẵn góc, nhưng ở ranh giới nó diễn giải góc khác và làm trơn nhẵn mà quá, kết quả là cho hành vi không cần thiết ở ranh giới. Tôi giải thích điều này với một con số được hiển thị trong liên kết dưới đây.
Boundary effects

Vấn đề này không phát sinh nếu chúng tôi tích hợp trực tiếp để tìm sự liên kết. Do đó vấn đề không có trong biến đổi Weierstrass, và do đó vấn đề nằm trong hàm fftconvolve của scipy.

Để hiểu lý do tại sao vấn đề này phát sinh, trước tiên chúng ta cần phải hiểu được hoạt động của fftconvolve trong scipy.
Hàm fftconvolve về cơ bản sử dụng định lý convolution để tăng tốc độ tính toán.
Nói ngắn gọn:
convolution (int1, int2) = ifft (fft (int1) * fft (int2))
Nếu chúng tôi trực tiếp áp dụng định lý này, chúng tôi không nhận được kết quả mong muốn. Để có được kết quả mong muốn, chúng ta cần lấy fft trên một mảng gấp đôi kích thước của max (int1, int2). Nhưng điều này dẫn đến các hiệu ứng ranh giới không mong muốn. Điều này là bởi vì trong mã fft, nếu kích thước (int) lớn hơn kích thước (trên đó để có fft) nó không đệm đầu vào và sau đó mất fft. Điều này đệm không chính xác là những gì chịu trách nhiệm cho các hiệu ứng ranh giới không mong muốn.

Bạn có thể đề xuất cách xóa hiệu ứng biên này không?

Tôi đã cố gắng xóa nó bằng một mẹo đơn giản. Sau khi làm mịn hàm tôi đang tính giá trị của tín hiệu được làm phẳng với tín hiệu gốc gần ranh giới và nếu chúng không khớp, tôi thay thế giá trị của func được làm phẳng bằng tín hiệu đầu vào tại điểm đó.
Nó được như sau:


i = 0 
eps=1e-3 
while abs(smooth[i]-sig[i])> eps: #compairing the signals on the left boundary 
    smooth[i] = sig[i] 
    i = i + 1 
j = -1 

while abs(smooth[j]-sig[j])> eps: # compairing on the right boundary. 
    smooth[j] = sig[j] 
    j = j - 1 

Có một vấn đề với phương pháp này, vì sử dụng một epsilon có bước nhảy nhỏ trong chức năng làm phẳng, như hình dưới đây:
jumps in the smooth func

Có thể có bất kỳ thay đổi nào được thực hiện trong phương pháp trên để giải quyết vấn đề biên này không?

+0

Ngắt của http://math.stackexchange.com/q/127875/2206 – endolith

Trả lời

3

Một hạt nhân bộ lọc đối xứng tạo ra ở hai đầu phụ thuộc vào những gì bạn cho rằng dữ liệu nằm ngoài các đầu.

Nếu bạn không thích giao diện của kết quả hiện tại, giả sử số không vượt quá cả hai đầu, hãy thử mở rộng dữ liệu bằng một giả định khác, nói phản xạ dữ liệu hoặc tiếp tục hồi quy đa thức. Mở rộng dữ liệu trên cả hai đầu bằng ít nhất một nửa độ dài của hạt nhân bộ lọc (ngoại trừ nếu phần mở rộng của bạn là số không, mà đến miễn phí với số không đệm hiện có cần thiết cho chập tròn không tròn). Sau đó, xóa các phần cuối của phần bổ sung sau khi lọc và xem bạn có thích giao diện giả định của mình hay không. Nếu không, hãy thử một giả định khác. Hoặc tốt hơn, sử dụng dữ liệu thực tế ngoài các đầu nếu bạn có.

+0

Cảm ơn, câu trả lời của bạn mở ra một loạt các khả năng. – Omkar

6

cách tiếp cận tốt nhất có lẽ là sử dụng mode = 'valid':

The output consists only of those elements that do not rely on the zero-padding.

Trừ khi bạn có thể bọc tín hiệu của bạn, hoặc tín hiệu được xử lý là một đoạn trích từ một tín hiệu lớn hơn (trong trường hợp này: quá trình tín hiệu đầy đủ sau đó vùng trồng cây quan tâm) bạn sẽ luôn có hiệu ứng cạnh khi thực hiện chập chững.Bạn phải chọn cách bạn muốn đối phó với chúng. Sử dụng mode = valid chỉ cần cắt giảm chúng, đó là một giải pháp khá tốt. Nếu bạn biết rằng tín hiệu luôn 'giống như bước', bạn có thể mở rộng mặt trước và cuối của tín hiệu được xử lý nếu thích hợp.

+0

Cảm ơn giải pháp của bạn đã hoạt động. – Omkar

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