Cara melihat gema atau transmisi video dengan suara melalui air - 2

Halo sayang!



Hari ini kita akan mengirimkan gambar dengan ultrasound melalui air: kita benar-benar akan melihat gema dan gema, dan bahkan bagaimana mereka berubah tergantung pada kondisi. Semua yang saya akan katakan kepada Anda sederhana, menarik untuk mengulanginya sendiri dan dapat dilakukan oleh hampir semua orang.

Jika ada sesuatu yang berkobar di jiwa Anda dari kata-kata ini, selamat datang di Kat, ke perairan gelap kolam kami!




"Sisanya yang terbaik adalah menafsirkan kebenaran yang terkenal." (C) ABS, Siang, Abad XXII


Foreplay


Aturan dasar dari klub saksi hidroacoustics adalah bahwa video menggunakan hidroacoustics pada jarak yang lebih atau kurang signifikan (lebih dari beberapa meter) di badan air tengah tidak dapat ditransmisikan, dan akan selalu mustahil.
Ada alasan serius untuk ini - saluran komunikasi dengan bandwidth yang sangat rendah, kecepatan propagasi sinyal yang rendah (dalam air hanya 1.500 m / s) dan probabilitas kesalahan yang tinggi. Pita frekuensi yang tersedia hanya beberapa puluh kilohertz.
Tapi ini tidak semua - jika, secara relatif, sinyal pada frekuensi urutan 10 kHz merambat dalam air pada jarak sekitar 8-10 km, maka pada frekuensi 20 kHz sudah 3-5 km, dan semakin tinggi frekuensinya, semakin kuat pelemahannya . Sebagai contoh, modem uWAVE terkecil kami di dunia beroperasi pada pita 20-30 kHz dan mengirimkan data pada kecepatan 78 bit / detik per 1000 meter, dan RedLINE dengan pita 5-15 hingga 8000 meter. Rekor di antara perangkat komersial milik EvoLogics - 68 kBits per 300 meter.
Fisika, sayangnya, tidak dapat dibohongi dan tidak mungkin untuk menyetujuinya - fisika dapat ditransmisikan dengan sangat lambat dan tidak berisik, atau dengan cepat, tetapi dalam jarak pendek.
Namun, dalam beberapa kasus adalah mungkin untuk "memotong beberapa sudut", sudut mana yang akan kita potong kali ini lebih rendah.

Apa yang akan kita lakukan hari ini dan apa yang dibutuhkan untuk ini?


Dalam artikel sebelumnya, kami sudah mentransmisikan "video" dengan suara melalui air , saya mengingatkan Anda bahwa ada frame "digambar pada spektrum", yaitu spektrum, atau lebih tepatnya spektrogram sinyal adalah gambar.
Kemudian kami membuat antena hidroakustik sederhana dari puing - puing dan membuat modem hidroakustik sederhana . Di sana kami juga membuat preamp untuk antena (desain PCB untuk produksi sendiri oleh LUT-ohm masih ada di sini ).

Kami berpikir, bagaimana lagi Anda dapat mencoba menyampaikan gambar sehingga bahkan seorang siswa TK dapat mengetahuinya, dan seperti yang terlihat bagi kami, mereka datang dengan cara yang bahkan lebih sederhana daripada sebelumnya.

Jadi, untuk meringkas, buatlah daftar apa yang kita butuhkan:

- Sepasang antena sonar dari pemetik pie
- preamplifier diproduksi oleh LUT
- C # kode sumber proyek
- sepasang baterai timbal pada 12 volt
- sebuah penguat pada TDA, saya mengambil satu untuk hanya 50 rubel pada Ali

Sedikit teori


Ingat bahwa modem sonar kami didasarkan pada pendeteksi nada sederhana, yang frekuensinya 4 kali lebih sedikit dari frekuensi pengambilan sampel. Ingat secara singkat cara kerjanya.


Gambar menunjukkan dua osilasi bergeser relatif satu sama lain pada Pi / 2 - yaitu, fase sinus dan kosinus. Dan jika frekuensinya tepat empat kali lebih sedikit dari frekuensi sampling, maka hanya 4 sampel yang jatuh pada periode tersebut.
Habuchitel yang penuh perhatian tentu memperhatikan bahwa kedua sinyal dialihkan ke Pi / 4. Dengan perubahan ini, sinyal hanya mengambil dua nilai: √2 / 2 dan -√2 / 2.
Dan nilai-nilai spesifik bahkan tidak penting, penting bahwa Anda hanya dapat menggunakan tanda-tanda: "+" dan "-".

Sekarang kita dapat mewakili fase sinus sebagai urutan tanda "+" "+" "-" "-", dan fase cosinus sebagai "+" "-" "-" "+".

