FFT 출력 이해
DFT/FFT 계산의 출력을 이해하는 데 도움이 필요합니다.
저는 숙련된 소프트웨어 엔지니어이며 주요 주파수 찾기 등 스마트폰 가속도계 수치를 해석해야 합니다.안타깝게도 저는 15년 전에 대학 EE 수업 대부분을 잤지만, 최근 며칠 동안 DFT와 FFT에 대해 자세히 읽고 있습니다(아무런 효과도 없는 것 같습니다).
제발 "EE 수업 들으러 가"라고 대답하지 마세요.사실 저는 고용주가 돈을 준다면 그렇게 할 계획입니다.:)
제 문제는 이렇습니다.
32Hz의 신호를 포착했습니다엑셀로 작성한 32점의 1초 샘플입니다.
그 후, 콜롬비아 대학에서 Java로 작성된 FFT 코드를 입수했습니다(「Java에서의 신뢰성과 고속 FFT」에 관한 투고에서 제시된 내용을 따름).
이 프로그램의 출력은 다음과 같습니다.인플레이스 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 개념을 이해했습니다.이 그림은 훌륭한 책인 "디지털 신호 처리 과학자와 엔지니어 가이드"에서도 볼 수 있습니다.
구체적인 질문은 다음과 같습니다.
FFT 출력에서 "가장 많이 발생하는 주파수"를 찾으려면 어떻게 해야 합니까?이것은 가속도계 데이터 분석의 일부입니다.실제(코사인) 어레이와 가상(사인) 어레이 중 어느 것을 읽어야 합니까?
시간 영역에 32포인트 입력이 있습니다.FFT의 출력은 실수의 경우 16 요소 배열, 허상의 경우 16 요소 배열이어야 하지 않나요?이 프로그램은 왜 32사이즈의 실제와 가상의 배열 출력을 모두 제공합니까?
이전 질문과 관련하여 출력 배열의 인덱스를 해석하려면 어떻게 해야 합니까?32Hz에서 샘플링된 32개의 샘플 입력을 고려할 때 16비트 어레이 출력의 인덱스는 샘플링 속도(32Hz)의 1/2까지 균등하게 분산되어야 한다고 생각합니다. 어레이의 각 요소가 (32Hz * 1/2) / 16 = 1Hz를 나타낸다고 이해하면 올바른 것입니까?
FFT 출력의 값이 음수인 이유는 무엇입니까?나는 그 값이 정현동의 진폭을 나타낸다고 생각했다.예를 들어 Real [ 3 ] = -1.075의 출력은 주파수 3의 코사인 파형에 대해 -1.075의 진폭을 의미합니다.그래요?어떻게 진폭이 음수일 수 있죠?
복소수에서 실수나 상상력이 풍부한 부분(실제 배열과 상상의 배열)을 찾지 마십시오.대신 sqrt(실제 * 실제 + 이미지 * 이미지)로 정의된 주파수의 크기를 찾아야 합니다.이 숫자는 항상 양수입니다.이제 최대값만 검색하면 됩니다(어레이의 첫 번째 엔트리는 무시).이는 DC 오프셋이며 주파수 종속 정보를 전달하지 않습니다.
복소 FFT를 사용하고 있기 때문에 32개의 실제 출력과 32개의 허수 출력을 얻을 수 있습니다.32개의 표본을 0개의 허수 부품으로 확장하여 64개의 값(또는 32개의 복소수 값)으로 변환했습니다.따라서 주파수 결과가 두 번 발생하는 시메트릭 FFT 출력이 생성됩니다.출력 0 ~ N/2에서 사용할 준비가 된 후 출력 N/2 ~ N에서 미러링됩니다.이 경우 출력 N/2에서 N으로 단순히 무시하는 것이 가장 쉽습니다.FFT 계산 방법의 아티팩트일 뿐이므로 필요하지 않습니다.
FFT-bin 방정식의 주파수는 (bin_id * freq/2) / (N/2)입니다. 여기서 freq는 샘플 주파수(일명 32Hz, N은 FFT 크기)입니다.이 경우 빈당 1Hz로 단순화됩니다.빈 N/2 ~ N은 음의 주파수를 나타냅니다(이상한 개념, 알고 있습니다).이 경우 첫 번째 N/2 주파수의 미러에 불과하기 때문에 중요한 정보는 포함되지 않습니다.
각 빈의 실제 부분과 상상의 부분이 복소수를 형성합니다.주파수 자체의 크기가 양수인 반면 실제 및 가상 부분이 음수인 경우에도 괜찮습니다(질문 1에 대한 내 답변 참조).나는 당신이 복잡한 숫자에 대해 읽기를 제안합니다.이러한 기능의 설명(및 그것들이 유용한 이유)은 단일 스택오버플로우 질문으로 설명할 수 있는 수준을 넘어섭니다.
참고: 자기 상관이란 무엇이며, 신호의 기본 주파수를 찾는 데 자기 상관을 사용하는 방법도 읽을 수 있습니다.이게 당신이 정말 원하는 것 같아요.
당신은 이미 몇 가지 좋은 답을 가지고 있지만, FFT 전에 윈도우 함수를 시간 영역 데이터에 적용해야 합니다. 그렇지 않으면 스펙트럼 누출로 인해 스펙트럼에 좋지 않은 아티팩트가 생깁니다.
1) 실제 배열에서 값이 가장 높은 인덱스를 찾습니다.이것이 DC 컴포넌트입니다.의미 있는 결과를 얻으려면 32Hz보다 상당히 높은 샘플링 레이트와 더 큰 윈도우 사이즈가 필요할 수 있습니다.
2) 양쪽 어레이의 후반부는 전반부의 미러입니다.예를 들어, 실제 배열의 마지막 요소(1.774)는 두 번째 요소(1.774)와 같고, 가상 배열의 마지막 요소(1.474)는 두 번째 요소의 음수입니다.
3) 샘플 레이트 32Hz로 픽업할 수 있는 최대 주파수는 16Hz(나이키스트 한계)이므로 각 스텝은 2Hz입니다.앞에서 설명한 바와 같이 첫 번째 요소는 0Hz(DC 오프셋)입니다.
4) 물론 음의 진폭은 매우 적합합니다.즉, 신호가 "표준 FFT"임을 의미합니다. 표준 FFT는 일반적으로 t = 0에서 값 = 1인 코사인(cosine)을 기반으로 하므로 시간 = -1인 신호는 음의 진폭을 가집니다.
"가장 많이 발생하는 주파수"는 윈도우 기능이 있더라도 여러 FFT 빈으로 분산될 수 있습니다.따라서 스펙트럼 피크의 빈도를 더 잘 추정하기 위해 더 긴 창, 여러 창 또는 보간법을 사용해야 할 수 있습니다.
언급URL : https://stackoverflow.com/questions/6740545/understanding-fft-output
'source' 카테고리의 다른 글
MariaDB/MySQL의 다단계 JSON에서 특정 값을 쿼리하는 중 (0) | 2022.12.18 |
---|---|
SQL - 특정 조건을 가진 행을 선택하는 방법 (0) | 2022.12.18 |
Larabel 5 마이그레이션 식별자 이름이 너무 깁니다. (0) | 2022.12.18 |
매크로에서 1과 0을 정의하기 위해 3진 연산자를 사용하는 이유는 무엇입니까? (0) | 2022.12.18 |
도커 업데이트 후 Mysql 테이블이 없음: "TableName이 엔진에 없습니다." (0) | 2022.12.18 |