이미지 압축은 시각적 품질을 유지하면서 이미지를 보다 효율적으로 저장하고 전송할 수 있게 해주는 컴퓨터 비전의 중요한 기술입니다. 이상적으로는 최고의 품질을 갖춘 작은 파일을 갖고 싶습니다. 그러나 우리는 균형을 이루고 어느 것이 더 중요한지 결정해야 합니다.
이 튜토리얼에서는 이론과 실제 적용을 다루며 OpenCV를 사용한 이미지 압축에 대해 설명합니다. 마지막에는 컴퓨터 비전 프로젝트(또는 다른 프로젝트)를 위해 사진을 성공적으로 압축하는 방법을 이해하게 됩니다.
이미지 압축은 허용 가능한 수준의 시각적 품질을 유지하면서 이미지의 파일 크기를 줄이는 것입니다. 압축에는 두 가지 주요 유형이 있습니다.
자주 듣는 것처럼 "디스크 공간이 저렴하다"면 왜 이미지를 압축합니까? 소규모에서는 이미지 압축이 크게 중요하지 않지만 대규모에서는 매우 중요합니다.
예를 들어, 하드 드라이브에 이미지가 몇 개 있는 경우 해당 이미지를 압축하여 몇 메가바이트의 데이터를 저장할 수 있습니다. 하드 드라이브를 테라바이트 단위로 측정하는 경우 이는 큰 영향을 미치지 않습니다. 하지만 하드 드라이브에 100,000개의 이미지가 있다면 어떨까요? 일부 기본 압축은 실시간 시간과 비용을 절약해 줍니다. 성능 측면에서도 마찬가지다. 이미지가 많은 웹사이트가 있고 하루에 10,000명의 사람들이 웹사이트를 방문한다면 압축이 중요합니다.
우리가 그렇게 하는 이유는 다음과 같습니다:
이미지 압축 기술은 두 가지 유형의 중복성을 활용합니다.
공간 중복은 대부분의 자연 이미지에서 인접 픽셀이 유사한 값을 갖는 경향이 있다는 사실을 활용합니다. 이렇게 하면 부드러운 전환이 생성됩니다. 한 영역에서 다른 영역으로 자연스러운 흐름이 있기 때문에 많은 사진이 "실제처럼 보입니다". 인접한 픽셀의 값이 크게 다른 경우 "노이즈가 있는" 이미지가 나타납니다. 픽셀을 단일 색상으로 그룹화하여 이미지를 더 작게 만들어 이러한 전환을 덜 "부드럽게" 만들기 위해 픽셀이 변경되었습니다.
반면색상 중복은 이미지의 인접 영역이 유사한 색상을 공유하는 경우가 얼마나 많은지에 중점을 둡니다. 푸른 하늘이나 녹색 들판을 생각해 보세요. 이미지의 많은 부분이 매우 유사한 색상 값을 가질 수 있습니다. 공간을 절약하기 위해 함께 그룹화하여 단일 색상으로 만들 수도 있습니다.
OpenCV는 이러한 아이디어를 작업할 수 있는 견고한 도구를 제공합니다. 예를 들어 OpenCV의 cv2.inpaint() 함수는 공간 중복성을 사용하여 근처 픽셀의 정보를 사용하여 그림의 누락되거나 손상된 영역을 채웁니다. OpenCV를 사용하면 개발자는 cv2.cvtColor()를 사용하여 색상 중복과 관련된 여러 색상 공간 간에 이미지를 변환할 수 있습니다. 특정 종류의 이미지를 인코딩할 때 일부 색상 공간이 다른 색상 공간보다 더 효과적이기 때문에 이는 많은 압축 기술의 전처리 단계로 어느 정도 도움이 될 수 있습니다.
이제 이 이론 중 일부를 테스트해 보겠습니다. 그것을 가지고 놀자.
OpenCV의 Python 바인딩을 사용하여 이미지를 압축하는 방법을 살펴보겠습니다. 이 코드를 작성하거나 복사하세요:
여기에서 소스 코드를 얻을 수도 있습니다.
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}")
이 예에는 두 개의 매개변수를 사용하는 압축 이미지 함수가 포함되어 있습니다.
그런 다음 원본 이미지를 original_img에 로드하겠습니다. 그런 다음 동일한 이미지를 50% 압축하여 새 인스턴스인 압축 이미지에 로드합니다.
그런 다음 원본 이미지와 압축 이미지를 나란히 표시해 보겠습니다.
그런 다음 압축률을 계산하고 표시합니다.
이 예제에서는 OpenCV에서 JPEG 압축을 사용하여 이미지를 압축하는 방법을 보여줍니다. 품질 매개변수는 파일 크기와 이미지 품질의 균형을 제어합니다.
실행해 보겠습니다.
처음에 이미지를 보면 차이가 거의 없습니다. 그러나 확대하면 품질의 차이를 알 수 있습니다.
창을 닫고 파일을 살펴보면 파일 크기가 크게 줄어든 것을 확인할 수 있습니다.
또한, 품질을 더 낮추면 품질을 10%로 변경할 수 있습니다.
compressed_img = compress_image('sampleimage.jpg', quality=10)
결과는 훨씬 더 심각합니다.
그리고 파일 크기 결과도 더욱 극심해졌습니다.
이러한 매개변수를 아주 쉽게 조정하고 품질과 파일 크기 사이에서 원하는 균형을 얻을 수 있습니다.
압축의 영향을 평가하기 위해 다음과 같은 측정항목을 사용할 수 있습니다.
평균 제곱 오차(MSE)는 두 이미지가 서로 얼마나 다른지 측정합니다. 이미지를 압축할 때 MSE는 원본과 비교하여 압축된 이미지가 얼마나 변경되었는지 확인하는 데 도움이 됩니다.
두 이미지에서 해당 픽셀의 색상 차이를 샘플링하고 해당 차이를 제곱한 후 평균을 구하는 방식으로 이를 수행합니다. 결과는 단일 숫자입니다. MSE가 낮을수록 압축된 이미지가 원본에 더 가깝다는 의미입니다. 이에 비해 MSE가 높을수록 품질이 눈에 띄게 저하된다는 의미입니다.
이를 측정하는 Python 코드는 다음과 같습니다.
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}")
데모 이미지 압축은 다음과 같습니다.
PSNR(피크 신호 대 잡음비)은 압축 후 이미지 품질이 얼마나 저하되었는지를 나타내는 척도입니다. 이는 눈으로 흔히 볼 수 있지만 설정된 값을 할당합니다. 원본 이미지와 압축된 이미지를 비교하여 그 차이를 비율로 표현합니다.
PSNR 값이 높을수록 압축된 이미지의 품질이 원본에 더 가깝고 품질 손실이 적다는 것을 의미합니다. PSNR이 낮을수록 눈에 띄는 성능 저하가 더 심해집니다. PSNR은 MSE와 함께 사용되는 경우가 많으며 PSNR은 높을수록 더 나은 해석하기 쉬운 척도를 제공합니다.
다음은 이를 측정하는 Python 코드입니다.
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")
데모 이미지 압축은 다음과 같습니다.
압축 후 이미지를 "눈으로 확인"하여 품질을 결정하는 것은 괜찮습니다. 그러나 대규모에서는 스크립트를 사용하여 표준을 설정하고 이미지가 표준을 따르도록 하는 것이 훨씬 더 쉬운 방법입니다.
몇 가지 다른 기술을 살펴보겠습니다.
더 발전된 압축을 위해 OpenCV는 다양한 알고리즘을 지원합니다:
이미지를 PNG 형식으로 변환할 수 있는데, 여기에는 많은 장점이 있습니다. 다음 코드 줄을 사용하면 필요에 따라 압축을 0에서 9까지 설정할 수 있습니다. 0은 압축이 전혀 없음을 의미하고 9는 최대값을 의미합니다. PNG는 "무손실" 형식이므로 최대 압축에서도 이미지는 그대로 유지되어야 합니다. 가장 큰 절충안은 파일 크기와 압축 시간입니다.
다음은 OpenCV에서 PNG 압축을 사용하는 코드입니다:
cv2.imwrite('compressed.png', img, [cv2.IMWRITE_PNG_COMPRESSION, 9])
결과는 다음과 같습니다.
참고: 이 경우처럼 PNG 파일이 실제로 크기가 더 크다는 것을 알 수 있습니다. 이미지 내용에 따라 다릅니다.
이미지를 .webp 형식으로 변환할 수도 있습니다. 이것은 인기를 얻고 있는 새로운 압축 방법입니다. 나는 수년간 내 블로그의 이미지에 이 압축을 사용해 왔습니다.
다음 코드에서는 이미지를 webp 파일에 쓰고 압축 수준을 0에서 100으로 설정할 수 있습니다. 이는 0이므로 PNG의 배율과 반대입니다. 대신에 품질을 설정하기 때문입니다. 압축. 0으로 설정하면 파일 크기가 작고 손실이 심할 정도로 품질이 가장 낮기 때문에 이러한 작은 차이가 중요합니다. 100이 최고 품질이며, 이는 최고의 이미지 품질을 갖춘 대용량 파일을 의미합니다.
이를 가능하게 하는 Python 코드는 다음과 같습니다.
cv2.imwrite('compressed.webp', img, [cv2.IMWRITE_WEBP_QUALITY, 80])
결과는 다음과 같습니다.
이 두 가지 기술은 대량의 데이터를 압축하는 데 적합합니다. 수천 또는 수십만 개의 이미지를 자동으로 압축하는 스크립트를 작성할 수 있습니다.
이미지 압축은 환상적입니다. 특히 공간을 절약하거나 처리 속도를 높이는 경우 여러 면에서 컴퓨터 비전 작업에 필수적입니다. 하드 드라이브 공간을 줄이거나 대역폭을 절약하려는 경우 언제든지 컴퓨터 비전 외부에 많은 사용 사례가 있습니다. 이미지 압축은 많은 도움이 될 수 있습니다.
이론을 이해하고 적용함으로써 프로젝트에서 몇 가지 강력한 작업을 수행할 수 있습니다.
효과적인 압축의 핵심은 파일 크기 축소와 애플리케이션에 적합한 시각적 품질 유지 사이에서 최적의 지점을 찾는 것임을 기억하세요.
읽어주셔서 감사합니다. 의견이나 질문이 있으면 언제든지 문의해 주세요!
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3