Cómo ver la reverberación o la transmisión de video por sonido a través del agua - 2

Hola querida



Hoy volveremos a transmitir la imagen con ultrasonido a través del agua: literalmente veremos reverberación y eco, e incluso cómo cambian según las condiciones. Todo lo que le diré es simple, es interesante repetirlo yo mismo y casi cualquier persona puede hacerlo.

Si algo está revoloteando en tu alma por estas palabras, ¡bienvenido a Kat a las aguas oscuras de nuestro estanque!




"El mejor descanso es interpretar verdades conocidas". (C) ABS, mediodía, siglo XXII


Juegos previos


La regla básica del club de testigos de hidroacústica es que el video que usa hidroacústica a una distancia más o menos significativa (más de unos pocos metros) en el cuerpo medio de agua no se puede transmitir, y siempre será imposible.
Existen serias razones para esto: un canal de comunicación con un ancho de banda muy bajo, una velocidad de propagación de señal baja (en agua de solo 1,500 m / s) y una alta probabilidad de error. La banda de frecuencia disponible es solo unas pocas decenas de kilohercios.
Pero esto no es todo: si, en términos relativos, una señal a frecuencias del orden de 10 kHz se propaga en el agua a una distancia de aproximadamente 8-10 km, entonces a una frecuencia de 20 kHz ya es de 3-5 km, y cuanto mayor sea la frecuencia, mayor será la atenuación . Por ejemplo, nuestros módems uWAVE más pequeños del mundo operan en la banda de 20-30 kHz y transmiten datos a una velocidad de 78 bit / s por 1000 metros, y RedLINE con una banda de 5-15 a 8000 metros. El récord entre dispositivos comerciales pertenece a EvoLogics : 68 kBits por 300 metros.
La física, por desgracia, no puede ser engañada y es imposible estar de acuerdo con ella: puede transmitirse de forma muy lenta e inmune al ruido, o rápidamente, pero a distancias cortas.
Sin embargo, en algunos casos es posible "cortar algunas esquinas", las cuales cortaremos esta vez son más bajas.

¿Qué haremos hoy y qué se necesita para esto?


En artículos anteriores, ya transmitimos "video" con sonido a través del agua , les recuerdo que allí el cuadro fue "dibujado en el espectro", es decir, el espectro, o más bien el espectrograma de la señal era una imagen.
Más tarde fabricamos antenas hidroacústicas simples a partir de escombros e hicimos un módem hidroacústico simple . Allí también hicimos un preamplificador para la antena (el diseño de la PCB para la autoproducción por LUT-ohm todavía se encuentra aquí ).

Pensamos, ¿de qué otra manera puedes tratar de transmitir la imagen para que incluso un estudiante de jardín de infantes pueda resolverlo? Y, como nos parece a nosotros, se les ocurrió una forma aún más simple que antes.

Entonces, para resumir, elabore una lista de lo que necesitamos:

- un par de antenas de sonar de recolectores de pastel
- preamplificador fabricado por LUT
- Código fuente del proyecto C #
- un par de baterías de plomo a 12 voltios
- un amplificador en TDA, tomé uno por solo 50 rublos en Ali

Poco de teoría


Recuerde que nuestro módem de sonda se basó en un detector de tono simple, cuya frecuencia es 4 veces menor que la frecuencia de muestreo. Recuerda brevemente cómo funciona.


La imagen muestra dos oscilaciones desplazadas entre sí en Pi / 2, es decir, las fases seno y coseno. Y si la frecuencia es exactamente cuatro veces menor que la frecuencia de muestreo, entonces solo 4 muestras caen en el período.
Un habuchitel atento ciertamente notó que ambas señales se desplazan a Pi / 4. Con este cambio, la señal solo toma dos valores: √2 / 2 y -√2 / 2.
Y los valores específicos ni siquiera son importantes, es importante que pueda usar solo los signos: "+" y "-".

Ahora podemos representar la fase sinusoidal como una secuencia de signos "+" "+" "-" "-", y la fase cosenoidal como "+" "-" "-" "+".

