การเลือกตัวกรองที่ถูกต้องสำหรับข้อมูลมาตรวัดความเร่ง


28

ฉันค่อนข้างใหม่สำหรับ DSP และได้ทำการวิจัยบางอย่างเกี่ยวกับตัวกรองที่เป็นไปได้สำหรับการทำให้ข้อมูล accelerometer ใน python ราบรื่นขึ้น ตัวอย่างประเภทของข้อมูลที่ป่วยจะเห็นได้ในภาพต่อไปนี้:

ข้อมูลมาตรความเร่ง

โดยพื้นฐานแล้วฉันกำลังมองหาคำแนะนำในการทำให้ข้อมูลนี้ราบรื่นในที่สุดเพื่อแปลงเป็นความเร็วและการกระจัด ฉันเข้าใจว่า accelerometers จากโทรศัพท์มือถือมีเสียงดังมาก

ฉันไม่คิดว่าฉันสามารถใช้ตัวกรองคาลมานได้ในขณะนี้เพราะฉันไม่สามารถถืออุปกรณ์เพื่ออ้างอิงเสียงที่เกิดจากข้อมูลได้ (ฉันอ่านว่าจำเป็นที่จะต้องวางอุปกรณ์ให้แบนและหาเสียงจากการอ่านเหล่านั้นหรือไม่)

FFT ให้ผลลัพธ์ที่น่าสนใจ หนึ่งในความพยายามของฉันคือ FFT สัญญาณการเร่งความเร็วจากนั้นแสดงความถี่ต่ำให้มีค่า FFT สัมบูรณ์เป็น 0 จากนั้นฉันใช้เลขคณิตโอเมก้าและผกผัน FFT เพื่อให้ได้พล็อตเรื่องความเร็ว ผลการวิจัยพบว่า

สัญญาณกรอง

นี่เป็นวิธีที่ดีในการไปต่าง ๆ หรือไม่? ฉันกำลังพยายามลบลักษณะโดยรวมของสัญญาณรบกวน แต่ต้องมีการระบุจุดสูงสุดอย่างชัดเจนเช่นประมาณ 80 วินาที

ฉันยังเหนื่อยกับการใช้ low pass filter กับข้อมูล accelerometer ดั้งเดิมซึ่งทำได้ดีมากในการทำให้เรียบ แต่ฉันไม่แน่ใจว่าจะไปจากที่นี่ได้อย่างไร คำแนะนำเกี่ยวกับสถานที่ที่จะไปจากที่นี่จะเป็นประโยชน์จริง ๆ !

แก้ไข: รหัสเล็กน้อย:

for i in range(len(fz)): 
    testing = (abs(Sz[i]))/Nz

    if fz[i] < 0.05:
        Sz[i]=0

Velfreq = []
Velfreqa = array(Velfreq)
Velfreqa = Sz/(2*pi*fz*1j)
Veltimed = ifft(Velfreqa)
real = Veltimed.real

ดังนั้นโดยพื้นฐานแล้ว ive ดำเนินการ FFT กับข้อมูลมาตรวัดความเร่งของฉันโดยให้ Sz กรองความถี่สูงโดยใช้ตัวกรองกำแพงอิฐแบบง่าย (ฉันรู้ว่ามันไม่เหมาะ) จากนั้นให้ใช้ omega เลขคณิตกับ FFT ของข้อมูล ขอบคุณมากสำหรับนักดาต้าสำหรับการเพิ่มภาพของฉันในโพสต์ของฉัน :)


ยินดีต้อนรับสู่ DSP! เส้นโค้งสีแดงในภาพที่สองของคุณเป็นข้อมูล "ดั้งเดิม" (สีเขียว) ที่เป็นแบบ "เรียบ" หรือไม่
Phonon

เส้นโค้งสีแดงคือ (หวังว่า!) เส้นโค้งความเร็วที่สร้างจาก fft ตามด้วยการกรองตามด้วยเลขคณิตโอเมก้า (หารด้วย 2 * pi f j) ตามด้วย inv fft
Michael M

1
บางทีถ้าคุณรวมการแสดงออกทางคณิตศาสตร์ที่แม่นยำยิ่งขึ้นหรือรหัสเทียมสำหรับสิ่งที่คุณทำไว้จะทำให้สิ่งต่าง ๆ ชัดเจนขึ้น
Phonon

เพิ่มบางตอนนี้ครับความรู้สึกทั่วไปของรหัส ..
ไมเคิล M

1
คำถามของฉันคือ: สิ่งที่คุณคาดหวังที่จะเห็นในข้อมูล? คุณจะไม่ทราบว่าคุณมีวิธีการที่ดีหรือไม่เว้นแต่คุณจะรู้อะไรบางอย่างเกี่ยวกับสัญญาณพื้นฐานที่คุณคาดว่าจะเห็นหลังจากการกรอง นอกจากนี้รหัสที่คุณแสดงมีความสับสน แม้ว่าคุณจะไม่แสดงการเริ่มต้นของfzอาร์เรย์ แต่ดูเหมือนว่าคุณกำลังใช้ตัวกรอง highpass แทน
เจสันอาร์

