Sessão de transmissão de vídeo de som através da água com exposição

O Senhor Todo-Poderoso! Parece que acabei de matar o Sr. May! ... Mas, seja como for, continuamos ”(C) J. Clarkson

Neste artigo, mostrarei como transferir vídeo (bem, quase vídeo) usando o som através da água, usando um laptop comum, um pedaço de fio, duas tomadas de 3,5 mm e dois piezo-tweeter. Também vou explicar por que e como funciona, contar uma história engraçada sobre como chegamos a isso. E como uma cereja no bolo, um artigo em C # com códigos-fonte é anexado ao artigo, para que todos os interessados ​​possam experimentá-lo, porque o conhecimento científico é verificável, não é?

Se de repente o leitor quiser se aprofundar um pouco nos tópicos hidroacústicos, sugiro que você se familiarize com nossas publicações anteriores, nas quais falamos sobre nossos projetos de uma maneira que revela as dificuldades de transmitir informações pela água:

GPS subaquático do zero por ano
GPS subaquático: continuação
Navegação debaixo d'água: descoberta de direção - não descoberta de direção, você está fadado ao sucesso
Sobre o efeito das cianobactérias nas funções de fala do presidente

Em geral, uma simples verdade deve ser aprendida: o vídeo através da água a uma distância significativa (bem, pelo menos centenas de metros) não pode ser transmitido usando acústica. O ponto é a banda de frequência disponível extremamente estreita e a forte irregularidade da atenuação de diferentes frequências com a distância. As vantagens são ruído, propagação de caminhos múltiplos, reverberação, mudança na velocidade do som no meio em relação à densidade (ou seja, pressão, temperatura e salinidade), o efeito Doppler, que aliás não funciona exatamente como nas radiocomunicações.

Os limites de velocidade para os modems de sonar mais avançados estão muito longe de poder transmitir vídeo. Até onde eu sei, o registro pertence ao EvoLogics e atinge 62,5 kbps com uma distância máxima declarada de 300 metros. Além disso, as palavras sobre a impossibilidade de transmitir som de vídeo através da água (a distâncias razoáveis) pertencem apenas a Konstantin Georgievich, fundador e diretor da EvoLogics.

Quando eu era pesquisador no Instituto de Pesquisa Hydrosvyaz, então completamente inconsciente, queria grandes realizações, vitórias no norte e sul, grande afrouxamento de solos (não, eu ainda os quero, mas não fiquei sobrecarregado com experiência e conhecimento e tudo parecia quase mágico e fabuloso). Em nossa equipe da época (parte da qual é real), muitas vezes fantasiamos sobre alguns projetos de sonares irreais, vasculhávamos um aterro e tentamos usar todo tipo de artefato de uma grande civilização antiga consecutiva, da qual esse instituto de pesquisa está parcialmente tentando compreender o tao da comunicação do sonar. .

A imersão nessas memórias evoca sentimentos conflitantes em mim. Então nada pareceu e ninguém poderia nos parar: derrubamos uma fresadora chinesa do diretor de prototipagem de produtos, montamos corpos normobáricos de tubulações de água holandesas Van De Lande, cujo fabricante até escreveu uma carta sobre o assunto: “Você checou acidentalmente quais seus tubos suportam pressão externa? ” Eles coletaram modelos de tábua de pão para o seu próprio dinheiro em recipientes de café da manhã e foram secretamente ao teste para testá-los secretamente, coletando brocas e trenós para colegas e parentes e até compraram um barco chinês de PVC em Auchan. Olhando para trás, sinto como meu coração está cheio de horror, nostalgia e ansiedade.

Para ser honesto, vale a pena notar que, durante todo esse tempo, recebemos grande apoio de alguns de nossos líderes - em palavras e ações, e, como resultado, todos os nossos ofícios foram legalizados no TOC (que significa trabalho experimental de design e não transtorno obsessivo-compulsivo), que foi ainda apresentado no salão naval internacional em 2013. Sim, sim, nós dirigimos para o salão nossos canos de água, pintamos StDmitirev em nossas próprias mãos em laranja brilhante! Aqui estão eles, em malas:



Um dia, meu amigo e colega StDmitirev, no meio de uma conversa sobre espectros e espectrogramas, pronunciou a seguinte frase:

"Mas, seria divertido criar um sistema desse tipo: o submarino fica no submarino e olha para o monitor, no qual o espectrograma se move suavemente, no qual letras e números são escritos como o dedo de outro submarino na janela de outro submarino ".

Todo mundo riu, desenvolveu esse tópico, parece que, mesmo no mesmo dia, desenhou um smiley no espectrograma e ouviu como ele soa. Eu realmente queria trazer isso para uma aparência prática.

