Sesi transmisi video suara melalui air dengan pencahayaan

“Tuhan Yang Mahakuasa! Sepertinya saya baru saja membunuh Tn. May! ... Tapi bagaimanapun juga, kita lanjutkan ”(C) J. Clarkson

Pada artikel ini, saya akan memberi tahu Anda cara mentransfer video (well, hampir video) menggunakan suara melalui air menggunakan laptop biasa, sepotong kawat, dua jack 3,5 mm dan dua piezo tweeter. Saya juga akan menjelaskan mengapa dan bagaimana cara kerjanya, menceritakan sebuah kisah lucu tentang bagaimana kami menemukan ini. Dan sebagai ceri pada kue, artikel tentang C # dengan kode sumber dilampirkan ke artikel sehingga setiap orang yang tertarik dapat mencobanya sendiri, karena pengetahuan ilmiah dapat diverifikasi, bukan?

Jika tiba-tiba pembaca ingin menyelam lebih dalam ke topik hidroakustik, saya sarankan Anda membiasakan diri dengan publikasi kami sebelumnya, di mana kami berbicara tentang proyek kami dengan cara mengungkapkan kesulitan dalam mengirimkan informasi melalui air:

GPS bawah laut dari awal per tahun
GPS bawah air: lanjutan
Navigasi di bawah air: arahan temuan - jangan arahan menemukan, Anda ditakdirkan untuk sukses
Tentang efek cyanobacteria pada fungsi pidato presiden

Secara umum, satu kebenaran sederhana harus dipelajari: video melalui air pada jarak yang signifikan (well, setidaknya ratusan meter) tidak dapat ditransmisikan menggunakan akustik. Intinya adalah pita frekuensi yang tersedia sangat sempit dan ketidakseimbangan yang kuat dari pelemahan frekuensi yang berbeda dengan jarak. Kelebihannya adalah noise, propagasi multipath, gema, perubahan dalam kecepatan suara dalam medium dari kepadatan (mis., Tekanan, suhu dan salinitas), efek Doppler, yang notabene tidak bekerja seperti di komunikasi radio.

Batas kecepatan untuk modem sonar tercanggih sangat jauh dari kemampuan untuk mengirimkan video. Sejauh yang saya tahu, catatan itu milik EvoLogics dan berjumlah 62,5 kbps dengan jarak maksimum yang dinyatakan 300 meter. Selain itu, kata-kata tentang ketidakmungkinan mentransmisikan suara video melalui air (pada jarak yang masuk akal) hanya milik Konstantin Georgievich, pendiri dan direktur EvoLogics.

Ketika saya adalah seorang peneliti di Hydrosvyaz Research Institute, yang saat itu benar-benar tidak sadar, saya menginginkan pencapaian besar, kemenangan di utara dan selatan, pelonggaran tanah yang besar (tidak, saya masih menginginkannya, tetapi kemudian saya sama sekali tidak dibebani dengan pengalaman dan pengetahuan dan semuanya tampak hampir ajaib dan menakjubkan). Di tim kami pada waktu itu (sebagian adalah yang asli saya), kami sering berfantasi tentang beberapa proyek sonar yang tidak realistis, mengaduk-aduk di tempat pembuangan sampah dan mencoba menggunakan segala macam artefak dari peradaban kuno yang besar secara berurutan, di mana lembaga penelitian ini sebagian mencoba memahami tao komunikasi sonar .

Perendaman dalam ingatan itu membangkitkan perasaan yang saling bertentangan dalam diri saya. Kemudian tidak ada yang tampak dan tidak ada yang bisa menghentikan kami: kami merobohkan sebuah mesin penggilingan Cina dari direktur untuk pembuatan prototipe produk, mengumpulkan badan normobarik dari pipa air Belanda Van De Lande, produsen yang bahkan menulis surat pada subjek: "Apakah Anda secara tidak sengaja memeriksa yang mana apakah pipa Anda tahan terhadap tekanan eksternal? " Mereka mengumpulkan model papan tempat memotong roti untuk uang mereka sendiri dalam wadah sarapan dan diam-diam pergi ke tes untuk menguji mereka secara diam-diam, mengumpulkan latihan es dan kereta luncur untuk rekan dan kerabat, dan bahkan membeli kapal PVC Cina di Auchan. Melihat ke belakang, saya merasakan bagaimana hati saya dipenuhi dengan kengerian, nostalgia dan gentar.

