Oi Habr.
Uma publicação recente aqui no site descreveu um dispositivo que permite que pessoas cegas “vejam” uma imagem, transformando-a usando ondas sonoras. Do ponto de vista técnico, naquele artigo não havia nenhum detalhe (
e se a idéia de um milhão fosse roubada ), mas o conceito em si parecia interessante. Tendo alguma experiência com o processamento de sinais, decidi experimentar por conta própria.

O que aconteceu, detalhes e exemplos de arquivos sob o gato.
Converter 2D em 1D
A primeira tarefa óbvia que nos espera é converter uma imagem "plana" bidimensional em uma onda sonora "unidimensional". Conforme sugerido nos comentários desse artigo, é conveniente usar
a curva de Hilbert para isso.

Assemelha-se essencialmente a um fractal, e a idéia é que, com um aumento na resolução da imagem, a posição relativa dos objetos não muda (se o objeto estava no canto superior esquerdo da imagem, ele
permanecerá lá ). Diferentes dimensões das curvas de Hilbert podem nos fornecer imagens diferentes: 32x32 para N = 5, 64x64 para N = 6 e assim por diante. Ao “caminhar” pela imagem ao longo dessa curva, obtemos uma linha, um objeto unidimensional.
A próxima pergunta é o tamanho da imagem. Intuitivamente, quero tirar uma imagem maior, mas existe um grande "mas": até a imagem é 512x512, é 262144 pixels. Se convertermos cada ponto em um pulso de áudio, em uma frequência de amostragem de 44100, obteremos uma sequência de até 6 segundos, e isso é muito longo - as imagens devem ser atualizadas rapidamente, por exemplo, usando uma câmera da web. Não faz sentido aumentar a taxa de amostragem; obtemos frequências ultrassônicas inaudíveis pelo ouvido (embora isso possa funcionar para uma coruja ou um morcego). Como resultado, uma resolução de 128x128 foi escolhida
pelo método de cutucada
científica , que fornecerá impulsos com 0,37 c de comprimento - por um lado, é rápido o suficiente para navegar em tempo real; por outro, é suficiente para captar quaisquer alterações na forma do sinal pelo ouvido.
Processamento de imagem
O primeiro passo é baixar a imagem, convertê-la em preto e branco e escalá-la para o tamanho desejado. O tamanho da imagem depende da dimensão da curva de Hilbert.
from PIL import Image from hilbertcurve.hilbertcurve import HilbertCurve import numpy as np from scipy.signal import butter, filtfilt
O próximo passo é formar uma onda sonora. Aqui, é claro, pode haver muitos algoritmos e know-how, para o teste que acabei de fazer o componente de brilho. Claro, provavelmente existem maneiras melhores.
width, height = img_grayscale.size sound_data = np.zeros(width*height) for ii in range(width*height): coord_x, coord_y = hilbert_curve.coordinates_from_distance(ii) pixel_l = img_data[coord_x][coord_y]
Pelo código, espero que tudo esteja claro. A função coordinates_from_distance faz todo o trabalho para converter as coordenadas (x, y) para uma distância em uma curva de Hilbert, invertemos e convertemos o valor do brilho L em cor.
Isso não é tudo. Porque pode haver grandes blocos da mesma cor na imagem, isso pode levar ao aparecimento de um “componente dc” no som - uma longa série de valores diferentes de zero, por exemplo [100.100.100, ...]. Para removê-los, aplicamos um filtro passa-alto (filtro
Butterworth ) ao nosso array com uma frequência de corte de 50 Hz (a coincidência com a frequência da rede é aleatória). Há uma síntese de filtros na biblioteca scipy, que usaremos.
def butter_highpass(cutoff, fs, order=5): nyq = 0.5 * fs normal_cutoff = cutoff / nyq b, a = butter(order, normal_cutoff, btype='high', analog=False) return b, a def butter_highpass_filter(data, cutoff, fs, order=5): b, a = butter_highpass(cutoff, fs, order) y = filtfilt(b, a, data) return y
O último passo é salvar a imagem. Porque o comprimento de um pulso é curto, repetimos 10 vezes; será mais audível mais perto de uma imagem de repetição real, por exemplo, de uma câmera web.
Resultados
O algoritmo acima é, é claro, bastante primitivo. Eu queria verificar três pontos - quanto você pode distinguir entre diferentes formas simples e quanto você pode estimar a distância até as formas.
Teste 1
A imagem corresponde ao seguinte sinal sonoro:

WAV:
cloud.mail.ru/public/nt2R/2kwBvyRupTeste 2
A idéia deste teste é comparar o "som" de um objeto de uma forma diferente. Sinal sonoro:

WAV:
cloud.mail.ru/public/2rLu/4fCNRxCG2Você pode perceber que o som é realmente diferente e há uma diferença de ouvido.
Teste 3
A idéia do teste é testar um objeto menor. Sinal sonoro:

WAV:
cloud.mail.ru/public/5GLV/2HoCHvoaYEm princípio, quanto menor o tamanho do objeto, menos haverá "explosões" no som, portanto a dependência aqui é bastante direta.
Editar:Conforme sugerido nos comentários, você pode usar a transformação de Fourier para converter diretamente imagens em som. Um teste rápido mostra os seguintes resultados (as imagens são as mesmas):
Teste 1:
cloud.mail.ru/public/2C5Z/5MEQ8SwjoTeste 2:
cloud.mail.ru/public/2dxp/3sz8mjAibTeste 3:
cloud.mail.ru/public/3NjJ/ZYrfdTYrkOs testes parecem interessantes, pelo menos para quadrados pequenos e grandes (arquivos 1 e 3), a diferença na audição é perceptível. Mas a forma das figuras (1 e 2) praticamente não difere, então também há algo em que pensar. Mas, em geral, o som obtido usando FFT, de ouvido eu gosto mais.
Conclusão
Este teste, é claro, não é uma dissertação, mas simplesmente uma prova de conceito, feita em poucas horas de tempo livre. Mas mesmo assim, basicamente funciona, e é bem possível sentir a diferença de ouvido. Não sei se é possível aprender a navegar no espaço com esses sons, hipoteticamente, provavelmente após algum treinamento. Embora exista um grande campo para aprimoramentos e experimentos, por exemplo, você pode usar som estéreo, o que permitirá separar melhor objetos de lados diferentes, você pode experimentar outros métodos de conversão de imagens em som, por exemplo, codificar cores em diferentes frequências etc. Finalmente, é promissor o uso de câmeras 3D capazes de perceber a profundidade (infelizmente, essa câmera não está disponível). A propósito, com a ajuda de um código OpenCV simples, o algoritmo acima pode ser adaptado para usar uma câmera da web, o que permitirá que você experimente imagens dinâmicas.
Bem, como sempre, todas as experiências bem-sucedidas.