Agora é difícil lembrar (foi em 2012). Eu tinha um computador em funcionamento com uma webcam, várias antenas de artefatos e um “sonar de balde” (VG-1-P) especial com água. Eles o chamaram de intensificador devido ao fato de eu ter mostrado a todos os seus chefes o trabalho de diferentes modelos de equipamento, o que levou a minha promoção a um pesquisador sênior.

Não sou limitado por nenhuma obrigação, o método em si já foi publicado em domínio público e os resultados foram relatados repetidamente em conferências.

Estou lhe dizendo como, em espírito, como transmitir um vídeo pela água:

Como gerar um sinal?


Lembramos que a idéia é baseada no “desenho de um espectrograma”, ou seja, a imagem transmitida é o espectrograma do sinal. Para converter um sinal do domínio do tempo no domínio da frequência e vice-versa, é conveniente usar (bem, por exemplo) a transformada de Fourier, ou melhor, a transformada rápida de Fourier, por uma questão de brevidade, chamada FFT ou, mais comumente, FFT (Fast Fourier Transform).

Como precisamos transformar uma imagem (quadro de vídeo) em um sinal de áudio que possa ser emitido pela placa de som de qualquer computador, obviamente usaremos a transformação inversa, IFFT, para formar a imagem. Emitiremos uma imagem em colunas e um sinal para uma coluna será formado como no diagrama a seguir:


=
Suponha que o tamanho da janela da FFT seja N e tenhamos uma matriz de tamanho N. Se o considerarmos como o espectro do sinal, seu elemento zero corresponderá à frequência zero (constante) e a contagem com o índice N-1 corresponderá à frequência de amostragem da taxa de amostragem. É necessário escolher esses tamanhos de quadro de imagem e tamanho da janela FFT para que, por um lado, tudo se assemelhe ao vídeo (transferir um quadro levaria um tempo razoável) e, por outro lado, a faixa de frequência usada era adequada em princípio e adequada ao equipamento disponível . Agora, se inserirmos os valores de brilho da coluna da imagem (quantidade de quadros) de alguma contagem favorita (de baixo para cima no diagrama) e executar a FFT inversa, a saída receberá um sinal codificando uma coluna da imagem. Agora cabe a nós formar os sinais da mesma maneira para as colunas restantes da imagem e emiti-los alternadamente usando uma placa de som.

Vale notar que a FFT na saída fornece uma matriz de valores complexos, portanto nosso sinal é a parte real. Obviamente, o sinal resultante nas colunas é reduzido para números inteiros assinados de 16 bits (nesta forma, um sinal de áudio digital é geralmente armazenado) e normalizado.

De fato, no início da imagem, também insiro algumas colunas de brilho máximo; mais tarde, no lado do receptor, isso determinará a resposta de freqüência do caminho do transceptor (e canal de transmissão), que, quando invertido e suavizado, nos ajudará a melhorar o quadro recebido.

Na minha opinião, a maneira mais fácil de demonstrar o dispositivo do transmissor é com um pedaço de código, aqui está (método Encode da classe Encoder):

public double[] Encode(Bitmap source) { 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); double[] samples = new double[fftSize * frameSize.Width]; alglib.complex[] slice = new alglib.complex[fftSize]; double maxSlice; int sampleIndex = 0; int colsCount = frameSize.Width; int startRow = startLine; int endRow = startRow + frameSize.Height; for (int x = 0; x < colsCount; x++) { for (int y = startRow; y < endRow; y++) slice[y].x = (frame.GetPixel(x, frameSize.Height - (y - startRow) - 1).R / 255.0) * short.MaxValue; for (int y = 0; y < fftSize; y++) slice[y].x *= randomizerMask[y]; alglib.fftc1dinv(ref slice); maxSlice = double.MinValue; for (int y = 0; y < slice.Length; y++) if (Math.Abs(slice[y].x) > maxSlice) maxSlice = Math.Abs(slice[y].x); for (int i = 0; i < slice.Length; i++) { samples[sampleIndex] = (short)Math.Round(slice[i].x * short.MaxValue / maxSlice); sampleIndex++; } } return samples; } 

O código, naturalmente, não finge nada e foi escrito com pressa puramente para demonstração.

E quanto à velocidade de transmissão?


E como avaliá-lo? Conseguimos ( do mal, não do mal) manter a intriga por cerca de dois meses, e alguns de nossos camaradas e líderes seniores em seu tempo livre conseguiram escrever um monte de papel, imaginando como seria uma velocidade de transferência tão louca.

Por exemplo, se a frequência de amostragem for 96 kHz e levarmos o tamanho da janela da FFT para 512, enviaremos 120 x 120 pixels (8 bits por pixel) para a entrada do transmissor, e o tempo necessário para transmitir um quadro de imagem é:

120 * 512/96000 = 0,64 segundos

A taxa de bits deve parecer:

120x120 * 8 / 0,64 = 180.000 bits por segundo!