Dalam keadilan, perlu dicatat bahwa selama ini kami menerima dukungan besar dari beberapa pemimpin kami - dalam kata-kata dan perbuatan, dan sebagai hasilnya semua kerajinan kami dilegalkan dalam OCD (yang berarti Pekerjaan Desain Eksperimental dan bukan Obsesif Compulsive Disorder), yang bahkan disajikan di salon angkatan laut internasional pada 2013. Ya, ya, kami pergi ke salon pipa air kami, dicat StDmitirev di tangan kami sendiri dengan warna oranye terang! Inilah mereka, di dalam koper:



Suatu hari, teman dan kolega saya StDmitirev, di tengah-tengah pembicaraan tentang spektra dan spektogram, mengucapkan kalimat berikut:

"Tapi, akan menyenangkan untuk membuat sistem seperti itu: kapal selam itu duduk di dalam kapal selam dan melihat ke monitor, tempat spektogram bergerak dengan lancar, di mana huruf dan angka ditulis seperti jari kapal selam lain di jendela berkabut di kapal selam lain ."

Semua orang tertawa, mengembangkan topik ini, tampaknya bahkan pada hari yang sama mereka menggambar sebuah senyuman di spektogram dan mendengarkan bagaimana suaranya. Saya benar-benar ingin membawa ini ke tampilan praktis.

Sekarang sulit untuk diingat (kembali pada tahun 2012). Saya memiliki komputer yang berfungsi dengan webcam, berbagai artefak-antena dan “bucket sonar boosting” khusus (VG-1-P) dengan air. Mereka memanggilnya sebagai langkah maju karena fakta bahwa saya memperlihatkan kepada semua bosnya pekerjaan model-model peralatan berbeda di dalamnya, yang menyebabkan promosi saya menjadi peneliti senior.

Saya tidak dibatasi oleh kewajiban apa pun, metode itu sendiri telah lama diterbitkan dalam domain publik, dan hasilnya telah berulang kali dilaporkan di konferensi.

Jadi, saya memberi tahu Anda bagaimana dalam semangat - cara mengirimkan video melalui air:

Bagaimana cara menghasilkan sinyal?


Kita ingat bahwa idenya didasarkan pada "menggambar pada spektogram," yaitu, gambar yang ditransmisikan adalah spektrogram sinyal. Untuk mengonversi sinyal dari domain waktu ke domain frekuensi dan sebaliknya, lebih mudah menggunakan (well, misalnya) transformasi Fourier, atau lebih tepatnya, transformasi Fourier cepat, untuk singkatnya, yang disebut FFT atau, lebih umum, FFT (Fast Fourier Transform).

Karena kita perlu mengubah gambar (bingkai video) menjadi sinyal audio yang dapat dipancarkan oleh kartu suara dari komputer mana pun, kita jelas akan menggunakan transformasi terbalik, IFFT, untuk membentuknya. Kami akan memancarkan gambar dalam kolom, dan sinyal untuk satu kolom akan dibentuk seperti pada diagram berikut:


=
Misalkan ukuran jendela FFT adalah N dan kami memiliki array ukuran N. Jika kami menganggapnya sebagai spektrum sinyal, maka elemen nolnya sesuai dengan frekuensi nol (konstan), dan penghitungan dengan indeks N-1 sesuai dengan frekuensi pengambilan sampel Sample Rate. Penting untuk memilih ukuran bingkai gambar dan ukuran jendela FFT sehingga di satu sisi semuanya menyerupai video (mentransfer satu frame akan membutuhkan waktu yang wajar), dan di sisi lain, pita frekuensi yang digunakan pada prinsipnya memadai dan memadai untuk peralatan yang tersedia. . Sekarang, jika kita memasukkan nilai kecerahan kolom gambar (Frame kolom) dari beberapa hitungan favorit (dari bawah ke atas dalam diagram), dan kemudian melakukan FFT terbalik, maka output akan menerima sinyal yang mengkodekan satu kolom gambar. Sekarang tinggal kita untuk membentuk sinyal dengan cara yang sama untuk kolom gambar yang tersisa dan memancarkannya secara bergantian menggunakan kartu suara.

Perlu dicatat bahwa FFT pada output memberikan array nilai kompleks, jadi sinyal kami adalah bagian yang sebenarnya. Tentu saja, sinyal yang dihasilkan dalam kolom dikurangi menjadi bilangan bulat bertanda 16-bit (dalam bentuk ini, sinyal audio digital biasanya disimpan) dan dinormalisasi.

Bahkan, pada awal gambar saya juga memasukkan beberapa kolom kecerahan maksimum, kemudian di sisi penerima ini akan menentukan respon frekuensi jalur transceiver (dan saluran transmisi), yang, ketika terbalik dan sedikit dihaluskan, akan membantu kami meningkatkan frame yang diterima.