Di bawah spoiler, ulangi detektor:
Biarkan sinyal input berada di buffer sn, kami memiliki dua buffer cincin rata-rata untuk fase sinus dan cosinus - bs dan bc dengan ukuran N. Mereka memiliki pointer head dan tail yang sama - bH dan bT. Pada saat awal waktu, bH = N-1, bT = 0. Penghitung siklus rata-rata C = 0.
Kami mengambil 4 sampel dari buffer input dan menambahkannya sesuai dengan urutan karakter.

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


Setelah masing-masing memproses empat sampel, kami memeriksa penghitung siklus rata-rata dan jika telah melebihi N, maka kami menghitung amplitudo pembawa cA:

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



Kami menggunakan metode ini sebagai dasar, ini akan bertanggung jawab untuk "sinkronisasi".
Sekarang mari kita lihat bagaimana gambar dikodekan. Saya sarankan menggunakan manipulasi amplitudo . Manipulasi adalah ketika sinyal dibagi menjadi segmen yang sama yang disebut chip atau simbol, dan beberapa parameter variabel (dalam kasus kami, amplitudo) disimpan di sepanjang chip.
Jika, misalnya, kami dapat memvariasikan amplitudo dalam kisaran dari 0 hingga 32767 (sampel 16-bit), dan kami perlu mentransfer 255 nilai kecerahan piksel, kemudian per unit perubahan kecerahan piksel, amplitudo chip akan berubah menjadi 32768/255 = 128.
Parameter penting lainnya adalah panjang chip, kami mulai dengan satu periode pembawa - empat sampel dalam kasus kami.
Jadi gambar akan ditransmisikan piksel demi piksel, setiap piksel berlangsung 4 sampel, dan amplitudo untuk periode ini adalah b [x, y] * 128, di mana b [x, y] adalah nilai kecerahan piksel dengan koordinat x dan y pada gambar b.

Mari kita perkirakan kecepatan transmisi yang akan terjadi.
Dalam contoh, saya menggunakan ukuran bingkai 120x120 piksel. Ini berarti bahwa untuk mentransfer satu frame, kita perlu

120x120x4 = 57600 sampel,

Jika frekuensi sampling 96 kHz, maka transmisi satu frame akan memakan waktu:

57600/96000 = 0,6 detik

Jelas, kita membutuhkan semacam jeda, interval pengawal tertentu, sehingga detektor dapat menentukan awal dari frame berikutnya. Untuk alasan yang manusiawi, anggaplah bahwa 0,1 detik sudah cukup bagi kita, selama semua gema mati (sebenarnya tidak). Kemudian, pada akhirnya, kecepatan transfer akan berubah:

1 / (0,6 + 0,1) = 1,428 frame per detik.

Sangat mudah untuk membuat kesalahan di sini dan mencoba menghitung kecepatan dalam bit per detik. Lihat betapa luar biasanya kecepatan transmisi:

120 * 120 * 8 / 1.428 = 80 627 bps

Tetapi apa yang terjadi jika saya tidak memiliki piksel 8-bit, tetapi 16-bit?

120 * 120 * 16 / 1.428 = 161344 bps

Tangkapan di sini adalah bahwa, sekali lagi, metode transmisi ini tidak dapat disebut digital, dan konsep bit rate tidak sepenuhnya valid untuk itu.
Cobalah untuk menghitung bit rate untuk sinyal televisi analog. Dan untuk penerima detektor? :)

Jadi, misalnya, sepotong sinyal akan terlihat seperti, mentransmisikan kecerahan 10 piksel, nilai yang berubah secara bergantian: 1 2 1 2 1 2 1 2 1 2


Sekarang mari kita lihat bagaimana ini bekerja dalam contoh. Metode Encode dan Decode hidup dalam kelas Encoder dan bertanggung jawab untuk memodulasi dan mendemodulasi gambar:

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


Hal ini dapat dilihat dari kode bahwa sebelum memodulasi gambar, awalan sinkronisasi yang terdiri dari nada murni (sampel pSize) ditambahkan ke sinyal output - ini diperlukan sehingga pada sisi penerima sinkronisasi dapat terjadi sebelum gambar itu sendiri dan secara umum dapat terjadi dalam kondisi buruk.
Metode Decode adalah sebagai berikut:

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


Dapat dilihat bahwa kedua metode tidak terikat pada frekuensi tertentu dan dapat digunakan dengan detektor lain.