Debajo del spoiler, repita el detector:
Deje que la señal de entrada esté en el búfer sn, tenemos dos búferes de promedio de anillo para las fases seno y coseno - bs y bc de tamaño N. Tienen punteros comunes de cabeza y cola - bH y bT. En el momento inicial del tiempo, bH = N-1, bT = 0. Contador de ciclo promedio C = 0.
Tomamos 4 muestras del búfer de entrada y las agregamos de acuerdo con las secuencias de caracteres.

a = sn(i)
bs(bH) = a
bc(bH) = a
s1 = s1 + a - bs(bT)
s2 = s2 + a - bc(bT)
bH = (bH + 1) % N
bT = (bT + 1) % N

a = sn(i+1)
bs(bH) = a
bc(bH) = -a
s1 = s1 + a - bs(bT)
s2 = s2 - a - bc(bT)
bH = (bH + 1) % N
bT = (bT + 1) % N

a = sn(i+2)
bs(bH) = -a
bc(bH) = -a
s1 = s1 - a - bs(bT)
s2 = s2 - a - bc(bT)
bH = (bH + 1) % N
bT = (bT + 1) % N

a = sn(i+3)
bs(bH) = -a
bc(bH) = a
s1 = s1 - a - bs(bT)
s2 = s2 + a - bc(bT)
bH = (bH + 1) % N
bT = (bT + 1) % N


Después de cada cuatro muestras procesadas, verificamos el contador de los ciclos de promedio y si ha excedido N, entonces calculamos la amplitud cA de la portadora:

if ++cycle >= N
cA = sqrt(s1 * s1 + s2 * s2)
cycle = 0
end



Tomamos este método como base, será responsable de la "sincronización".
Ahora veamos cómo se codifica la imagen. Sugiero usar manipulación de amplitud . La manipulación es cuando una señal se divide en segmentos iguales llamados chips o símbolos, y algún parámetro variable (en nuestro caso, la amplitud) se almacena a lo largo de la longitud del chip.
Si, por ejemplo, podemos variar la amplitud en el rango de 0 a 32767 (muestras de 16 bits), y necesitamos transferir 255 valores del brillo de los píxeles, entonces, por unidad de cambio en el brillo del píxel, la amplitud del chip cambiará a 32768/255 = 128.
Otro parámetro importante es la longitud del chip, comenzamos con un período de soporte, cuatro muestras en nuestro caso.
Entonces, la imagen se transmitirá píxel por píxel, cada píxel dura 4 muestras, y la amplitud para este período será b [x, y] * 128, donde b [x, y] es el valor de brillo del píxel con las coordenadas x e y en la imagen b.

Vamos a estimar cuál será la velocidad de transmisión.
En el ejemplo, utilicé un tamaño de cuadro de 120x120 píxeles. Esto significa que para transferir un cuadro, necesitamos

120x120x4 = 57600 muestras,

Si la frecuencia de muestreo es de 96 kHz, la transmisión de un cuadro llevará tiempo:

57600/96000 = 0.6 segundos

Obviamente, necesitamos algún tipo de pausa, un cierto intervalo de guarda, para que el detector pueda determinar el comienzo del siguiente cuadro. Por razones humanas, supongamos que 0.1 segundos son suficientes para nosotros, durante los cuales todos los ecos desaparecen (en realidad no). Luego, al final, la tasa de transferencia resultará:

1 / (0.6 + 0.1) = 1.428 cuadros por segundo.

Aquí es muy fácil cometer un error e intentar calcular la velocidad en bits por segundo. Vea lo increíble que es la velocidad de transmisión:

120 * 120 * 8 / 1.428 = 80627 bps

Pero, ¿qué sucede si no tengo píxeles de 8 bits, sino de 16 bits?

120 * 120 * 16 / 1.428 = 161344 bps

El problema aquí es que, nuevamente, este método de transmisión no puede llamarse digital, y el concepto de velocidad de bits no es completamente válido para él.
Intente calcular la velocidad de bits para una señal de televisión analógica. ¿Y para el receptor detector? :)

Entonces, por ejemplo, se verá una parte de la señal, transmitiendo el brillo de 10 píxeles, cuyos valores cambian alternativamente: 1 2 1 2 1 2 1 2 1 2