O filho do diretor ficou encantado na época - sim, você já pode usar protocolos da Internet! Esta é uma inovação!

Como mostrarei abaixo, é muito fácil cair em um conceito tão errado. O que há de errado aqui? Afinal, tudo é tão simples e elegante!

De fato, esse cálculo de velocidade não é aplicável a esse método, assim como, por exemplo, não é aplicável a um sinal de televisão analógica, quantos bits por pixel existem? =) E o receptor detector mais simples? =))

O método de transmissão descrito é essencialmente ANALOGUE e os conceitos de "bit" e "pixel" não são aplicáveis ​​a ele - na mesma imagem, teoricamente, você não pode receber 8 bits por brilho de pixel, mas 16 e "velocidade" dobram automaticamente.

É hora de mostrar os primeiros resultados de nossa "inovação":



A foto acima foi tirada por nós no inverno de 2012, no rio Pichuga. A distância de transmissão foi de 700 metros. Sim, infelizmente, meu caro leitor, isso não é nada de HD e nem se baseia no CamRip mais vergonhoso. Ainda não lembro quem, mas alguém notou com precisão que todos os nossos "vídeos" são como enviar sinais de ajuda de um planeta moribundo.

O que é digno de nota, com um alongamento, isso pode ser caracterizado como uma espécie de OFDM - os dados são transmitidos em subportadoras ortogonais, o que significa boa resistência a interferências tonais e outras faixas estreitas - nesse caso, "linhas" individuais da imagem são distorcidas. O ruído de impulso, pelo contrário, distorce uma ou um grupo de colunas. A característica "formação de faixas" das imagens é causada pelo chamado desbotamento seletivo da frequência devido à propagação de caminhos múltiplos, mas falarei sobre isso em outro momento.

Como é organizado o receptor?


Farei uma reserva imediatamente de que, para tentar esse método em um balde ou mesmo em uma pequena piscina, serão suficientes peças de duas horas (como as redondas) com um conector para uma placa de som soldada a elas. Para o transmissor, você pode usar um cabo bastante longo (2-3-4-5 metros) e não blindado, selando o elemento piezoelétrico com zapon-verniz ou uma pequena camada de selante - o suficiente por várias vezes. A antena do sonar resultante (não, bem, o que?) É inserida no fone de ouvido.

A foto abaixo mostra várias peças que estavam à mão no momento da escrita. Todos os elementos piezoelétricos mostrados são bastante adequados para "tentar" e geralmente há uma loja de rádio em qualquer depósito de lixo . Pyatak não tem um efeito piezoelétrico e está presente na imagem para escala.



Para o receptor, é melhor usar um cabo de microfone blindado com o mesmo conector e um piezo manchado com selante ou verniz no final. Nós inserimos esta antena na tomada do microfone.

Para experimentos em uma lagoa, é melhor pegar algum tipo de anel piezo como transmissor e alimentá-lo com um amplificado (um amplificador em um TDA2030 com um transformador enrolado corretamente vai durar várias centenas de metros em uma boa lagoa ou outras 5 voltas podem ser enroladas). Para o receptor, neste caso, também é necessário um pré-amplificador e, de preferência, um filtro passa-banda. Se os leitores estiverem interessados ​​em aprender mais sobre isso em detalhes, conte-nos nos comentários e tentaremos criar um artigo sobre a criação de amplificadores de potência, pré-amplificadores e antenas para comunicação por sonar.

Então, voltando ao receptor, mais precisamente à parte do software


O mais importante na comunicação é a sincronização e a determinação da presença de um sinal útil. No nosso exemplo, a detecção é realizada pela energia na banda: são determinados locais onde aumenta acentuadamente (o início do quadro) e onde cai acentuadamente (o final do quadro), com a condição de que da frente para a queda deva haver pelo menos a duração do quadro.

Por toda a sua simplicidade, funciona surpreendentemente bem.

Os dados da placa de som são coletados de acordo com as amostras do FFTSize, a FFT é executada imediatamente sobre elas e são armazenadas como “fatias” separadas, aguardando o momento em que serão processadas pelo procedimento de busca, e aqui está o código (método de busca na classe Receiver):

 private void Search() { int sliceIndex = 0; int frameWidth = encoder.FrameSize.Width; int minSlicesToSearch = Convert.ToInt32((frameWidth + 5) * 2); int sliceSize = encoder.FFTSize; double weight; int lastRisePosition = 0; int prevRisePosition = 0; while ((slices.Count > minSlicesToSearch) && (sliceIndex < slices.Count)) { weight = 0.0; for (int i = 0; i < sliceSize; i++) weight += Math.Abs(slices[sliceIndex][i]); double ratio = weight / previousWeight; if ((ratio >= risePeekRatio) && (sliceIndex - prevRisePosition > frameWidth)) { prevRisePosition = lastRisePosition; lastRisePosition = sliceIndex; if (lastRisePosition + (frameWidth + 5) < slices.Count) { double[][] samples = new double[frameWidth + 5][]; for (int i = 0; i < frameWidth + 5; i++) { samples[i] = new double[sliceSize]; Array.Copy(slices[lastRisePosition + i], samples[i], sliceSize); } slices.RemoveRange(0, sliceIndex); lastRisePosition = 0; if (FrameReceived != null) FrameReceived(this, new FrameReceivedEventArgs(encoder.DecodeEx(samples, 5))); lastRisePosition = sliceIndex; } } sliceIndex++; previousWeight = weight; } Interlocked.Decrement(ref isSearching); } 

