FFT 출력 이해


87

DFT / FFT 계산의 출력을 이해하는 데 도움이 필요합니다.

저는 숙련 된 소프트웨어 엔지니어이며 주요 주파수 찾기와 같은 일부 스마트 폰 가속도계 판독 값을 해석해야합니다. 불행히도, 저는 15 년 전에 대부분의 대학 EE 수업을 잤지 만 지난 며칠 동안 DFT와 FFT를 읽고있었습니다.

"EE 수업을 들어라"라는 응답은 없습니다. 고용주가 저에게 돈을 지불하면 실제로 그렇게 할 계획입니다. :)

그래서 여기 내 문제가 있습니다.

32Hz에서 신호를 캡처했습니다. 다음은 Excel에서 차트로 작성한 32 점의 1 초 샘플입니다.

여기에 이미지 설명 입력

그런 다음 Columbia University에서 Java로 작성된 일부 FFT 코드 를 얻었습니다 ( " Reliable and fast FFT in Java " 에 대한 게시물의 제안 사항을 따름 ).

이 프로그램의 출력은 다음과 같습니다. 나는 그것이 내부 FFT를 실행하고 있다고 믿기 때문에 입력과 출력 모두에 동일한 버퍼를 재사용합니다.

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  ]

따라서이 시점에서는 출력의 앞면이나 뒷면을 만들 수 없습니다. 나는 실수 부분이 성분 코사인 파의 진폭이고 허수 부분이 성분 사인파의 진폭 인 DFT 개념을 이해합니다. 또한 " 디지털 신호 처리에 대한 과학자 및 엔지니어 가이드 "에서이 다이어그램을 따를 수도 있습니다 . 여기에 이미지 설명 입력

그래서 내 구체적인 질문은 다음과 같습니다.

  1. FFT의 출력에서 ​​"가장 많이 발생하는 주파수"를 어떻게 찾을 수 있습니까? 이것은 내 가속도계 데이터 분석의 일부입니다. 실수 (코사인) 또는 가상 (사인) 배열을 읽어야합니까?

  2. 시간 영역에 32 점 입력이 있습니다. FFT의 출력은 실수의 경우 16 개 요소 배열이고 가상의 경우 16 개 요소 배열이어야하지 않습니까? 프로그램이 크기 32의 실제 및 가상 배열 출력을 제공하는 이유는 무엇입니까?

  3. 이전 질문과 관련하여 출력 배열의 인덱스를 어떻게 구문 분석합니까? 32Hz로 샘플링 된 32 개 샘플의 입력을 감안할 때, 16 요소 배열 출력은 샘플링 속도 (32Hz)의 1/2까지 인덱스가 균일하게 분산되어야한다는 것을 이해하고 있으므로 각 요소를 이해하는 것이 맞습니까? 배열의 (32Hz * 1/2) / 16 = 1Hz?

  4. FFT 출력에 음수 값이있는 이유는 무엇입니까? 값이 정현파의 진폭을 나타내는 것으로 생각했습니다. 예를 들어, Real [3] = -1.075의 출력은 주파수 3의 코사인 파에 대해 -1.075의 진폭을 의미해야합니다. 맞습니까? 진폭이 어떻게 음수 일 수 있습니까?


가속도계 판독 값 (속도, 거리)에서 무엇을 계산 하시겠습니까? 가속도계 판독 값의 노이즈는 가우스 분포를 따르며 사인파를 피팅하는 것이이를 어떻게 해결할 수 있는지 알 수 없습니다.
알리

2
그것은 특정 언어보다 더 일반적인입니다 같은 자바 태그를 제거해야합니다
user3791372

Columbia University의 소스를 살펴보면 전혀 효율적이지 않습니다. 버터 플라이 조회 테이블이있는 Cooley-Tucky의 단순하고 최적화되지 않은 구현이며 기존 라이브러리 함수를 사용하는 대신 비트 반전이 수동으로 수행됩니다.
Mark Jeronimus

@MarkJeronimus : Java에서 효율적인 FFT 구현을 권장 할 수 있습니까? 내가 정확하게 기억한다면, 내가 Columbia University 코드를 사용한 이유는 FFTW 라이브러리가 안드로이드 스마트 폰에서 실행하기에는 너무 복잡했기 때문입니다.
stackoverflowuser2010

흩어져있는 '최적화'구현을 찾았지만 기본적으로 N 크기 하나의 알고리즘 이므로 크기 범위가 필요한 경우 모든 루틴이 필요합니다. 실제로 저는 주로 Intel Integrated Performance Primitives (예, Java에서 JNA를 통해)를 사용했지만 무료가 아닙니다. 집에서 나는 기본적으로 당신이 연결 한 것과 동일한 알고리즘을 사용하지만 2005 년 교과서를 사용하여 처음부터 작성했습니다. FFT (Fast Fourier Transform)에 불과하며 'Fast FFT'라는 이름을 정당화 할만큼 '빠른'것은 없습니다.
Mark Jeronimus

