Respostas no Fórum
- AutorPosts
Oi! Não se preocupe, esse é um tema que parece meio confuso mesmo e pode demandar certo tempo para adquirir a intuição necessária, então fique tranquila que durante o processo de aprendizagem vai fazer mais sentido para você 😉
Mas quanto à duvida, sim, acredito que você pode sim combinar as duas técnicas para alcançar seu objetivo. Para localizar os pontos de interseção no gráfico, uma abordagem eficaz seria realizar um pré-processamento usando técnicas de visão computacional e processamento de imagem conforme comentei na resposta anterior, como a detecção de bordas com OpenCV, desse modo permitindo você encontrar automaticamente essas interseções. A partir daí, você extrai as coordenadas (x, y) dos pontos de interseção.
A U-Net, por outro lado, poderia talvez ser usada para gerar a segunda imagem, ou seja, o gráfico final. Nesse caso, uma sugestão também seria procurar por papers que usam U-Net (ou outra rede) para reconstruir uma imagem com base na imagem original, estudar a real possibilidade disso na prática, pois creio que pode servir de inspiração (sugiro procurar nos repositórios por termos em inglês, como “unet image reconstruction”).
A U-Net é poderosa mesmo para segmentação de imagens, mas para a tarefa de encontrar as coordenadas exatas, métodos tradicionais de processamento de imagem podem ser mais adequados. Uma vez que você tenha as coordenadas das interseções (obtidas via processamento de imagem), pode utilizá-las para gerar o novo gráfico, traçando as linhas no local correto.
Para reconstruir esse gráfico a partir dos pontos de interseção que você extrair (coordenadas x, y), será necessário implementar um algoritmo que transforme esses valores em uma visualização gráfica. Esse algoritmo será responsável por organizar os pontos em uma estrutura coerente para o traçado da curva ou das linhas desejadas. Uma vez que você tenha as coordenadas, uma ótima opção é utilizar bibliotecas como Matplotlib ou Seaborn, que são amplamente usadas em Python para visualização de dados. Elas permitem gerar gráficos de alta qualidade e personalizáveis, garantindo imagem precisa e clara.
Ou seja, em seu projeto você vai usar uma combinação de diferentes bibliotecas, como as abaixo (ou outra de sua preferência, com o mesmo objetivo)
- OpenCV para o pré-processamento da imagem (detecção de bordas com cv2.Canny() ou cv2.findContours() para detectar as curvas).
- NumPy para lidar com os arrays de coordenadas.
- Matplotlib para gerar o novo gráfico com base nas coordenadas extraídas dos pontos de interseção.
- TensorFlow/Keras ou PyTorch para treinar e usar a U-Net, caso você precise de uma abordagem mais robusta para segmentação de imagem.
Portanto, uma solução pode ser: (1) pré-processar a imagem para detectar os pontos de interseção, (2) extrair as coordenadas desses pontos e (3) usar essas coordenadas para gerar um novo gráfico com Matplotlib ou outro pacote de visualização. Isso evitaria a necessidade de uma rede neural para a parte de detecção das interseções, simplificando o processo.
Olá Douglas!
Isso é devido a uma atualização recente do tensorflow, onde é necessário um pequeno ajuste. Na verdade, você tem duas opções: ou usar uma versão anterior, ou fazer esse ajuste.
Se optar por usar uma versão anterior (por exemplo a 2.12.0 — mas pode ser mais recente, só não pode ser uma das últimas) então basta rodar esse comando abaixo antes de todo o código, colocando como o primeiro bloco.
!pip install tensorflow==2.12.0
E após executar isso reiniciar a sessão do Colab. Caso não apareça já automaticamente um botão para reiniciar, basta ir em ‘Ambiente de execução > reiniciar sessão’. Com isso vai funcionar e não precisa fazer nenhum ajuste.
A outra opção é fazer um pequeno ajuste. Após uma atualização recente do tensorflow é necessário agora usar get_layer() para a camada de input, igual é feito com a camada de output.
Ou seja, ao invés de autoencoder.input agora vai ser: autoencoder.get_layer(‘dense’).input
você deve substituir isso no parâmetro inputs em “encoder = Model()“. ficando assim:
encoder = Model(inputs = autoencoder.get_layer(‘dense’).input, outputs = autoencoder.get_layer(‘dense_2’).output)
Observação: além desse trecho, também será preciso mudar lá logo abaixo da seção “Codificação e decodificação das imagens de teste”, alterando de autoencoder.input para autoencoder.get_layer(‘conv2d’).input
Olá, eu acredito que conseguiria sim reconstruir a imagem usando técnicas tradicionais (isso se entendi corretamente o que você quis dizer que “reconstruir”, que seria criar esse gráfico que você mandou por último). Caso o interesse seja segmentar a linha (e não apenas retornar a localização do ponto de intersecção) então teria vantagem usar o U-Net ou outra abordagem para segmentação de imagem, pois através da segmentação você retornaria o desenho da linha no gráfico, já com detecção você poderá obter somente a região do ponto de intersecção na imagem e as coordenadas dessa região de interesse (ROI).
Mas caso você precise apenas achar o ponto x,y na imagem e não segmentar a linha então penso que a U-Net não teria uma vantagem nesse contexto, já que o retorno da U-net no final das contas é basicamente uma máscara do “objeto” segmentado (nesse caso, objeto é o ponto de intersecção). Ou seja, ao final do processamento da rede neural você terá uma imagem binarizada que representa o “objeto” com um cor e o fundo (tudo o que não é o objeto) com outra. Mas talvez tenha outro detalhe em relação ao que você deseja fazer e que faça o U-Net ser mais vantajosa, essa minha opinião acima seria com base apenas no que entendi quanto à questão que você apresentou na pergunta.
Mesmo assim, se ideia é segmentar a região eu aconselho testar também as técnicas tradicionais mostradas na primeira seção do curso, por exemplo a técnica de limiarização (thresholding). É um método mais simples mas que pode ser bastante eficaz para imagens digitais, que possuem menos variação de tons de cores. Aliás, se todas as imagens que você fará o processamento forem semelhantes e possuírem o mesmo estilo de gráfico por exemplo, então esses métodos tradicionais podem ser o suficiente. Já se as imagens de gráficos que serão testadas possuírem muitas diferenças entre si então faz mais sentido usar técnica baseada em deep learning como U-Net, pois irão ser mais robustas e funcionar melhor para uma gama maior de imagens e sem exigir customização individual de parâmetros.
Quanto à possibilidade de extrair as coordenadas desse segmento na imagem, dá para fazer isso tanto usando os métodos com deep learning quanto métodos com processamento de imagem (por exemplo assim). Ou seja, de qualquer forma poderá obter as coordenadas de localização desse ponto na imagem, podendo usar para gerar uma imagem semelhante à que você forneceu. E para obter esses valores dos eixos X e Y em uma imagem de gráfico, é possível usar técnicas de processamento de imagem como detecção de bordas ou contornos para identificar elementos relevantes, como curvas ou interseções (ou a técnica de limiarização, que citei acima). Uma vez detectado o ponto de interesse – nesse caso, ponto de interseção – as coordenadas desse ponto podem ser extraídas em termos de pixels. Com essas coordenadas em pixel, você pode realizar uma calibração comparando os pixels com os valores reais dos eixos. Isso é feito associando pontos de referência conhecidos no gráfico aos seus valores correspondentes no eixo (por exemplo, associar um ponto específico no gráfico ao valor de 3.5 no eixo X e 1 no eixo Y). Dessa forma, é possível converter as coordenadas de pixel em valores reais do gráfico, permitindo a leitura precisa das variáveis como tempo (Y) e velocidade (X).
Uma outra sugestão seria que você combine ambas as abordagens: comece com o processamento de imagem tradicional para pré-processar ou até mesmo identificar os pontos de interesse, e, em seguida, use uma U-Net ou outra rede neural adequada para mapear essas interseções e depois poder gerar a imagem final do perfil de velocidade.
Olá João!
Segue abaixo a explicação para cada função de loss / perda:
- Box loss – mede o quão bem o modelo prevê a localização e o tamanho das caixas delimitadoras previstas pelo modelo (x, y, largura, altura) em relação às coordenadas reais (da ground truth) que encapsula o objeto. Portanto, mede a discrepância entre a caixa delimitadora prevista e a real, indicando a importância de obter a localização correta da bbox com o mínimo de erro.
- Cls (Class) loss – está relacionada à tarefa de classificação, que corresponde à classificação correta dos objetos. É a diferença entre a classe prevista de um objeto pelo modelo e a classe real do objeto (indicado no arquivo de anotação usado para treinamento). Aumentar esse valor diz ao modelo para prestar mais atenção em obter as classificações corretas, potencialmente melhorando a precisão onde ocorre identificação incorreta.
- DFL loss – Significa ‘Distribution Focal Loss’, que é uma variante da focal loss (detalhada nesse artigo) que ajuda a melhorar o desempenho do modelo quando os dados de treinamento são desequilibrados. Especificamente, isso é usado para lidar com o desequilíbrio de classe (class imbalance) que surge ao treinar em conjuntos de dados com objetos muito raros. Quando há muito poucos exemplos de uma determinada classe de objeto no conjunto de treinamento, a rede pode normalmente ter dificuldade para aprender a detectar esses objetos corretamente. Essa perda visa abordar esse problema e garantir que o modelo detecte corretamente esses objetos mais raros.
Para mais informações você pode conferir a documentação do YOLOv8: https://docs.ultralytics.com/reference/utils/loss
Na documentação eles não detalham muito sobre cada loss especificamente, mas se quiser saber onde encontrar mais detalhes sobre a explicação você pode procurar em discussões no repositório oficial, que contém informações do autor (fonte dessas informações acima por exemplo: [1], [2], [3], [4], [5]).
Olá Amanda!
Sim, é possível treinar uma rede neural para identificar a região de interseção como a na imagem que você passou. Esse tipo de problema pode ser abordado como uma tarefa de detecção ou segmentação de objetos, onde o objetivo é localizar ou destacar a área de interesse. Ou ainda, focando em usar um conjunto de técnicas de processamento de imagem para se obter a localização exata da região.
Uma abordagem usando redes neurais e deep learning seria criar um conjunto de dados anotado onde as áreas de interseção são marcadas manualmente, permitindo que a rede aprenda a identificar essas características durante o treinamento. Como você já tem algum conhecimento teórico sobre Redes Neurais Artificiais, a próxima etapa seria aplicar esse conhecimento em um projeto prático. Um detalhe apenas é que essa abordagem seria um pouco mais trabalhosa pois tem que reunir um bom conjunto de imagens de treinamento, mas é possível sim.
Para aprender a treinar uma rede neural do zero, recomendo focar em cursos que abordam a criação e treinamento de modelos de deep learning na prática, de preferências cursos focados em visão computacional. O curso “Visão Computacional – O Guia Completo” poderia ser uma boa escolha para agora, mas sugiro dar uma olhada antes nos outros da trilha de visão computacional para ver se a grade de algum deles pode ser mais adequada ao que você procura (e também para ver em qual nível de conhecimento você estaria).
Embora seja possível treinar uma rede neural para detectar a interseção na imagem, penso que pode ser mais prático e eficiente utilizar técnicas tradicionais de processamento de imagem para essa tarefa específica. Métodos como detecção de bordas, segmentação baseada em limiar (thresholding), ou transformadas como a Transformada de Hough, que são frequentemente usados para identificar formas geométricas em imagens, podem ser suficientes para resolver esse problema de maneira precisa e rápida. A vantagem é que além dessas técnicas requerem menos recursos computacionais, também podem ser mais facilmente interpretadas e ajustadas para detectar interseções em imagens como a que você está trabalhando. Ou seja, mexendo nos parâmetros do algoritmo (que pode ser facilmente implementado pela função pronta) você conseguiria adequar ao seu exemplo.
Esse aqui é um exemplo de como poderia ser usado, não é tão semelhante ao seu exemplo mas a ideia é basicamente a mesma, sendo usado para achar a intersecção. Ali já tem o código pronto, porém pode ser necessária uma customização dos parâmetros para se alcançar o resultado ideal.
Portanto, por exigir menos trabalho que o treinamento de um modelo próprio eu recomendaria testar antes essas abordagens.
Aliás, boa sorte em seu projeto!
Disponha, João!
Olá Douglas!
Para definir esse valor foi usado a mesma fórmula vista na aula “Construção e treinamento da rede neural”.
Primeiramente você deve obter a descrição de todas as camadas usando o .summary(). Você precisa pegar os valores de dimensões da última camada de max pooling.
Em seguida é necessário “achatar” (flatten), fazendo a transformação de matriz em vetor.
Esses valores que serão usadas na camada de entrada da rede neural.
Fórmula: (número de entradas da rede neural + número de classes) / 2
Ou seja, para esse exemplo a entrada é (14, 14, 32) então vai ficar: 14 * 14 * 32 = 6272
(6272 + 2) / 2 = 3137Tudo isso é explicado com mais detalhes nessa aula, portanto sugiro ver ela inteira pois lá é explicado bem certo.
28 de agosto de 2024 às 16:03 em resposta a: Redes neurais convolucionais para classificação de imagens #45826Olá Douglas!
A escolha do número de camadas vai depender de vários fatores, como a complexidade do problema, a quantidade de dados disponíveis e os recursos computacionais que possui na máquina onde será executado. Portanto, em projetos reais não há uma regra fixa, e a arquitetura da rede geralmente é definida após analisar outros trabalhos semelhantes publicados com o mesmo objetivo ou por meio de experimentação, testes e ajustes.
A ideia é começar com uma arquitetura básica e ir aumentando a complexidade conforme necessário. Em tarefas simples, redes com menos camadas podem ser suficientes, enquanto em problemas mais complexos (como reconhecimento facial ou classificação de objetos em grande escala), redes mais profundas são necessárias para capturar as características mais sutis das imagens. Isso caso deseje criar sua própria rede, pois lembrando que existem implementações que auxiliam no desenvolvimento, evitando a necessidade de se definir e escolher manualmente os critérios da arquitetura como a quantidade de camadas.
O que se faz durante o desenvolvimento é monitorar o desempenho da rede (usando métricas como precisão, recall e loss) e ajustar a quantidade de camadas e neurônios conforme necessário. Também é comum utilizar técnicas como validação cruzada para evitar overfitting e garantir que a rede generalize bem para novos dados.
Ou seja, a quantidade de camadas e a arquitetura da rede vão depender muito do seu objetivo e da complexidade do problema que você está tentando resolver. Se você deseja ajustar manualmente a arquitetura e criar sua própria implementação, recomendo seguir para cursos mais avançados na Trilha de Visão Computacional ou de Deep Learning, onde você pode explorar técnicas e práticas mais sofisticadas. Este curso em particular tem um objetivo mais introdutório e visa fornecer uma base sólida. Em cursos mais avançados de Deep Learning (por exemplo o Deep Learning com Python de A à Z), você terá a oportunidade de desenvolver uma intuição mais apurada para ajustar redes neurais de acordo com diferentes tipos de problemas da área, o que será útil caso tenha a intenção de desenvolver sua própria solução.
Olá João!
Para dividir uma imagem maior em várias subimagens você pode usar dois loops para cortar a imagem em blocos de 640 x 640 pixels.
A ideia é basicamente iterar sobre as coordenadas da imagem original e através dessas coodenadas xy você delimita o inicio/fim de cada pedaço da imagem, de forma que a cada iteração uma subimagem seja extraída e armazenada.
Aqui está um exemplo de código:
# Carrega a imagem imagem = cv2.imread('sua_imagem.jpg') # (Tamanho das subimagens) altura_subimagem = 640 largura_subimagem = 640 # Obter as dimensões da imagem original altura, largura, _ = imagem.shape # Loop para cortar as subimagens for i in range(0, altura, altura_subimagem): for j in range(0, largura, largura_subimagem): # Coordenadas para cortar subimagem = imagem[i:i+altura_subimagem, j:j+largura_subimagem] # Salvar ou processar a subimagem nome_arquivo = f'subimagem_{i}_{j}.jpg' cv2.imwrite(nome_arquivo, subimagem)
O loop corta a imagem em subimagens e cada subimagem é salva como um arquivo separado. Você pode ajustar o nome dos arquivos conforme necessário. Com isso, sua imagem original de 3.000 x 4.000 pixels será fragmentada em várias imagens menores, todas do tamanho que você especificou (640 x 640 pixels).
2 de agosto de 2024 às 21:30 em resposta a: Armazenamento de Imagem Colorida (Array com 03 dimensoes) em um Dataframe #45721Opa, que ótimo que melhorou bastante o desempenho!
Comparando esses dois testes, dá para comprovar que ambas as abordagens têm suas vantagens e desvantagens. Usar base64 resulta em um arquivo significativamente menor (710 KB contra 9.002 KB com pickle), o que é vantajoso para armazenamento e transmissão de dados. No entanto, a performance de pickle é superior tanto no tempo de cadastro quanto carregamento e processamento.
Portanto, a escolha entre as duas depende das suas prioridades. Se o objetivo principal for economizar espaço de armazenamento e garantir portabilidade, base64 é a melhor opção. Por outro lado, se a prioridade for performance e rapidez na leitura e escrita de dados, pickle é mais recomendado. Avalie o que é mais importante para seu projeto e escolha a abordagem que melhor se alinha às suas necessidades. Caso escolha a pickle devido à velocidade, você pode ainda tentar aplicar técnicas para reduzir o tamanho em disco, como explicado nesse artigo por exemplo.
1 de agosto de 2024 às 10:08 em resposta a: Armazenamento de Imagem Colorida (Array com 03 dimensoes) em um Dataframe #45677Olá Cesar!
Para melhorar a performance ao armazenar e exibir imagens coloridas em um DataFrame eu acredito que algumas mudanças podem ser feitas na sua abordagem.
No código de cadastro de usuários no DataFrame, atualmente você está convertendo cada imagem em uma lista antes de armazenar, o que pode ser bem ineficiente em termos de espaço e tempo de execução. Além disso, ao ler as imagens do DataFrame, você está usando ast.literal_eval para converter as strings de volta em listas, o que também pode vir a ser extremamente lento.
Uma abordagem mais eficiente seria armazenar as imagens codificadas em base64 diretamente no dataframe. Isso não só melhora a performance, mas também facilita a manipulação dos dados.
E codificando as imagens em base64 você reduz o tempo necessário para converter entre diferentes formatos de dados. Armazenar imagens codificadas como strings base64 em um CSV pode ser mais eficiente do que armazenar listas de números, além de facilitar a manipulação dos dados. Isso deve resolver o problema de performance que você está enfrentando e tornar o processo de armazenamento e recuperação de imagens mais eficiente.
Aqui está uma sugestão de código com base no que você informou:
[ ... importações e restante do código ] # Função para converter imagem para base64 def image_to_base64(image): _, buffer = cv2.imencode('.jpg', image) image_base64 = base64.b64encode(buffer).decode('utf-8') return image_base64 # Função para converter base64 para imagem def base64_to_image(image_base64): image_data = base64.b64decode(image_base64) image_np = np.frombuffer(image_data, dtype=np.uint8) image = cv2.imdecode(image_np, cv2.IMREAD_COLOR) return image # Cadastrar usuario no Dataframe def cadastra_dataframe(full_name, imagem): nome = [full_name] imagem_base64 = [image_to_base64(imagem)] # Abrindo df existente df = pd.read_csv('usuario.csv') # Dados para ser incluído o dataframe existente dados = {'full_name': nome, 'imagem': imagem_base64} dados = pd.DataFrame(dados) df = pd.concat([df, dados], ignore_index=True) df.to_csv('usuario.csv', index=False) # Exibir as imagens gravadas no dataframe dados_df = pd.read_csv('usuario.csv') ### E para iterar sobre cada linha do DataFrame para exibir as imagens for i in range(len(dados_df)): full_name = dados_df['full_name'][i] print(full_name) inicio = time.time() imagem_base64 = dados_df['imagem'][i] imagem_array = base64_to_image(imagem_base64) fim = time.time() execucao = fim - inicio print(f'tempo de execucao : {execucao:.6f} segundos') cv2.imshow('Imagem Recuperada', imagem_array) cv2.waitKey(0) cv2.destroyAllWindows()
Olá Douglas!
Com o conhecimento do curso de Reconhecimento e Detecção Facial com Python você conseguirá criar sim a sua solução de reconhecimento facial. E seguir o restante da trilha é também recomendado para obter uma maior intuição e aprender a dominar melhor as principais bibliotecas de visão computacional, como OpenCV e Dlib (e assim saber o caminho adequado para desenvolver sua própria solução).
Embora não tenha atualmente um curso na trilha com a proposta específica de desenvolver um sistema próprio e completo com esse objetivo, você terá todo o conhecimento sobre a IA necessária para a tarefa de reconhecimento e saberá como fazer o treinamento da mesma, para que ela aprenda a reconhecer qualquer rosto. Portanto, o curso citado não mostra como criar passo a passo tal aplicação, pois isso foge do propósito (nesse caso procurar por cursos de desenvolvimento de sistemas, ou desenvolvimento de interfaces por exemplo, como é possível encontrar aqui na plataforma também).
Apesar de ensinar a usar técnicas modernas e robustas, o uso dessas técnicas de reconhecimento facial em sistemas de CFTV podem ser um pouco mais desafiadoras devido a fatores como qualidade de câmera, ângulo, etc – portanto, requer uma atenção maior a certos detalhes. Mas qualquer dúvida que tiver sobre o conteúdo ou dicas adicionais você pode perguntar aqui no fórum.
- Esta resposta foi modificada 9 meses, 2 semanas atrás por
Gabriel Alves.
Olá Vinicius!
O que resolve esse erro geralmente é interromper o Kernel, reiniciar o ambiente de execução (na página inicial do painel do SageMaker) e abrir novamente ao ambiente com GPU.
Se persistir, peço que compartilhe aqui um print das últimas informações que aparecem na saída da célula onde há o comando para abrir a interface (etapa 4), se possível um print ou pode copiar e colar se preferir, mostrando as últimas informações que foram exibidas antes de aparecer esse problema. Talvez com essas informações adicionais eu consiga verificar melhor o que poderia estar causando e assim determinar como resolver.
Olá Victor!
Para passar para a rede neural as imagens são geralmente convertidas para vetores (um array unidimensional), pois essas camadas trabalham com dados em formato vetorial. Por isso que anteriormente você viu ser feito dessa forma.
No entanto, para visualização e algumas operações específicas é mais conveniente e necessário trabalhar com imagens no formato matricial (bidimensional). No código que você mencionou, o X_teste[0].reshape(28,28) está convertendo o vetor de volta para uma matriz de 28×28 pixels para que possamos visualizar a imagem original de maneira mais intuitiva. Ou seja, é apenas para visualizarmos a imagem (repare que para isso estamos usando a função plt.imshow, que é justamente usada para exibir a imagem).
Portanto, essa conversão não é necessária para o processamento na rede neural, mas é útil para a visualização e interpretação dos dados. Então, embora a imagem seja processada internamente como um vetor ao passar pelas camadas densas, ela é reformatada em uma matriz para facilitar a visualização.
Olá Cesar!
Nesse caso você vai precisar instalar antes o CMake, disponível para baixar aqui https://cmake.org/download/
Em seguida, instale também o compilador Visual studio tools: https://visualstudio.microsoft.com/visual-cpp-build-tools/. Durante a instalação, certifique-se de selecionar os componentes de desenvolvimento de C++.
Para evitar alguns erros comuns que podem vir a ocorrer, eu sugiro dar uma olhada nesse artigo, que contém algumas dicas de como evitar os erros, como por exemplo adicionar o CMake às variáveis de ambiente do Windows.
- AutorPosts