Comprehensive documentation for accessing the DWARF camera streams:
- RTSP URLs and channels (ch0=tele, ch1=wide)
- The critical prerequisite: camera must be opened via WebSocket first
- ffmpeg commands for frame capture, timelapse, and video recording
- mpv and VLC usage with TCP transport
- Python/OpenCV integration example
- Troubleshooting common issues (black image, connection refused, VLC delay)
- Comparison of RTSP vs MJPEG modes across device models
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
86 lines
1.7 KiB
Go
86 lines
1.7 KiB
Go
package odometry
|
||
|
||
import "math"
|
||
|
||
// fft is an in-place iterative radix-2 Cooley-Tukey FFT.
|
||
// len(a) must be a power of two. If inverse is true the result is normalized
|
||
// by 1/n (so ifft(fft(x)) == x).
|
||
func fft(a []complex128, inverse bool) {
|
||
n := len(a)
|
||
if n <= 1 {
|
||
return
|
||
}
|
||
|
||
// Bit-reversal permutation.
|
||
for i, j := 1, 0; i < n; i++ {
|
||
bit := n >> 1
|
||
for ; j&bit != 0; bit >>= 1 {
|
||
j ^= bit
|
||
}
|
||
j ^= bit
|
||
if i < j {
|
||
a[i], a[j] = a[j], a[i]
|
||
}
|
||
}
|
||
|
||
// Butterfly stages.
|
||
for length := 2; length <= n; length <<= 1 {
|
||
// Standard forward DFT uses exp(-i*2π/length); inverse negates.
|
||
angle := -2 * math.Pi / float64(length)
|
||
if inverse {
|
||
angle = -angle
|
||
}
|
||
wlen := complex(math.Cos(angle), math.Sin(angle))
|
||
half := length / 2
|
||
for i := 0; i < n; i += length {
|
||
var w complex128 = 1
|
||
for k := 0; k < half; k++ {
|
||
u := a[i+k]
|
||
v := a[i+k+half] * w
|
||
a[i+k] = u + v
|
||
a[i+k+half] = u - v
|
||
w *= wlen
|
||
}
|
||
}
|
||
}
|
||
|
||
if inverse {
|
||
invN := complex(1/float64(n), 0)
|
||
for i := range a {
|
||
a[i] *= invN
|
||
}
|
||
}
|
||
}
|
||
|
||
// fftRows applies a 1-D FFT to every row of m (in place).
|
||
func fftRows(m [][]complex128, inverse bool) {
|
||
for i := range m {
|
||
fft(m[i], inverse)
|
||
}
|
||
}
|
||
|
||
// fftCols applies a 1-D FFT to every column of m (in place).
|
||
func fftCols(m [][]complex128, inverse bool) {
|
||
rows := len(m)
|
||
if rows == 0 {
|
||
return
|
||
}
|
||
cols := len(m[0])
|
||
col := make([]complex128, rows)
|
||
for j := 0; j < cols; j++ {
|
||
for i := 0; i < rows; i++ {
|
||
col[i] = m[i][j]
|
||
}
|
||
fft(col, inverse)
|
||
for i := 0; i < rows; i++ {
|
||
m[i][j] = col[i]
|
||
}
|
||
}
|
||
}
|
||
|
||
// fft2 performs a forward 2-D FFT on the rows×cols complex matrix m.
|
||
func fft2(m [][]complex128, inverse bool) {
|
||
fftRows(m, inverse)
|
||
fftCols(m, inverse)
|
||
}
|