Hiểu đầu ra FFT


87

Tôi cần một số trợ giúp để hiểu đầu ra của tính toán DFT / FFT.

Tôi là một kỹ sư phần mềm có kinh nghiệm và cần giải thích một số kết quả đo gia tốc trên điện thoại thông minh, chẳng hạn như tìm tần số chính. Thật không may, tôi đã ngủ qua hầu hết các lớp EE đại học của mình cách đây mười lăm năm, nhưng tôi đã đọc trên DFT và FFT trong vài ngày qua (dường như có ít).

Vui lòng không có câu trả lời "tham gia lớp học EE". Tôi thực sự định làm điều đó nếu chủ nhân của tôi trả tiền cho tôi. :)

Vì vậy, đây là vấn đề của tôi:

Tôi đã bắt được tín hiệu ở tần số 32 Hz. Đây là mẫu 1 giây gồm 32 điểm, mà tôi đã vẽ biểu đồ trong Excel.

nhập mô tả hình ảnh ở đây

Sau đó, tôi nhận được một số mã FFT được viết bằng Java từ Đại học Columbia (sau khi làm theo các đề xuất trong một bài đăng về " FFT đáng tin cậy và nhanh chóng trong Java ").

Kết quả của chương trình này như sau. Tôi tin rằng nó đang chạy FFT tại chỗ, vì vậy nó sử dụng lại cùng một bộ đệm cho cả đầu vào và đầu ra.

Before: 

Re: [0.887  1.645  2.005  1.069  1.069  0.69  1.046  1.847  0.808  0.617  0.792  1.384  1.782  0.925  0.751  0.858  0.915  1.006  0.985  0.97  1.075  1.183  1.408  1.575  1.556  1.282  1.06  1.061  1.283  1.701  1.101  0.702  ]

Im: [0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ]

After: 

Re: [37.054  1.774  -1.075  1.451  -0.653  -0.253  -1.686  -3.602  0.226  0.374  -0.194  -0.312  -1.432  0.429  0.709  -0.085  0.0090  -0.085  0.709  0.429  -1.432  -0.312  -0.194  0.374  0.226  -3.602  -1.686  -0.253  -0.653  1.451  -1.075  1.774  ]

Im: [0.0  1.474  -0.238  -2.026  -0.22  -0.24  -5.009  -1.398  0.416  -1.251  -0.708  -0.713  0.851  1.882  0.379  0.021  0.0  -0.021  -0.379  -1.882  -0.851  0.713  0.708  1.251  -0.416  1.398  5.009  0.24  0.22  2.026  0.238  -1.474  ]

Vì vậy, tại thời điểm này, tôi không thể tạo đầu hoặc đuôi của đầu ra. Tôi hiểu các khái niệm DFT, chẳng hạn như phần thực là biên độ của sóng cosin thành phần và phần ảo là biên độ của sóng sin thành phần. Tôi cũng có thể theo dõi sơ đồ này từ cuốn sách tuyệt vời " Hướng dẫn của nhà khoa học và kỹ sư về xử lý tín hiệu kỹ thuật số ": nhập mô tả hình ảnh ở đây

Vì vậy, các câu hỏi cụ thể của tôi là:

  1. Từ đầu ra của FFT, làm cách nào để tìm "tần số xuất hiện nhiều nhất"? Đây là một phần trong phân tích dữ liệu gia tốc kế của tôi. Tôi nên đọc mảng thực (cosine) hay ảo (sin)?

  2. Tôi có đầu vào 32 điểm trong miền thời gian. Đầu ra của FFT không phải là một mảng 16 phần tử cho số thực và một mảng 16 phần tử cho ảo? Tại sao chương trình cung cấp cho tôi kết quả mảng thực và mảng ảo đều có kích thước 32?

  3. Liên quan đến câu hỏi trước, làm cách nào để phân tích cú pháp các chỉ mục trong mảng đầu ra? Với đầu vào của tôi là 32 mẫu được lấy mẫu ở 32 Hz, tôi hiểu rằng đầu ra của mảng 16 phần tử phải có chỉ số của nó trải đều lên đến 1/2 tốc độ lấy mẫu (32 Hz), vì vậy tôi hiểu rằng mỗi phần tử của mảng biểu diễn (32 Hz * 1/2) / 16 = 1 Hz?

  4. Tại sao đầu ra FFT có giá trị âm? Tôi nghĩ các giá trị đại diện cho biên độ của một hình sin. Ví dụ, đầu ra của Real [3] = -1.075 có nghĩa là biên độ -1.075 đối với sóng cosine tần số 3. Có đúng không? Làm thế nào một biên độ có thể là âm?