คำตอบ:


13

@JohnRobertson ชี้ให้เห็นในBag of Tricks สำหรับสัญญาณ Denoising ในขณะที่ยังคงรักษาช่วงการเปลี่ยนภาพได้อย่างชัดเจน Total Variaton (TV) denoising เป็นอีกทางเลือกที่ดีถ้าสัญญาณของคุณคงที่ นี่อาจเป็นกรณีของข้อมูลมาตรวัดความเร่งถ้าสัญญาณของคุณแตกต่างกันระหว่างที่ราบสูงที่แตกต่างกัน

ด้านล่างนี้คือรหัส Matlab ที่แสดงสัญญาณทีวีแบบ denoising รหัสจะขึ้นอยู่กับกระดาษAugmented วิธีลากรองจ์สำหรับการเปลี่ยนแปลงรวมวิดีโอฟื้นฟู พารามิเตอร์และจะต้องมีการปรับตามระดับเสียงและลักษณะสัญญาณμρ

ถ้าเป็นสัญญาณรบกวนและคือสัญญาณที่จะประมาณฟังก์ชั่นที่จะย่อขนาดคือโดยที่คือตัวดำเนินการผลต่าง จำกัดyxμxy2+Dx1D

function denoise()

f = [-1*ones(1000,1);3*ones(100,1);1*ones(500,1);-2*ones(800,1);0*ones(900,1)];
plot(f);
axis([1 length(f) -4 4]);
title('Original');
g = f + .25*randn(length(f),1);
figure;
plot(g,'r');
title('Noisy');
axis([1 length(f) -4 4]);
fc = denoisetv(g,.5);
figure;
plot(fc,'g');
title('De-noised');
axis([1 length(f) -4 4]);

function f = denoisetv(g,mu)
I = length(g);
u = zeros(I,1);
y = zeros(I,1);
rho = 10;

eigD = abs(fftn([-1;1],[I 1])).^2;
for k=1:100
    f = real(ifft(fft(mu*g+rho*Dt(u)-Dt(y))./(mu+rho*eigD)));
    v = D(f)+(1/rho)*y;
    u = max(abs(v)-1/rho,0).*sign(v);
    y = y - rho*(u-D(f));
end

function y = D(x)
y = [diff(x);x(1)-x(end)];

function y = Dt(x)
y = [x(end)-x(1);-diff(x)];

ผล:

ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่


ชอบคำตอบนี้มากและจะลองทำดู ขออภัยฉันใช้เวลานานมากในการตอบ!
Michael M

คำตอบที่ยอดเยี่ยม ขอบคุณสำหรับรายละเอียด ฉันกำลังมองหารหัส C รุ่นนี้ ทุกคนที่นี่นำรหัส MATLAB นี้ไปยัง C ที่พวกเขาต้องการแบ่งปันหรือไม่ ขอบคุณ
Rene Limberger

ค่าคงที่ที่ชาญฉลาดหมายถึงอะไร
tilaprimera

6

ปัญหาคือเสียงของคุณมีคลื่นความถี่แบน หากคุณคิดว่าเสียงแบบเกาส์เซียนสีขาว (ซึ่งถือว่าเป็นข้อสันนิษฐานที่ดี) ความหนาแน่นของพลังงานนั้นคงที่ พูดอย่างหยาบ ๆ หมายความว่าเสียงของคุณมีความถี่ทั้งหมด นั่นเป็นสาเหตุที่วิธีการใด ๆ ที่มีความถี่เช่นตัวกรอง DFT หรือ low-pass นั้นไม่ใช่วิธีที่ดี สิ่งที่จะเป็นความถี่ตัดออกของคุณเนื่องจากเสียงของคุณทั่วสเปกตรัม?

คำตอบเดียวสำหรับคำถามนี้คือตัวกรอง Wiener ซึ่งต้องการความรู้เกี่ยวกับสถิติเสียงรบกวนและสัญญาณที่คุณต้องการ โดยทั่วไปสัญญาณรบกวน (สัญญาณ + เสียง) จะถูกลดทอนไปตามความถี่ที่คาดว่าจะมีเสียงรบกวนมากกว่าสัญญาณของคุณและมีการขยายเมื่อสัญญาณของคุณคาดว่าน่ากลัวกว่าเสียงของคุณ

อย่างไรก็ตามฉันขอแนะนำวิธีการที่ทันสมัยกว่าซึ่งใช้การประมวลผลที่ไม่ใช่เชิงเส้นตัวอย่างเช่นการแปลงเวฟเล็ต วิธีการเหล่านี้ให้ผลลัพธ์ที่ยอดเยี่ยม โดยทั่วไปสัญญาณรบกวนจะถูกย่อยสลายเป็นเวฟเล็ตก่อนจากนั้นจึงมีค่าสัมประสิทธิ์ขนาดเล็กเป็นศูนย์ วิธีการนี้ใช้งานได้ (และ DFT ไม่ได้) เนื่องจากลักษณะความละเอียดหลายระดับของเวฟเล็ต นั่นคือสัญญาณจะถูกประมวลผลแยกกันในย่านความถี่ที่กำหนดโดยการแปลงเวฟเล็ต