E aqui está um pedaço de código responsável pela decodificação da imagem (Encoder.DecodeEx):

 public Bitmap Decode(double[] samples, int measureCols) { int colCount = samples.Length / fftSize; if (colCount == frameSize.Width + measureCols) { int rowCount = frameSize.Height; Bitmap temp = new Bitmap(colCount, rowCount); double[] slice = new double[fftSize]; alglib.complex[] sliceC = new alglib.complex[fftSize]; int samplesCount = 0; byte component; int decodeStart = startLine; int decodeEnd = startLine + rowCount; double maxSlice; for (int x = 0; x < colCount; x++) { for (int y = 0; y < fftSize; y++) { slice[y] = samples[samplesCount]; samplesCount++; } alglib.fftr1d(slice, out sliceC); maxSlice = double.MinValue; for (int y = decodeStart; y < decodeEnd; y++) if (alglib.math.abscomplex(sliceC[y].x) > maxSlice) maxSlice = alglib.math.abscomplex(sliceC[y].x); int offset = temp.Height + decodeStart - 1; for (int y = decodeStart; y < decodeEnd; y++) { component = (byte)(255.0 * alglib.math.abscomplex(sliceC[y].x) / maxSlice); temp.SetPixel(x, offset - y, Color.FromArgb(component, component, component)); } } return temp; } else { throw new ApplicationException("Specified array length error"); } } 

E agora proponho olhar os resultados de experimentos sobre a transmissão de "vídeo", realizados em diferentes momentos em diferentes reservatórios.

Ambas as fotos (abaixo) foram gravadas no salão naval internacional de São Petersburgo em 2013 em nosso (então) stand através de dois laptops e um aquário.

Não é possível distinguir o que está escrito no crachá





E aqui estão dois "vídeos" gravados por nós em uma das baías do Lago Ladoga, na Carélia, eles são um tipo de registro para esse método (nunca mais tentamos e é improvável que seja) - o primeiro foi recebido a uma distância de 500 e o segundo a 1.000 metros :

Transmissão de vídeo pela água, distância de 500 m (arquivo 8,7 mb)



Como o "vídeo" foi gravado em tempo real usando uma webcam, várias coisas estranhas caíram no quadro. Será muito interessante se alguém adivinhar e escrever em um comentário o que está em segundo plano no último “vídeo”).

Em apoio ao fato de o método ter sido publicado há muito tempo - nosso artigo já para 2013

Usei a maravilhosa biblioteca AForge para capturar imagens da webcam .

Funções complexas de número e FFT são usadas na excelente biblioteca AlgLib .

E, como prometi, todo o projeto em C # (VS2012) é anexado ao artigo como material para o trabalho "doméstico". Por conveniência, o projeto e os arquivos binários são separados.
A demonstração oferece a capacidade de alterar (mover) a banda de frequência ocupada, bem como a correção de gama do quadro de saída (tudo pode ser alterado em tempo real).

PS


Não uso C # há muito tempo e é muito difícil encontrar tempo no horário de trabalho, então peço desculpas antecipadamente pela confusão e rapidez do código.

PPS


Não prendo um pedaço de arame, dois macacos e dois pedaços ao artigo - não é suficiente para todos.

Erratas e Apêndice


- Em algumas placas de som na entrada, existe um filtro passa-baixo que corta tragicamente tudo acima de ~ 15 kHz (por que ???).

- Por padrão, o projeto demo funciona com uma frequência de amostragem de 96 kHz, mas nem todas as placas de som modernas são compatíveis (Por que ???). Se o equipamento não puder 96 kHz, você precisará definir 48 kHz nas configurações; caso contrário, o 44100 certamente será suportado em todos os lugares; no entanto, a duração da transmissão de um quadro será correspondentemente mais longa.

Aqui está uma lista de laptops e placas de som que podem ser considerados equipamentos de sonar jovem:

  • Lenovo ideapad Y510P com som JBL
  • Asus n55s
  • Asus K501U
  • placa de som externa Sound Blaster X-Fi Surround 5.1 (modelo no. SB 1095)

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


All Articles