답변:


85
  1. 복소수의 실수 또는 가상 부분을 찾아서는 안됩니다 (실수 및 가상 배열이 무엇인지). 대신 sqrt (real * real + imag * imag)로 정의 된 주파수의 크기를 찾고 싶습니다. 이 숫자는 항상 양수입니다. 이제 검색해야하는 모든 것은 최대 값입니다 (어레이의 첫 번째 항목은 무시합니다. DC 오프셋이며 주파수에 따른 정보를 전달하지 않음).

  2. 복잡한 FFT에서 복잡한 FFT를 사용하기 때문에 32 개의 실수 및 32 개의 가상 출력을 얻습니다. 허수 부 0 개로 확장하여 32 개의 샘플을 64 개의 값 (또는 32 개의 복잡한 값)으로 변환했습니다. 그 결과 주파수 결과가 두 번 발생하는 대칭 FFT 출력이 생성됩니다. 출력 0 ~ N / 2에서 사용할 준비가되고 출력 N / 2 ~ N에 미러링됩니다. 귀하의 경우 출력 N / 2 ~ N을 무시하는 것이 가장 쉽습니다. 필요하지 않습니다. FFT를 계산하는 방법에 대한 아티팩트입니다.

  3. fft-bin 방정식에 대한 주파수는 (bin_id * freq / 2) / (N / 2)이며 여기서 freq는 샘플 주파수 (일명 32Hz, N은 FFT의 크기)입니다. 귀하의 경우 이것은 빈당 1Hz로 단순화됩니다. 빈 N / 2에서 N은 음의 주파수를 나타냅니다 (이상한 개념, 알고 있습니다). 귀하의 경우에는 처음 N / 2 주파수의 거울이기 때문에 중요한 정보를 포함하지 않습니다.

  4. 각 빈의 실수 부와 허수 부는 복소수를 형성합니다. 실수와 허수 부분이 음수이고 주파수 자체의 크기가 양수이면 괜찮습니다 (질문 1에 대한 답변 참조). 나는 당신이 복소수를 읽는 것이 좋습니다. 작동 방식 (및 유용한 이유)을 설명하는 것은 단일 스택 오버플로 질문에서 설명 할 수있는 것보다 많습니다.

참고 : 자기 상관이 무엇인지, 그리고 신호의 기본 주파수를 찾는 데 사용되는 방법을 읽을 수도 있습니다. 이것이 당신이 정말로 원하는 것이라고 생각합니다.


1
감사. 관련 1 : 주파수 스펙트럼을 보여주는 Matlab 페이지 ( mathworks.com/help/techdoc/ref/fft.html )를 보았습니다 . 그 페이지에는 "y (t)의 단면 진폭 스펙트럼"이라는 제목의 플롯이 있습니다. 그것은 당신이 제안한 것처럼 주파수의 크기를 플로팅하고 있습니까, sqrt (real ^ 2 + img ^ 2)? 3에 관해서 : 나는 여전히 빈당 2Hz 결과를 얻지 못합니다. 제 경우에는 N = 32이고 freq = 32 맞죠? 따라서 N / 2 = 32 / 2 = 16 빈이 있고 가장 높은 주파수 (Nyquist)는 freq / 2 = 32 / 2 = 16Hz입니다. 결과적으로 빈당 16Hz가 발생하여 빈당 1Hz가됩니다.
stackoverflowuser2010

1
예, 플롯은 스펙트럼의 크기를 보여줍니다-| Y (f) |. 절대 값 막대는 크기를 의미합니다. 빈 너비 = 샘플 속도 / FFT 크기. 샘플 속도는 32 hz이고 FFT 크기는 32입니다. 네, 빈 너비에 대해 맞습니다!
Matt Montag 2011

빈 주파수를 수정했습니다.
André Chalella 2013-10-16

1
좋은 대답, 감사합니다! 파티에 조금 늦어서 미안하지만, (1 번에서 언급했듯이) 주파수의 크기가 일반적으로 몇 단위인지 대답 해 주시겠습니까? 제 경우에는 가속도계의 값 신호 (m / s ^ 2)를 사용합니다. 나는 그것을 이해할 수 없다.
Markus Wüstenberg 2014 년

매혹적인! 내 음악 시각화 주파수 막대는 모두 왼쪽에서 오른쪽으로 미러링되었습니다. 대답 # 2는 이것을 설명합니다 !! 미친!!
Ryan S

