Сжатие изображений — это важнейшая технология компьютерного зрения, которая позволяет нам более эффективно хранить и передавать изображения, сохраняя при этом визуальное качество. В идеале нам бы хотелось иметь небольшие файлы наилучшего качества. Однако мы должны пойти на компромисс и решить, что важнее.
Это руководство научит сжатию изображений с помощью OpenCV, включая теорию и практическое применение. К концу вы поймете, как успешно сжимать фотографии для проектов компьютерного зрения (или любых других ваших проектов).
Сжатие изображения позволяет уменьшить размер файла изображения при сохранении приемлемого уровня визуального качества. Существует два основных типа сжатия:
Если «дисковое пространство дешево», как мы часто слышим, то зачем вообще сжимать изображения? В небольшом масштабе сжатие изображения не имеет большого значения, но в большом масштабе оно имеет решающее значение.
Например, если у вас на жестком диске есть несколько изображений, вы можете сжать их и сохранить несколько мегабайт данных. Это не имеет большого значения, если жесткие диски измеряются в терабайтах. Но что, если у вас на жестком диске 100 000 изображений? Некоторое базовое сжатие экономит реальное время и деньги. С точки зрения производительности это то же самое. Если у вас есть веб-сайт с большим количеством изображений и его посещают 10 000 человек в день, сжатие имеет значение.
Вот почему мы это делаем:
Методы сжатия изображений используют два типа избыточности:
Пространственная избыточность использует тот факт, что соседние пиксели имеют тенденцию иметь одинаковые значения в большинстве естественных изображений. Это создает плавные переходы. Многие фотографии «выглядят настоящими», потому что существует естественный переход от одной области к другой. Когда соседние пиксели имеют совершенно разные значения, вы получаете «шумные» изображения. Пиксели были изменены, чтобы сделать эти переходы менее «плавными», за счет группировки пикселей в один цвет, что сделало изображение меньше.
Избыточность цвета, с другой стороны, фокусируется на том, что соседние области изображения часто имеют одинаковые цвета. Представьте себе голубое небо или зеленое поле: большие части изображения могут иметь очень похожие цветовые значения. Их также можно сгруппировать и сделать одним цветом для экономии места.
OpenCV предлагает надежные инструменты для работы с этими идеями. Например, используя пространственную избыточность, функция cv2.inpaint() OpenCV заполняет недостающие или поврежденные области изображения, используя информацию из близлежащих пикселей. OpenCV позволяет разработчикам использовать cv2.cvtColor() для перевода изображений между несколькими цветовыми пространствами с учетом избыточности цвета. Это может быть в некоторой степени полезно в качестве этапа предварительной обработки во многих методах сжатия, поскольку некоторые цветовые пространства более эффективны, чем другие, при кодировании определенных типов изображений.
Сейчас мы проверим некоторые из этих теорий. Давайте поиграем с этим.
Давайте рассмотрим, как сжимать изображения с помощью привязок Python OpenCV. Запишите этот код или скопируйте его:
Вы также можете получить исходный код здесь
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}")
Этот пример содержит функцию compress_image, которая принимает два параметра:
Затем мы загрузим исходное изображение в original_img. Затем мы сжимаем то же изображение на 50 % и загружаем его в новый экземпляр compressed_image.
Затем мы покажем исходное и сжатое изображения, чтобы вы могли просматривать их рядом.
Затем мы вычисляем и отображаем степень сжатия.
В этом примере показано, как сжать изображение с помощью сжатия JPEG в OpenCV. Параметр качества управляет размером файла и соотношением качества изображения.
Давайте запустим:
При первом взгляде на изображения вы не увидите особой разницы. Однако при увеличении масштаба вы увидите разницу в качестве:
И после закрытия окон и просмотра файлов мы видим, что размер файла значительно уменьшился:
Кроме того, если мы снизим его еще больше, мы сможем изменить качество на 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 — это формат без потерь, поэтому даже при максимальном сжатии изображение должно остаться неповрежденным. Большим компромиссом является размер файла и время сжатия.
Вот код для использования сжатия PNG с OpenCV:
cv2.imwrite('compressed.png', img, [cv2.IMWRITE_PNG_COMPRESSION, 9])
И вот наш результат:
Примечание. Иногда вы можете заметить, что файлы PNG на самом деле больше по размеру, как в этом случае. Это зависит от содержания изображения.
Вы также можете конвертировать изображения в формат .webp. Это новый метод сжатия, который набирает популярность. Я использую это сжатие изображений в своем блоге уже много лет.
В следующем коде мы можем записать наше изображение в файл webp и установить уровень сжатия от 0 до 100. Это противоположно масштабу PNG, потому что 0, потому что мы устанавливаем качество вместо сжатие. Это небольшое различие имеет значение, поскольку значение 0 соответствует минимально возможному качеству с небольшим размером файла и значительными потерями. 100 — самое высокое качество, что означает большие файлы с лучшим качеством изображения.
Вот код Python, позволяющий это сделать:
cv2.imwrite('compressed.webp', img, [cv2.IMWRITE_WEBP_QUALITY, 80])
И вот наш результат:
Эти два метода отлично подходят для сжатия больших объемов данных. Вы можете написать сценарии для автоматического сжатия тысяч или сотен тысяч изображений.
Сжатие изображений просто фантастическое. Это важно для задач компьютерного зрения во многих отношениях, особенно при экономии места или увеличении скорости обработки. Существует также множество вариантов использования за пределами компьютерного зрения в любое время, когда вы хотите уменьшить пространство на жестком диске или сэкономить пропускную способность. Сжатие изображений может очень помочь.
Понимая теорию, лежащую в ее основе, и применяя ее, вы сможете добиться значительных успехов в своих проектах.
Помните, что ключ к эффективному сжатию — найти золотую середину между уменьшением размера файла и поддержанием приемлемого визуального качества для вашего приложения.
Спасибо за чтение. Если у вас есть комментарии или вопросы, обращайтесь!
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3