|
280 | 280 | :high-cutoff high-cutoff}) |
281 | 281 | :standardize stats/standardize})) |
282 | 282 |
|
283 | | -;; ## Power Spectrum Analysis: Extracting Heart Rate |
| 283 | +;; ## Power Spectrum Analysis: Extracting Heart Rate - DRAFT |
| 284 | +;; |
| 285 | +;; 🛠 NOTE: This is stil work-in-progress. In visualizing, we need to scale the frequency domain exist correctly. |
284 | 286 | ;; |
285 | 287 | ;; Now comes the key step: **extracting heart rate from the camera signal**. |
286 | 288 | ;; |
|
397 | 399 | (kind/fragment |
398 | 400 | [(kind/hiccup |
399 | 401 | [:div |
400 | | - [:h4 "1. Raw Windowed Signal (after preprocessing)"] |
| 402 | + [:h4 "1. Raw windowed signal (after preprocessing)"] |
401 | 403 | [:p "Each row is a time sample, showing how the signal varies across windows (columns) and channels."]]) |
402 | 404 |
|
403 | 405 | (-> windows |
|
406 | 408 |
|
407 | 409 | (kind/hiccup |
408 | 410 | [:div |
409 | | - [:h4 "2. After Hanning Window"] |
| 411 | + [:h4 "2. After Hanning window"] |
410 | 412 | [:p "Notice how the edges of each window are tapered to zero. This reduces spectral leakage in the FFT."]]) |
411 | 413 |
|
412 | 414 | (-> hanninged-windows |
|
415 | 417 |
|
416 | 418 | (kind/hiccup |
417 | 419 | [:div |
418 | | - [:h4 "3. Power Spectrum"] |
| 420 | + [:h4 "3. Power spectrum"] |
419 | 421 | [:p "Each row is a frequency bin. Bright bands indicate strong frequency components. " |
420 | 422 | "The dominant frequency (brightest band in the 0.65-4 Hz range) corresponds to the heart rate."]]) |
421 | 423 |
|
422 | 424 | (-> power-spectrum |
423 | 425 | plotly/imshow) |
424 | 426 |
|
425 | | - (kind/md "### 4. Power Spectrum Time Series\n\nEach plot shows how the power spectrum evolves over time.") |
| 427 | + (kind/md "4. Slicing the power spectrum along time\n\nEach plot shows how the power spectrum at one window.") |
426 | 428 |
|
427 | 429 | (-> power-spectrum |
428 | 430 | (tensor/slice 1) |
429 | 431 | (->> (map (fn [s] |
430 | 432 | (-> s |
431 | 433 | ds-tensor/tensor->dataset |
432 | 434 | (tc/rename-columns [:R :G :B]) |
433 | | - plot-signal))) |
| 435 | + (plotly/base {:=x :x |
| 436 | + :=mark-opacity 0.7}) |
| 437 | + (plotly/layer-line {:=y :R |
| 438 | + :=mark-color "red"}) |
| 439 | + (plotly/layer-line {:=y :G |
| 440 | + :=mark-color "green"}) |
| 441 | + (plotly/layer-line {:=y :B |
| 442 | + :=mark-color "blue"})))) |
434 | 443 | (into [:div {:style {:max-height "600px" |
435 | 444 | :overflow-y "auto"}}]) |
436 | 445 | kind/hiccup))])) |
|
0 commit comments