Bạn muốn tính toán gì từ các kết quả đo gia tốc kế: vận tốc, quãng đường? Tiếng ồn của các số đọc gia tốc kế tuân theo phân bố Gaussian và tôi không thể thấy sóng sin phù hợp sẽ khắc phục điều đó như thế nào.
Ali

2
tag java nên được loại bỏ vì nó là hơn chung hơn là một ngôn ngữ cụ thể
user3791372

Nhìn vào khu vực của Đại học Columbia, nó không hiệu quả chút nào. Đó là một triển khai đơn giản, không được tối ưu hóa của Cooley-Tucky với các bảng tra cứu bướm và đảo ngược bit được thực hiện thủ công thay vì sử dụng các chức năng thư viện hiện có
Mark Jeronimus

@MarkJeronimus: Bạn có thể đề xuất triển khai FFT hiệu quả trong Java không? Nếu tôi nhớ chính xác, lý do tôi sử dụng mã của Đại học Columbia là thư viện FFTW quá phức tạp để chạy trên điện thoại thông minh Android.
stackoverflowuser2010

Tôi đã tìm thấy một số triển khai 'tối ưu hóa' rải rác, nhưng về cơ bản chúng là một thuật toán cho mỗi kích thước N, vì vậy nếu bạn cần một loạt các kích thước, bạn cần tất cả các quy trình đó. Trong thực tế, tôi chủ yếu sử dụng Nguyên tắc Hiệu suất Tích hợp của Intel (có, từ Java, thông qua JNA), nhưng điều đó không miễn phí. Ở nhà, tôi sử dụng về cơ bản cùng một thuật toán mà bạn đã liên kết, nhưng được viết từ đầu vào năm 2005 bằng cách sử dụng một cuốn sách giáo khoa. Nó chỉ là FFT (Fast Fourier Transform), không có gì quá 'Nhanh' về nó để biện minh cho cái tên 'Fast FFT'.
Mark Jeronimus

Câu trả lời:


85
  1. Bạn không nên tìm phần thực hoặc phần tưởng tượng của một số phức (mảng thực và mảng ảo của bạn là gì). Thay vào đó, bạn muốn tìm độ lớn của tần số được định nghĩa là sqrt (real * real + image * images). Con số này sẽ luôn là số dương. Bây giờ tất cả những gì bạn phải tìm kiếm là giá trị lớn nhất (bỏ qua mục nhập đầu tiên trong mảng của bạn. Đó là phần bù DC của bạn và không mang thông tin phụ thuộc tần số).

  2. Bạn nhận được 32 đầu ra thực và 32 đầu ra tưởng tượng bởi vì bạn đang sử dụng FFT từ phức tạp đến phức tạp. Hãy nhớ rằng bạn đã chuyển đổi 32 mẫu của mình thành 64 giá trị (hoặc 32 giá trị phức tạp) bằng cách mở rộng nó bằng không phần ảo. Điều này dẫn đến đầu ra FFT đối xứng trong đó kết quả tần số xảy ra hai lần. Sau khi đã sẵn sàng để sử dụng ở các đầu ra 0 đến N / 2 và sau khi được nhân bản trong các đầu ra N / 2 đến N. Trong trường hợp của bạn, đơn giản nhất là bỏ qua các đầu ra N / 2 đến N. Bạn không cần chúng, chúng chỉ là một hiện vật về cách bạn tính toán FFT của mình.

  3. Tần số của phương trình fft-bin là (bin_id * freq / 2) / (N / 2) trong đó freq là tần số mẫu của bạn (còn gọi là 32 Hz và N là kích thước FFT của bạn). Trong trường hợp của bạn, điều này đơn giản hóa thành 1 Hz cho mỗi thùng. Các thùng từ N / 2 đến N đại diện cho tần số âm (khái niệm lạ, tôi biết). Đối với trường hợp của bạn, chúng không chứa bất kỳ thông tin quan trọng nào vì chúng chỉ là bản sao của N / 2 tần số đầu tiên.

  4. Phần thực và phần ảo của mỗi thùng tạo thành một số phức. Sẽ không sao nếu các phần thực và phần ảo là âm trong khi độ lớn của tần số là dương (xem câu trả lời của tôi cho câu hỏi 1). Tôi đề nghị bạn nên đọc các số phức. Giải thích cách chúng hoạt động (và tại sao chúng hữu ích) vượt quá những gì có thể giải thích trong một câu hỏi ngăn xếp chồng lên nhau.