Ahora veamos cómo funciona esto en el ejemplo. Los métodos Encode y Decode viven en la clase Encoder y son responsables de modular y demodular la imagen:

 public double[] Encode(Bitmap source, double carrier, int pSize, int interframePauseMs) { Bitmap frame; if (source.PixelFormat != System.Drawing.Imaging.PixelFormat.Format8bppIndexed) frame = Grayscale.CommonAlgorithms.RMY.Apply(source); else frame = source; if (!frame.Size.Equals(frameSize)) frame = resizer.Apply(frame); int cols = frameSize.Width; int rows = frameSize.Height; int col = 0; int row = 0; double delta = Math.PI * 2 * carrier / sampleRate; double alpha = 0; double phase = 0; double pxAmplitude = 0; double chipLimit = Math.PI * 2 * chipSize; double pLimit = Math.PI * 2; List<double> samples = new List<double>(); bool isFinished = false; for (int i = 0; i < pSize; i++) { alpha = Math.Sin(phase); phase += delta; if (phase >= pLimit) { phase -= pLimit; } samples.Add(alpha * short.MaxValue); } while (!isFinished) { alpha = Math.Sin(phase); phase += delta; if (phase >= chipLimit) { phase -= chipLimit; pxAmplitude = (((double)frame.GetPixel(col, row).R) / 255.0) * short.MaxValue; if (++col >= cols) { if (++row >= rows) isFinished = true; else col = 0; } } samples.Add(alpha * pxAmplitude); } if (interframePauseMs > 0) { samples.AddRange(new double[(int)((((double)interframePauseMs) / 1000.0) * (double)sampleRate)]); } return samples.ToArray(); } 


Se puede ver en el código que antes de modular la imagen, se agrega un prefijo de sincronización que consiste en un tono puro (muestras pSize) a la señal de salida; esto es necesario para que en el lado receptor pueda ocurrir una sincronización antes de que la imagen misma y en general pueda ocurrir en condiciones adversas.
El método de decodificación es el siguiente:

 public Bitmap Decode(double[] samples, double carrier, int pSize) { int cols = frameSize.Width; int rows = frameSize.Height; int col = 0; int row = 0; Bitmap result = new Bitmap(cols, rows); double delta = Math.PI * 2 * carrier / sampleRate; double alpha = 0; double phase = 0; double chipLimit = Math.PI * 2 * chipSize; double chipAmplitude = 0; double maxAmplitude = WaveUtils.GetMaxAmplitude(samples); double pxMax = -maxAmplitude; double pxMin = maxAmplitude; double smp; for (int i = pSize; (i < samples.Length) && (row < rows); i++) { alpha = Math.Sin(phase); phase += delta; if (phase >= chipLimit) { phase -= chipLimit; chipAmplitude = (Math.Max(Math.Abs(pxMax), Math.Abs(pxMin)) / maxAmplitude); pxMin = maxAmplitude; pxMax = -maxAmplitude; var gs = Convert.ToByte(chipAmplitude * 255); result.SetPixel(col, row, Color.FromArgb(255, gs, gs, gs)); if (++col >= cols) { col = 0; row++; } } else { smp = samples[i] * alpha; if (smp > pxMax) pxMax = smp; if (smp < pxMin) pxMin = smp; } } return result; } 


Se puede ver que ambos métodos no están vinculados a ninguna frecuencia en particular y se pueden usar con otro detector.

La búsqueda de señal en sí misma (detección, sincronización) también se produce como en nuestro módem hidroacústico más simple , con la única diferencia de que lo puse en una clase separada FsBy4CarrierDetector para un cambio.
Toda la magia sin complicaciones ocurre en el método bool ProcessSample (breve a)

 public bool ProcessSample(short a) { bool result = false; if (smpCount == 0) { ring1[ringHead] = a; ring2[ringHead] = a; s1 += a - ring1[ringTail]; s2 += a - ring2[ringTail]; } else if (smpCount == 1) { ring1[ringHead] = a; ring2[ringHead] = -a; s1 += a - ring1[ringTail]; s2 += - a - ring2[ringTail]; } else if (smpCount == 2) { ring1[ringHead] = -a; ring2[ringHead] = -a; s1 += -a - ring1[ringTail]; s2 += -a - ring2[ringTail]; } else if (smpCount == 3) { ring1[ringHead] = -a; ring2[ringHead] = a; s1 += -a - ring1[ringTail]; s2 += a - ring2[ringTail]; } ringHead = (ringHead + 1) % ringSize; ringTail = (ringTail + 1) % ringSize; if (++smpCount >= 4) { smpCount = 0; if (++cycle >= ringSize) { s = Math.Sqrt(s1 * s1 + s2 * s2) / ringSize; cycle = 0; result = (s - sPrev) >= Threshold; sPrev = s; } } return result; } 