Pencarian sinyal itu sendiri (deteksi, sinkronisasi) juga terjadi seperti pada modem hidroakustik kami yang paling sederhana , dengan satu-satunya perbedaan adalah bahwa saya meletakkannya di kelas FsBy4CarrierDetector yang terpisah untuk perubahan.
Semua sihir tanpa komplikasi terjadi dalam metode bool ProcessSample (pendek 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; } 


Ini dipanggil pada setiap sampel yang masuk dan mengembalikan true jika terdeteksi pembawa.

Karena detektor jauh dari sempurna, dan dapat dengan mudah disinkronkan di tengah garis, saya menambahkan slider khusus, bergerak yang Anda dapat mencapai sinkronisasi yang lebih akurat.

Sekarang, setelah kita secara singkat memeriksa bagaimana ini semua bekerja, mari kita beralih ke bagian yang paling lezat: apa yang bisa diperoleh dari semua ini.

Sedikit latihan


Pertama, mari kita periksa bagaimana semuanya bekerja tanpa saluran sonar - cukup dengan melampirkan antena penerima dan pemancar satu sama lain.
Pertama, gambar lebih besar (240x120) sehingga setidaknya ada sesuatu yang bisa dibuat:


Dan kemudian dengan cepat, sehingga ada lebih banyak kehidupan seperti video:


Sepertinya tidak buruk? Tapi jangan buru-buru menarik kesimpulan, dan pergi ke kolam renang:


Dan di sini, seperti yang saya janjikan dalam judul, kita akan melihat gema dengan mata kita sendiri:


Bagaimana Anda suka itu, Elon Musk? apakah kamu suka HD? Kenapa begitu?
Dan semuanya sangat sederhana - gema pada dasarnya adalah salinan yang tertunda dari sinyal asli, terkenal mengganggu di titik penerima, melipat dalam fase yang berbeda dan memberikan gambar seperti itu. Karena kami mentransfer gambar, pada akhirnya kami mendapatkan banyak gambar saling melapis dengan amplitudo yang berbeda. Semua ini pada akhirnya mengarah pada pengaburan dan reproduksi.

Menengok ke belakang, mari kita periksa semuanya pada gambar model yang besar. Saya mengambil foto acak:


Saya memodulasinya, lalu menambahkan gema dan sedikit suara, lalu diterjemahkan, dan ya - hasilnya menyerupai apa yang kami dapatkan di kolam:


Pada prinsipnya, adalah mungkin untuk melakukan dekonvolusi dan mengurangi refleksi, tetapi biarlah orang-orang dari luar daerah kita yang meninggalkan titik ini untuk pekerjaan mandiri.

By the way, metode sebelumnya di kolam bekerja sedikit lebih baik, tetapi juga buruk - pada sinyal broadband, multipath dan reverb mengarah ke frekuensi selektif fading, yang dalam gambar (baca pada spektrum) terlihat seperti garis-garis hitam dan putih - di mana sinyal berada di antiphase, dan di mana ia dikembangkan secara bertahap (pada kenyataannya, masih ada banyak opsi antara):


Pada bulan April, kami memanfaatkan momen itu dan pergi ke kolam dengan model papan tempat memotong roti dan memanjakan diri Anda di sana juga:




Hasilnya tidak jauh berbeda dengan hasil yang didapat di pool:




Dan segera untuk perbandingan, metode sebelumnya:


Dan berikut ini adalah animasi gif yang dikumpulkan dari frame yang disimpan, metode 1:


Dan metode 2, yang kita bahas dalam artikel ini:


Kesimpulannya


Seperti yang dijanjikan, kami menunjukkan bagaimana gema dan reverb terlihat secara harfiah, menghabiskan waktu dengan manfaat dan melakukan sesuatu dengan tangan kami.

Dalam bentuk ini, tentu saja, metode ini tidak berlaku dalam praktik, tetapi bekerja dengannya akan sangat berguna bagi pemula.

Secara umum, kami memeriksa di kolam dangkal, di mana kondisinya sangat tidak menguntungkan, dan akan keren jika seseorang mengulangi percobaan kami di reservoir lain dan pasti akan memberi tahu tentang hasilnya.

Jika pembaca hanya ingin mencoba (bahkan di udara dengan mikrofon dan speaker), maka di sini adalah tautan untuk rilis:
Metode 1
Metode 2 (dari artikel ini)

PS

Kami benar-benar menantikan umpan balik dari pembaca, karena sangat penting untuk memahami bahwa Anda melakukan sesuatu dengan sia-sia (atau sia-sia, dan kemudian ini harus dihentikan segera).

PS / 2

Saya akan menjawab pertanyaan umum segera: untuk ikan dan kehidupan laut lainnya di fasilitas anak-anak seperti itu, ini semua tidak terlalu diperhatikan.

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


All Articles