Lưu ý: Bạn cũng có thể muốn đọc tự tương quan là gì và cách nó được sử dụng để tìm tần số cơ bản của tín hiệu. Tôi có cảm giác rằng đây là những gì bạn thực sự muốn.


1
Cảm ơn. Về 1: Tôi thấy trang Matlab này hiển thị phổ tần số ( mathworks.com/help/techdoc/ref/fft.html ). Trên trang đó là một âm mưu với tiêu đề là "Phổ biên độ một mặt của y (t)". Đó có phải là biểu đồ về độ lớn của tần suất như bạn đề xuất, sqrt (real ^ 2 + img ^ 2) không? Về 3: Tôi vẫn không nhận được kết quả 2Hz trên mỗi thùng. Trong trường hợp của tôi, N = 32 và freq = 32, phải không? Vậy có N / 2 = 32/2 = 16 thùng, và tần số cao nhất (Nyquist) là freq / 2 = 32/2 = 16 Hz, dẫn đến 16 Hz trên 16 thùng, cho 1 Hz trên mỗi thùng?
stackoverflowuser2010

1
Đúng, biểu đồ cho thấy độ lớn của quang phổ - | Y (f) |. Các thanh giá trị tuyệt đối có nghĩa là độ lớn. Chiều rộng thùng = tỷ lệ mẫu / kích thước FFT. Tốc độ lấy mẫu của bạn là 32 hz, kích thước FFT của bạn là 32. Vâng, bạn nói đúng về chiều rộng thùng rác!
Matt Montag,

Đã sửa tần số bin.
André Chalella

1
Câu trả lời tốt đẹp, cảm ơn! Xin lỗi vì tôi đến bữa tiệc hơi muộn, nhưng có lẽ bạn có thể trả lời cho tôi đơn vị độ lớn của tần số (như bạn đã đề cập ở điểm 1) nói chung là gì? Trong trường hợp của tôi, trên một tín hiệu của các giá trị từ một gia tốc kế (là m / s ^ 2). Tôi không thể hình dung ra được.
Markus Wüstenberg

Hấp dẫn! Tất cả các thanh tần số hình ảnh hóa âm nhạc của tôi đều được phản chiếu từ trái sang phải; câu trả lời số 2 giải thích điều này !! Khùng!!
Ryan S

11

Bạn đã có một số câu trả lời hay, nhưng tôi chỉ nói thêm rằng bạn thực sự cần áp dụng hàm cửa sổ cho dữ liệu miền thời gian của mình trước FFT, nếu không, bạn sẽ nhận được các đồ tạo tác khó chịu trong phổ của mình, do rò rỉ phổ .


Tôi đánh giá cao rằng đã có rất nhiều thời gian trôi qua kể từ câu trả lời này .. Tuy nhiên, bạn có thể giải thích thêm về loại đồ tạo tác mà bạn muốn nói không?
MattHusz

1
@MattHusz: thuật ngữ chung cho nguồn gốc của những đồ tạo tác này là "rò rỉ quang phổ" - Tôi đã thêm một liên kết đến câu trả lời để giải thích điều này. Cách tốt nhất tôi có thể mô tả hiệu ứng là quang phổ của bạn sẽ bị “nhòe” do cửa sổ hình chữ nhật ngầm định.
Paul R

6

