Veículos autônomos estão se tornando lentamente uma parte importante da indústria automotiva. Muitos acreditam que veículos totalmente autônomos em breve estarão dirigindo ao lado de humanos, e empresas de tecnologia estão em uma corrida para implantar veículos totalmente autônomos. Em dezembro de 2018, Waymo, a empresa que surgiu do projeto de carro autônomo do Google, iniciou oficialmente seu serviço comercial de carro autônomo nos subúrbios de Phoenix. Empresas como May Mobility, Drive.ai e Uber estão seguindo o mesmo caminho.
Veículos autônomos podem parecer ser uma visão grandiosa, mas veículos semi-autônomos já estão entre nós. Os novos carros da Tesla têm o recurso Tesla Autopilot, que é capaz de reconhecimento e rastreamento de faixas, controle de cruzeiro adaptativo e estacionamento automático. A capacidade de identificar e rastrear faixas na estrada é um dos muitos pré-requisitos para veículos sem motorista. Embora o reconhecimento de faixas possa parecer um problema difícil, você pode começar a desenvolver algoritmos de reconhecimento e rastreamento de faixas com a plataforma de hardware NVIDIA Jetson Nano.
O Jetson Nano COM é um pouco maior que um Raspberry Pi 3, mas pode executar redes neurais em paralelo com 472 Gflops de potência. Isso é cerca de 22 vezes mais potente que o Raspberry Pi 3 e é altamente eficiente em termos de energia, consumindo apenas 5 W. Esta placa é perfeita para aplicações de IA embarcada rodando em um kernel Linux enxuto. Ela possui poder de processamento e memória embarcada suficientes para aplicações de processamento de imagens e vídeos de alta qualidade. As principais características do Jetson Nano incluem:
Para este projeto, precisamos de um Jetson Nano COM ou placa de desenvolvimento e uma câmera CSI (uma câmera CSI Raspberry Pi v2 funciona bem). Vou mostrar esta aplicação usando a placa de desenvolvimento Nano, mas você pode facilmente construir uma base personalizada para um Nano COM e implantar esta aplicação. A câmera CSI será conectada à porta da câmera no Jetson Nano, embora você possa usar uma câmera USB ou câmeras IP. Abaixo estão os requisitos necessários para fazer este projeto funcionar com sucesso:
A implementação completa para este projeto pode ser encontrada no GitHub. Siga os próximos passos para obter uma demonstração deste projeto em funcionamento. Estes passos são importantes etapas de processamento de imagem que se destinam a tornar o reconhecimento de faixas mais preciso.
O primeiro passo do nosso sistema de detecção de faixas é ser capaz de ler imagens ao vivo da câmera. Para novos usuários trabalhando com o Jetson Nano, lidar com as câmeras pode ser complicado. Para isso, estaremos usando a biblioteca NanoCamera. Esta biblioteca não é a melhor opção para uma aplicação de nível de produção, mas funciona para uma aplicação mais simples como a mostrada aqui.
Primeiro, instale a biblioteca com pip:
Lendo a imagem ao vivo da câmera:
Para tornar a imagem mais suave e remover ruídos indesejados, podemos aplicar um desfoque gaussiano. Isso envolve calcular o valor de cada pixel como uma média ponderada dos pixels ao redor.
O OpenCV inclui uma função para aplicar desfoque gaussiano em uma imagem:
Após o desfoque gaussiano, a imagem ainda está em RGB e deve ser transformada para o espaço de cores HSV. A separação de cores será usada para remover cores indesejadas da imagem. Uma vez que a imagem está em HSV, podemos "remover" todas as cores desnecessárias da imagem especificando uma faixa de escala de cinza.
A dilatação adiciona pixels aos limites dos objetos em uma imagem. Aplicar dilatação à imagem ajudará a fechar quaisquer espaços soltos nas imagens de linha.
Para detectar linhas de faixa, podemos usar uma técnica chamada detecção de bordas de Canny. A detecção de bordas de Canny pode ser usada para extrair informações estruturais úteis de um objeto. A biblioteca OpenCV fornece uma função de detecção de bordas de Canny que pode ser usada para detectar bordas em uma imagem. Para que a detecção de Canny funcione, precisamos fornecer limites mínimos e máximos. O OpenCV geralmente recomenda o valor de (100, 200) ou (200, 400), então estamos usando (200, 400).
A imagem de saída da borda de Canny contém algum ruído. Todas as informações, exceto as faixas na imagem, podem ser isoladas reduzindo a região de interesse. Ao realizar o reconhecimento e a navegação de faixas, não necessariamente precisamos ver a imagem inteira. Uma maneira fácil de fazer isso é simplesmente recortar a metade superior da imagem.
O código para reduzir a região de interesse é:
Após a região de interesse ter sido reduzida, as faixas estão claramente visíveis com quatro linhas distintas. No entanto, o computador não sabe que essas linhas representam os limites de duas faixas. Então, precisamos de uma maneira de extrair as coordenadas para essas linhas de faixa. Uma transformada de Hough é uma técnica usada no processamento de imagens para extrair características como linhas, círculos e elipses. Ela pode ser usada para encontrar linhas retas a partir de um número de pixels que parecem formar uma linha. Isso pode ser feito com a função HoughLinesP no OpenCV. A função ajusta várias linhas através de todos os pixels brancos e retorna o conjunto mais provável de linhas sujeitas a algumas restrições de limiar mínimo.
Aqui está o nosso código que detecta segmentos de linha usando uma Transformada de Hough. A maioria dos parâmetros usados aqui pode ser determinada por tentativa e erro ou selecionando parâmetros de imagens de referência.
A saída da função detect_line_segments() produz um conjunto de pequenas linhas com coordenadas de ponto final (x1, y1) e (x2, y2). Precisamos encontrar uma maneira de combiná-las em apenas duas linhas para as linhas de faixa esquerda e direita, mas como conseguimos isso? Uma maneira é classificar esses segmentos de linha por suas inclinações.
Todas as linhas da faixa esquerda têm uma inclinação positiva, e os segmentos de linha pertencentes à faixa da direita têm uma inclinação negativa. Com base nestes dois novos grupos, podemos calcular a média das inclinações e interceptações dos segmentos de linha para obter as inclinações e interceptações das linhas das faixas esquerda e direita. Isso é implementado com a função average_slope_intercept():
A função make_points() é uma função auxiliar para a função average_slope_intercept(), que recebe a inclinação e interceptação de uma linha, e retorna os pontos finais do segmento de linha. Neste ponto, agora temos as linhas das faixas!
Neste ponto, a saída desta função seria entrada para outro algoritmo para controlar a velocidade e direção do veículo. Para fazer isso, um ângulo de direção pode ser calculado a partir das linhas das faixas detectadas e, em seguida, passado para um controlador PID para minimizar o ângulo de direção e manter o veículo centrado.
Embora isso tenha sido feito com uma placa de desenvolvimento Nano, o mesmo código oferece um ponto de partida para a implantação de um sistema em um sistema de processamento de imagens embutido para um ambiente de produção. Para fazer isso, você precisará construir uma base real para o Jetson Nano. Isso é mais fácil quando você usa as ferramentas de design eletrônico modular no aplicativo Upverter Board Builder. Adotando uma abordagem modular, você pode facilmente personalizar uma base para um Jetson Nano, câmeras e outros sensores para reconhecimento de faixas.
As ferramentas de design eletrônico modular no Upverter dão acesso a uma ampla gama de COMs padrão da indústria e módulos populares sem a necessidade de baixar ou instalar nenhum novo software. Você pode criar hardware de grau de produção para uma variedade de aplicações, incluindo reconhecimento de faixas e outras tarefas de processamento de imagens com Jetson Nano, usando uma interface de usuário de arrastar e soltar. Se o seu sistema precisar de funcionalidades adicionais, você pode incluir conectividade sem fio, uma variedade de sensores e muito mais.
Veja algumas histórias de sucesso de clientes da Gumstix ou entre em contato conosco hoje mesmo para saber mais sobre nossos produtos, ferramentas de design e serviços.