Se llama en cada muestra entrante y devuelve verdadero en caso de detección de portadora.

Como el detector está lejos de ser perfecto y se puede sincronizar fácilmente en el medio de la línea, agregué un control deslizante especial, moviéndolo para que pueda lograr una sincronización más precisa.

Ahora, después de haber examinado brevemente cómo funciona todo esto, pasemos a la parte más deliciosa: lo que se puede obtener de todo esto.

Un poco de practica


Primero, verifiquemos cómo funciona todo sin un canal de sonda, simplemente conectando las antenas de recepción y transmisión entre sí.
Primero, la imagen es más grande (240x120) para que al menos se pueda ver algo:


Y luego rápidamente, para que haya más vida más como un video:


Parece que no está mal? Pero no se apresure a sacar conclusiones, y vaya a la piscina:


Y aquí, como prometí en el título, veremos un eco con nuestros propios ojos:


¿ Qué te parece eso, Elon Musk? ¿Te gusta la HD? ¿Por qué es esto así?
Y todo es muy simple: el eco, de hecho, son las copias retrasadas de la señal original, que interfieren con ella en el punto de recepción, se pliegan en una fase diferente y dan esa imagen. Como transferimos la imagen, al final obtenemos muchas imágenes superpuestas entre sí con diferentes amplitudes. Todo esto finalmente conduce a la falta de definición y reproducción.

Mirando hacia atrás, verifiquemos todo en la imagen grande del modelo. Tomé una foto al azar:


Lo modulé, luego agregué un eco y un poco de ruido, luego lo decodifiqué y sí, el resultado se parece a lo que obtuvimos en el grupo:


En principio, es posible llevar a cabo la desconvolución y restar reflexiones, pero dejemos que las personas de fuera de nuestra área dejen este punto para un trabajo independiente.

Por cierto, el método anterior en el grupo funciona un poco mejor, pero también mal: en las señales de banda ancha, la trayectoria múltiple y la reverberación conducen a un desvanecimiento selectivo de frecuencia, que en la imagen (leída en el espectro) se ve como rayas en blanco y negro, donde la señal está en antifase, y donde se desarrolló en fase (de hecho, todavía hay un montón de opciones intermedias):


En abril, aprovechamos el momento y fuimos al estanque con una maqueta de pan y nos mimamos allí también:




El resultado no es muy diferente de los resultados obtenidos en el grupo:




E inmediatamente para comparación, el método anterior:


Y aquí están las animaciones gif recopiladas de los cuadros guardados, método 1:


Y el método 2, que discutimos en este artículo:


En conclusión


Como prometimos, mostramos cómo el eco y la reverberación se ven literalmente, pasamos tiempo con beneficio e hicimos algo con nuestras manos.

En esta forma, por supuesto, el método no es aplicable en la práctica, pero trabajar con él será muy útil para los principiantes.

En general, verificamos en un estanque poco profundo, donde las condiciones son muy desfavorables, y sería genial si alguien repitiera nuestros experimentos en otros embalses y ciertamente informara sobre sus resultados.

Si el lector solo quiere probar (incluso en el aire con un micrófono y altavoces), aquí están los enlaces a los lanzamientos:
Método 1
Método 2 (de este artículo)

PS

Realmente esperamos comentarios de los lectores, ya que es muy importante entender que está haciendo algo en vano (o en vano, y luego esto debe detenerse de inmediato).

PS / 2

Contestaré una pregunta común de inmediato: para los peces y otras especies marinas en esas instalaciones infantiles, todo esto es imperceptible.

Source: https://habr.com/ru/post/453678/


All Articles