1) Tìm kiếm các chỉ số trong mảng thực có giá trị cao nhất, bên cạnh chỉ số đầu tiên (đó là thành phần DC). Có thể bạn sẽ cần tốc độ lấy mẫu cao hơn đáng kể 32 Hz và kích thước cửa sổ lớn hơn, để có được nhiều kết quả có ý nghĩa.

2) Nửa sau của cả hai mảng là gương của nửa đầu. Ví dụ: lưu ý rằng phần tử cuối cùng của mảng thực (1.774) giống với phần tử thứ hai (1.774) và phần tử cuối cùng của mảng ảo (1.474) là phần tử âm của phần tử thứ hai.

3) Tần số tối đa bạn có thể nhận ở tốc độ lấy mẫu 32 Hz là 16 Hz ( giới hạn Nyquist ), vì vậy mỗi bước là 2 Hz. Như đã lưu ý trước đó, hãy nhớ rằng phần tử đầu tiên là 0 Hz (tức là độ lệch DC).

4) Chắc chắn, một biên độ âm có ý nghĩa hoàn hảo. Nó chỉ có nghĩa là tín hiệu bị "lộn" - FFT tiêu chuẩn dựa trên cosin, thường có giá trị = 1 tại t = 0, vì vậy tín hiệu có giá trị = -1 tại thời điểm = 0 sẽ có biên độ âm .


Cảm ơn vi đa trả lơi. (1) Ý của bạn là tôi có thể bỏ qua mảng (sin) tưởng tượng, và nếu vậy, tại sao? Chắc thành phần sin phải quan trọng? (2) Tại sao sự phản chiếu này xảy ra? Nó chỉ là kết quả của thuật toán FFT? Hầu hết mọi người có bỏ qua một nửa được nhân đôi không? (3) Làm thế nào bạn tính toán các bước của 2Hz? Tôi hiểu giới hạn Nyquist là 16Hz, vì vậy nếu có 16 phần tử mảng (không được nhân đôi), mỗi phần tử phải là 16 Hz / 16 = 1 Hz mỗi phần? (4) Để tìm tần số chính, tôi chỉ cần lấy giá trị tuyệt đối của giá trị biên độ trong mảng đầu ra?
stackoverflowuser2010

Bạn không nên tìm giá trị cao nhất trong mảng thực và không thể bỏ qua mảng sin / I. Thay vào đó bạn muốn độ lớn của vector phức hợp. Phản chiếu xảy ra bởi vì một nửa đầu vào (mảng I) là tất cả các số 0, vì vậy kết quả có một nửa số bậc tự do. Bạn có thể bỏ qua nó nếu dữ liệu của bạn là thật.
hotpaw2

@duskwuff Cảm ơn rất nhiều: bạn đã đưa ra câu trả lời cho câu hỏi mà tôi sẽ đăng, nếu tôi không tìm thấy câu trả lời của bạn: cách diễn giải phần THỨ HAI của FFT. Tôi muốn sửa đổi dữ liệu và thực hiện phép nghịch đảo và tôi chỉ nhận được một nửa kết quả, vì tôi đã sửa đổi dữ liệu sai trong phần đó. Cảm ơn một lần nữa.
Martin

(3), giá trị của bước = 2Hz vẫn còn ẩn đối với tôi cho đến nay. Chúng tôi có 16 thùng, được biểu diễn bằng mảng lenght = 16. Chúng ta cần mô tả tất cả các tần số từ 0Hz đến 16Hz. Tôi cho rằng mỗi thùng mô tả một phần của phạm vi đó, phải không?
krafter

@krafter Tôi nghĩ nó giảm một nửa vì bạn không thể suy ra tần số từ một giá trị duy nhất (vì không có sự lặp lại).
JVE999

5

Lưu ý rằng "tần suất xuất hiện nhiều nhất" có thể bị phân tán vào nhiều thùng FFT, ngay cả với chức năng cửa sổ. Vì vậy, bạn có thể phải sử dụng một cửa sổ dài hơn, nhiều cửa sổ hoặc phép nội suy để ước tính tốt hơn tần số của bất kỳ đỉnh quang phổ nào.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.