11

당신은 이미 좋은 답변을 가지고,하지만 난 당신이 정말 적용 할 필요가 있음을 추가 할 것입니다 윈도우 함수를 그렇지 않으면 인해, 당신의 스펙트럼에서 불쾌한 유물을 얻을 것이다는 FFT 이전에 당신의 시간 영역 데이터에 스펙트럼 누설 .


이 답변 이후 많은 시간이 흘렀다는 점에 감사드립니다. 그러나 어떤 종류의 인공물을 의미하는지 자세히 설명해 주시겠습니까?
MattHusz

1
@MattHusz : 이러한 인공물의 기원에 대한 일반적인 용어는 "스펙트럼 누출"입니다. 이제이를 설명하는 답변에 대한 링크를 추가했습니다. 효과를 설명 할 수있는 가장 좋은 방법은 암시 적 직사각형 창으로 인해 스펙트럼이 "번짐"된다는 것입니다.
Paul R

6

1) 첫 번째 값 (DC 구성 요소) 외에 가장 높은 값을 가진 실제 배열에서 인덱스를 찾습니다. 의미있는 결과를 많이 얻으려면 32Hz보다 상당히 높은 샘플 속도와 더 큰 창 크기가 필요할 것입니다.

2) 두 어레이의 후반부는 전반부의 미러입니다. 예를 들어, 실제 배열의 마지막 요소 (1.774)는 두 번째 요소 (1.774)와 동일하고 가상 배열의 마지막 요소 (1.474)는 두 번째 요소 의 음수 입니다.

3) 32Hz의 샘플링 속도에서 선택할 수있는 최대 주파수는 16Hz ( 나이 퀴 스트 제한 )이므로 각 단계는 2Hz입니다. 앞서 언급했듯이 첫 번째 요소는 0Hz (즉, DC 오프셋)임을 기억하십시오.

4) 물론 음의 진폭은 완벽합니다. 이는 신호가 "플립"된다는 것을 의미합니다. 표준 FFT는 일반적으로 t = 0에서 값 = 1 인 코사인을 기반으로하므로 시간 = 0에서 값 = -1 인 신호는 음의 진폭을 갖습니다. .


답장을 보내 주셔서 감사합니다. (1) 허수 (사인) 배열을 무시할 수 있다는 뜻입니까? 그렇다면 그 이유는 무엇입니까? 확실히 사인 성분이 중요해야합니까? (2) 왜 이러한 미러링이 발생합니까? FFT 알고리즘의 결과일까요? 대부분의 사람들은 미러링 된 절반을 무시합니까? (3) 2Hz 단계는 어떻게 계산 했습니까? 16Hz의 Nyquist 한계를 이해합니다. 따라서 16 개 (미러링되지 않은) 배열 요소가있는 경우 각 요소는 각각 16Hz / 16 = 1Hz 여야합니까? (4) 주 주파수를 찾으려면 출력 배열에서 진폭 값의 절대 값을 취해야합니까?
stackoverflowuser2010

실제 배열에서 가장 높은 값을 찾아서는 안되며 사인 / I 배열을 무시할 수 없습니다. 대신 복합 복소 벡터의 크기를 원합니다. 미러링은 입력 (I 배열)의 절반이 모두 0이므로 결과의 자유도가 절반이기 때문에 발생합니다. 데이터가 엄격하게 실제 인 경우 무시할 수 있습니다.
hotpaw2

@duskwuff 감사합니다. 제가 게시 할 질문에 답변을 주셨습니다. 답변을 찾지 못했을 경우 FFT의 두 번째 부분을 해석하는 방법입니다. 나는 데이터를 수정하고 역을 수행하고 싶고 그 부분에서 잘못된 데이터를 수정했기 때문에 결과의 절반 만 얻었습니다. 다시 한 번 감사드립니다.
Martin

(3), step = 2Hz의 값은 지금까지 나에게 암시 적으로 남아 있습니다. 길이가 16 인 배열로 표현되는 16 개의 빈이 있습니다. 0Hz에서 16Hz까지의 모든 주파수를 설명해야합니다. 나는 모든 빈이 그 범위의 일부를 설명한다고 가정합니다.
krafter

@krafter는 (반복이 없기 때문에) 단일 값에서 빈도를 추론 할 수 없기 때문에 절반으로 줄었다 고 생각합니다.
JVE999

5

"가장 많이 발생하는 주파수"는 윈도우 기능을 사용하더라도 여러 FFT 빈으로 산산조각이 날 수 있습니다. 따라서 스펙트럼 피크의 주파수를 더 잘 추정하기 위해 더 긴 창, 다중 창 또는 보간을 사용해야 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.