A compressão de imagens é uma tecnologia crítica em visão computacional que nos permite armazenar e transmitir imagens com mais eficiência, mantendo a qualidade visual. Idealmente, adoraríamos ter arquivos pequenos com a melhor qualidade. No entanto, devemos fazer a troca e decidir o que é mais importante.
Este tutorial ensinará compactação de imagens com OpenCV, cobrindo teoria e aplicações práticas. Ao final, você entenderá como compactar fotos com sucesso para projetos de visão computacional (ou qualquer outro projeto que possa ter).
A compactação de imagem reduz o tamanho do arquivo de uma imagem enquanto mantém um nível aceitável de qualidade visual. Existem dois tipos principais de compactação:
Se “o espaço em disco é barato”, como ouvimos com frequência, então por que compactar imagens? Em pequena escala, a compressão de imagem não importa muito, mas em grande escala é crucial.
Por exemplo, se você tiver algumas imagens em seu disco rígido, poderá compactá-las e salvar alguns megabytes de dados. Isso não causa muito impacto quando os discos rígidos são medidos em Terabytes. Mas e se você tivesse 100.000 imagens no seu disco rígido? Alguma compactação básica economiza tempo e dinheiro reais. Do ponto de vista do desempenho, é a mesma coisa. Se você tem um site com muitas imagens e 10.000 pessoas o visitam por dia, a compactação é importante.
Veja por que fazemos isso:
As técnicas de compressão de imagens exploram dois tipos de redundâncias:
Redundância espacial aproveita o fato de que pixels vizinhos tendem a ter valores semelhantes na maioria das imagens naturais. Isso cria transições suaves. Muitas fotos “parecem reais” porque existe um fluxo natural de uma área para outra. Quando os pixels vizinhos têm valores totalmente diferentes, você obtém imagens "ruidosas". Os pixels foram alterados para tornar essas transições menos "suaves", agrupando os pixels em uma única cor, tornando a imagem menor.
Redundância de cores, por outro lado, concentra-se em como as áreas adjacentes em uma imagem geralmente compartilham cores semelhantes. Pense em um céu azul ou em um campo verde – grandes partes da imagem podem ter valores de cores muito semelhantes. Eles também podem ser agrupados e feitos em uma única cor para economizar espaço.
OpenCV oferece ferramentas sólidas para trabalhar com essas ideias. Usando redundância espacial, a função cv2.inpaint() do OpenCV, por exemplo, preenche áreas ausentes ou danificadas de uma imagem usando informações de pixels próximos. OpenCV permite que os desenvolvedores usem cv2.cvtColor() para traduzir imagens entre vários espaços de cores em relação à redundância de cores. Isso pode ser útil como uma etapa de pré-processamento em muitas técnicas de compactação, uma vez que alguns espaços de cores são mais eficazes do que outros na codificação de determinados tipos de imagens.
Vamos testar um pouco dessa teoria agora. Vamos brincar com isso.
Vamos explorar como compactar imagens usando ligações Python do OpenCV. Escreva este código ou copie-o:
Você também pode obter o código-fonte aqui
import cv2 import numpy as np def compress_image(image_path, quality=90): # Read the image img = cv2.imread(image_path) # Encode the image with JPEG compression encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality] _, encoded_img = cv2.imencode('.jpg', img, encode_param) # Decode the compressed image decoded_img = cv2.imdecode(encoded_img, cv2.IMREAD_COLOR) return decoded_img # Example usage original_img = cv2.imread('original_image.jpg') compressed_img = compress_image('original_image.jpg', quality=50) # Display results cv2.imshow('Original', original_img) cv2.imshow('Compressed', compressed_img) cv2.waitKey(0) cv2.destroyAllWindows() # Calculate compression ratio original_size = original_img.nbytes compressed_size = compressed_img.nbytes compression_ratio = original_size / compressed_size print(f"Compression ratio: {compression_ratio:.2f}")
Este exemplo contém uma função compress_image que usa dois parâmetros:
Em seguida, carregaremos a imagem original em original_img. Em seguida, compactamos a mesma imagem em 50% e a carregamos em uma nova instância, compressed_image.
Depois mostraremos as imagens originais e compactadas para que você possa visualizá-las lado a lado.
Em seguida, calculamos e exibimos a taxa de compressão.
Este exemplo demonstra como compactar uma imagem usando compactação JPEG no OpenCV. O parâmetro de qualidade controla o tamanho do arquivo e a compensação da qualidade da imagem.
Vamos executá-lo:
Ao olhar inicialmente para as imagens, você vê pouca diferença. No entanto, aumentar o zoom mostra a diferença na qualidade:
E depois de fechar as janelas e olhar os arquivos, podemos ver que o tamanho do arquivo foi drasticamente reduzido:
Além disso, se diminuirmos ainda mais, podemos mudar nossa qualidade para 10%
compressed_img = compress_image('sampleimage.jpg', quality=10)
E os resultados são muito mais drásticos:
E os resultados do tamanho do arquivo também são mais drásticos:
Você pode ajustar esses parâmetros facilmente e alcançar o equilíbrio desejado entre qualidade e tamanho do arquivo.
Para avaliar o impacto da compactação, podemos usar métricas como:
Erro quadrático médio (MSE) mede a diferença entre duas imagens. Ao compactar uma imagem, o MSE ajuda a determinar o quanto a imagem compactada mudou em comparação com o original.
Ele faz isso amostrando as diferenças entre as cores dos pixels correspondentes nas duas imagens, quadrando essas diferenças e calculando a média delas. O resultado é um único número: um MSE mais baixo significa que a imagem compactada está mais próxima do original. Em comparação, um MSE mais alto significa que há uma perda de qualidade mais perceptível.
Aqui está um código Python para medir isso:
def calculate_mse(img1, img2): return np.mean((img1 - img2) ** 2) mse = calculate_mse(original_img, compressed_img) print(f"Mean Squared Error: {mse:.2f}")
Esta é a aparência de nossa compactação de imagem de demonstração:
Peak Signal-to-Noise Ratio (PSNR) é uma medida que mostra o quanto a qualidade de uma imagem foi degradada após a compactação. Isso geralmente é visível a olho nu, mas atribui um valor definido. Ele compara a imagem original com a compactada e expressa a diferença como uma proporção.
Um valor PSNR mais alto significa que a imagem compactada tem qualidade mais próxima do original, indicando menos perda de qualidade. Um PSNR mais baixo significa degradação mais visível. PSNR é frequentemente usado junto com MSE, com PSNR fornecendo uma escala mais fácil de interpretar onde quanto maior, melhor.
Aqui está um código Python que mede isso:
def calculate_psnr(img1, img2): mse = calculate_mse(img1, img2) if mse == 0: return float('inf') max_pixel = 255.0 return 20 * np.log10(max_pixel / np.sqrt(mse)) psnr = calculate_psnr(original_img, compressed_img) print(f"PSNR: {psnr:.2f} dB")
Esta é a aparência de nossa compactação de imagem de demonstração:
"Olhar" suas imagens após a compactação para determinar a qualidade é bom; entretanto, em grande escala, fazer com que os scripts façam isso é uma maneira muito mais fácil de definir padrões e garantir que as imagens os sigam.
Vejamos algumas outras técnicas:
Para compactação mais avançada, OpenCV suporta vários algoritmos:
Você pode converter suas imagens para o formato PNG, o que tem muitas vantagens. Use a linha de código a seguir e você pode definir sua compactação de 0 a 9, dependendo de suas necessidades. 0 significa nenhuma compactação e 9 é o máximo. Lembre-se de que PNGs são um formato “sem perdas”, portanto, mesmo com compactação máxima, a imagem deve permanecer intacta. A grande desvantagem é o tamanho do arquivo e o tempo de compactação.
Aqui está o código para usar a compactação PNG com OpenCV:
cv2.imwrite('compressed.png', img, [cv2.IMWRITE_PNG_COMPRESSION, 9])
E aqui está o nosso resultado:
Nota: às vezes você pode notar que os arquivos PNG são realmente maiores em tamanho, como neste caso. Depende do conteúdo da imagem.
Você também pode converter suas imagens para o formato .webp. Este é um método mais recente de compactação que está ganhando popularidade. Há anos que uso essa compactação nas imagens do meu blog.
No código a seguir, podemos gravar nossa imagem em um arquivo webp e definir o nível de compactação de 0 a 100. É o oposto da escala do PNG porque 0, porque estamos definindo qualidade em vez de compressão. Essa pequena distinção é importante porque uma configuração de 0 é a qualidade mais baixa possível, com tamanho de arquivo pequeno e perda significativa. 100 é a qualidade mais alta, o que significa arquivos grandes com a melhor qualidade de imagem.
Aqui está o código Python para fazer isso acontecer:
cv2.imwrite('compressed.webp', img, [cv2.IMWRITE_WEBP_QUALITY, 80])
E aqui está o nosso resultado:
Essas duas técnicas são ótimas para compactar grandes quantidades de dados. Você pode escrever scripts para compactar milhares ou centenas de milhares de imagens automaticamente.
A compactação de imagem é fantástica. É essencial para tarefas de visão computacional de várias maneiras, especialmente ao economizar espaço ou aumentar a velocidade de processamento. Existem também muitos casos de uso fora da visão computacional sempre que você deseja reduzir o espaço no disco rígido ou economizar largura de banda. A compactação de imagens pode ajudar muito.
Ao compreender a teoria por trás disso e aplicá-la, você pode fazer coisas poderosas com seus projetos.
Lembre-se de que a chave para uma compactação eficaz é encontrar o ponto ideal entre a redução do tamanho do arquivo e a manutenção de uma qualidade visual aceitável para seu aplicativo.
Obrigado pela leitura e sinta-se à vontade para entrar em contato se tiver algum comentário ou dúvida!
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3