Menurut pendapat saya, cara termudah untuk menunjukkan perangkat pemancar adalah dengan sepotong kode, ini dia (metode Encode kelas 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; } 

Kode, tentu saja, tidak berpura-pura apa pun dan ditulis terburu-buru murni untuk demonstrasi.

Lalu bagaimana dengan kecepatan transmisi?


Dan bagaimana cara mengevaluasinya? Kami berhasil ( dari kejahatan bukan dari kejahatan) untuk mempertahankan intrik selama sekitar dua bulan, dan beberapa kawan dan pemimpin senior kami berhasil menulis banyak kertas di waktu luang mereka, bertanya-tanya bagaimana kecepatan transmisi gila seperti itu bisa terjadi.

Misalnya, jika frekuensi sampling 96 kHz, dan kami mengambil ukuran jendela FFT menjadi 512, kami akan mengirim 120 x 120 piksel (8 bit per piksel) ke input pemancar, maka waktu yang diperlukan untuk mengirim satu bingkai gambar adalah:

120 * 512/96000 = 0,64 detik

Bit rate tampaknya:

120x120 * 8 / 0.64 = 180.000 bit per detik!

Putra direktur senang pada saat itu - ya, Anda sudah dapat menggunakan protokol internet! Ini adalah terobosan!

Seperti yang akan saya tunjukkan di bawah ini, sangat mudah untuk jatuh ke dalam kesalahpahaman seperti itu. Apa yang salah di sini? Bagaimanapun, semuanya sangat sederhana dan elegan!

Bahkan, perhitungan kecepatan seperti itu tidak berlaku untuk metode ini, sama seperti, misalnya, itu tidak berlaku untuk sinyal televisi analog, berapa banyak bit per piksel yang ada? =) Dan bagaimana dengan penerima detektor yang paling sederhana? =))

Metode transmisi yang dijelaskan pada dasarnya adalah ANALOG dan konsep "bit" dan "pixel" tidak berlaku untuk itu - dalam gambar yang sama, secara teoritis, Anda dapat mengambil bukan 8 bit per kecerahan pixel tetapi 16 dan "kecepatan" secara otomatis akan berlipat ganda.

Saatnya untuk menunjukkan hasil pertama dari "terobosan" kami:



Gambar di atas diambil oleh kami pada musim dingin 2012 di Sungai Pichuga. Jarak transmisi adalah 700 meter. Ya, sayang, pembaca yang budiman, ini sama sekali bukan HD dan bahkan tidak menggunakan CamRip yang paling memalukan. Saya tidak ingat siapa yang sudah, tetapi seseorang dengan sangat akurat memperhatikan bahwa semua "video" kami seperti mengirim sinyal bantuan dari planet yang sedang sekarat.

Yang perlu diperhatikan, dengan peregangan ini dapat digambarkan sebagai semacam OFDM - data ditransmisikan pada subcarrier ortogonal, yang berarti ketahanan yang baik terhadap tonal dan interferensi pita sempit lainnya - dalam hal ini, "garis" gambar terdistorsi. Kebisingan impuls, sebaliknya, mendistorsi satu atau sekelompok kolom. Karakteristik "banding" dari gambar-gambar tersebut disebabkan oleh apa yang disebut frekuensi selektif memudar karena propagasi multipas, tetapi saya akan membicarakannya lain kali.

Bagaimana pengaturan penerima?


Saya harus segera memesan bahwa untuk mencoba metode ini dalam ember atau bahkan di kolam kecil, potongan dua jam (yang bundar) dengan konektor untuk kartu suara yang disolder kepada mereka sudah cukup. Untuk pemancar, Anda dapat mengambil kabel yang cukup panjang (2-3-4-5 meter) dan tidak terlindung, menyegel elemen piezoelektrik dengan zapon-varnish atau lapisan kecil sealant - sudah pasti cukup untuk beberapa kali. Antena sonar yang dihasilkan (tidak, baik, apa?) Dimasukkan ke jack headphone.

Foto di bawah ini menunjukkan berbagai bagian yang ada pada saat penulisan. Semua elemen piezoelektrik yang ditampilkan cukup cocok untuk "mencoba" dan biasanya ada toko radio di tempat pembuangan sampah . Pyatak tidak memiliki efek piezoelektrik dan hadir dalam gambar untuk skala.



Untuk penerima, lebih baik mengambil kabel mikrofon berpelindung dengan konektor yang sama dan piezo dioleskan dengan sealant atau pernis di ujungnya. Kami memasukkan antena ini ke jack mikrofon.