ใน MATLAB ให้พิมพ์ 'wavemenu' และ 'SWT denoising 1-D' จากนั้น 'ไฟล์', 'การวิเคราะห์ตัวอย่าง', 'สัญญาณที่มีเสียงดัง', 'โดยใช้ Haar ที่ระดับ 5, บล็อกที่มีเสียงดัง' ตัวอย่างนี้ใช้เวฟเล็ต Haar ซึ่งควรทำงานได้ดีสำหรับปัญหาของคุณ

ฉันไม่เก่งใน Python แต่ฉันเชื่อว่าคุณสามารถหาแพ็คเกจ NumPy ที่ทำงานกับ denoising Haar wavelet ได้


1
ฉันจะไม่เห็นด้วยกับคำสั่งแรกของคุณ คุณสมมติว่าสัญญาณที่น่าสนใจครอบคลุมแบนด์วิดท์เต็มของลำดับการป้อนข้อมูลซึ่งไม่น่าเป็นไปได้ ยังคงเป็นไปได้ที่จะได้รับอัตราส่วนสัญญาณต่อสัญญาณรบกวนที่ดีขึ้นโดยใช้การกรองแบบเส้นตรงในกรณีนี้ขจัดเสียงรบกวนนอกวง หากสัญญาณมีสัญญาณสูงเกินไปคุณอาจได้รับการปรับปรุงอย่างมากด้วยวิธีการง่ายๆ
Jason R

มันเป็นเรื่องจริงและสิ่งนี้ทำได้โดยตัวกรอง Wiener เมื่อคุณทราบสถิติของสัญญาณและเสียงรบกวนของคุณ
Daniel R. Pipa

แม้ว่าทฤษฏีที่อยู่เบื้องหลังการ denoising ของเวฟเล็ตจะมีความซับซ้อน แต่การใช้งานนั้นง่ายพอ ๆ กับวิธีที่คุณอธิบาย มันเกี่ยวข้องกับตัวกรองธนาคารและ thresholding เท่านั้น
Daniel R. Pipa

1
ฉันกำลังค้นคว้าเรื่องนี้อยู่ตอนนี้จะโพสต์ความก้าวหน้าของฉันข้างบนขอบคุณทั้งคุณและ Phonon สำหรับความช่วยเหลือทั้งหมดของคุณ!
Michael M

@DanielPipa ฉันไม่สามารถเข้าถึงแพ็คเกจ matlab ที่เป็นปัญหาได้ คุณสามารถให้กระดาษหรือการอ้างอิงอื่น ๆ ที่อธิบายวิธีการที่สอดคล้องกับรหัส matlab ของคุณ
John Robertson

0

ตามข้อเสนอแนะของ Daniel Pipa ฉันลองดูdenoising เวฟและพบบทความที่ยอดเยี่ยมนี้โดย Francisco Blanco-Silva

ที่นี่ฉันได้แก้ไขโค้ด Python ของเขาเพื่อให้การประมวลผลภาพทำงานกับ 2D (accelerometer) แทนข้อมูล 3D (ภาพ)

หมายเหตุขีด จำกัด คือ "สร้างขึ้น" สำหรับ soft-thresholding ในตัวอย่างของ Francisco พิจารณาสิ่งนี้และปรับเปลี่ยนสำหรับแอปพลิเคชันของคุณ

def wavelet_denoise(data, wavelet, noise_sigma):
    '''Filter accelerometer data using wavelet denoising

    Modification of F. Blanco-Silva's code at: https://goo.gl/gOQwy5
    '''
    import numpy
    import scipy
    import pywt

    wavelet = pywt.Wavelet(wavelet)
    levels  = min(15, (numpy.floor(numpy.log2(data.shape[0]))).astype(int))

    # Francisco's code used wavedec2 for image data
    wavelet_coeffs = pywt.wavedec(data, wavelet, level=levels)
    threshold = noise_sigma*numpy.sqrt(2*numpy.log2(data.size))

    new_wavelet_coeffs = map(lambda x: pywt.threshold(x, threshold, mode='soft'),
                             wavelet_coeffs)

    return pywt.waverec(list(new_wavelet_coeffs), wavelet)

ที่ไหน:

  • wavelet- ชื่อสตริงของรูปแบบเวฟเล็ตที่จะใช้ (ดูpywt.wavelist()เช่น'haar')
  • noise_sigma - ค่าเบี่ยงเบนมาตรฐานของสัญญาณรบกวนจากข้อมูล
  • data - อาร์เรย์ของค่าที่จะกรอง (เช่นข้อมูลแกน x, y หรือ z)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.