Untuk percobaan di kolam, lebih baik mengambil beberapa jenis cincin piezo sebagai pemancar dan memberinya makan yang diperkuat (penguat pada TDA2030 dengan transformator luka yang benar akan bertahan beberapa ratus meter di kolam yang baik atau 5 putaran lainnya bisa terluka). Untuk penerima, dalam hal ini, preamplifier dan lebih disukai filter bandpass juga diperlukan. Jika pembaca akan tertarik untuk mempelajari lebih lanjut tentang ini secara rinci, beri tahu kami di komentar dan kami akan mencoba membuat artikel tentang penciptaan penguat daya, preamp, dan antena untuk komunikasi sonar.

Jadi, kembali ke penerima, lebih tepatnya ke bagian perangkat lunaknya


Hal terpenting dalam komunikasi adalah sinkronisasi dan penentuan keberadaan sinyal yang bermanfaat. Dalam contoh kami, deteksi dilakukan oleh energi di pita: tempat di mana ia meningkat tajam (awal bingkai) dan di mana ia jatuh tajam (ujung bingkai) ditentukan, dengan kondisi bahwa dari depan ke jatuh harus ada setidaknya durasi bingkai.

Untuk semua kesederhanaannya, ini bekerja dengan sangat baik.

Data dari kartu suara dikumpulkan oleh sampel FFTSize, FFT dilakukan segera pada mereka dan mereka disimpan sebagai "irisan" yang terpisah, menunggu saat ketika mereka akan diproses oleh prosedur pencarian, berikut adalah kodenya (Metode pencarian di kelas Penerima):

 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); } 

Dan ini adalah bagian dari kode yang bertanggung jawab untuk mendekode gambar (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"); } } 

Dan sekarang saya mengusulkan untuk melihat hasil percobaan pada transmisi "video", yang dilakukan pada waktu yang berbeda di reservoir yang berbeda.

Kedua gambar (di bawah) direkam di salon angkatan laut internasional di St. Petersburg pada tahun 2013 di stand (lalu) kami melalui dua laptop dan akuarium.

Tidak mungkin untuk mengetahui apa yang tertulis di lencana





Dan berikut adalah dua "video" yang direkam oleh kami di salah satu teluk Danau Ladoga di Karelia, mereka adalah semacam rekaman untuk metode ini (kami tidak pernah mencobanya lagi dan tidak mungkin) - yang pertama diperoleh pada jarak 500 dan yang kedua sebanyak 1000 meter :

Transmisi video melalui air, jarak 500 m (file 8,7 mb)



Karena "video" direkam secara real time menggunakan webcam, berbagai hal aneh jatuh ke dalam bingkai. Akan sangat menarik jika seseorang menebak dan menulis dalam komentar apa yang ada di latar belakang dalam "video" terakhir).

Untuk mendukung fakta bahwa metode ini telah dipublikasikan sejak lama - artikel kami sudah untuk tahun 2013

Saya menggunakan perpustakaan AForge yang indah untuk mengambil gambar webcam .

Nomor kompleks dan fungsi FFT digunakan dari pustaka AlgLib yang sangat baik.

Dan, seperti yang saya janjikan, seluruh proyek dalam C # (VS2012) dilampirkan pada artikel sebagai bahan untuk pekerjaan "rumah". Untuk kenyamanan, proyek dan file biner terpisah.
Demo ini menyediakan kemampuan untuk mengubah (memindahkan) pita frekuensi yang ditempati serta koreksi gamma dari kerangka output (semuanya dapat diubah secara real time).

PS


Saya belum mengambil C # untuk waktu yang lama dan sangat sulit untuk menemukan waktu dalam jadwal kerja, jadi saya minta maaf sebelumnya untuk kebingungan dan tergesa-gesa kode.

PPS


Saya tidak melampirkan sepotong kawat, dua jack dan dua potong untuk artikel - tidak cukup untuk semua orang.

Errata dan Apendiks


- Dalam beberapa kartu suara pada input terdapat filter low-pass yang secara tragis memotong semuanya di atas ~ 15 kHz (mengapa ???).

- Secara default, proyek demo berfungsi dengan frekuensi sampling 96 kHz, tetapi tidak semua kartu suara modern mendukungnya (Mengapa ???). Jika peralatan tidak dapat 96 kHz maka Anda perlu mengatur 48 kHz dalam pengaturan, jika tidak, maka 44100 tentu didukung di mana-mana, namun, durasi transmisi satu frame akan lebih lama.

Berikut adalah daftar laptop dan kartu suara yang dapat dianggap sebagai peralatan sonar muda:

  • Lenovo ideapad Y510P dengan suara JBL
  • Asus n55s
  • Asus K501U
  • kartu suara eksternal Sound Blaster X-Fi Surround 5.1 (model no. SB 1095)

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


All Articles