Глубина сжатия изображения до максимально допустимой ошибки

Статьи по сжатию изображений часто фокусируются на создании наилучшего качества изображения (PSNR) с фиксированной степенью сжатия. Мне любопытно получить максимально возможную степень сжатия, учитывая максимально допустимую за пиксельную ошибку. Мой инстинкт заключается в том, чтобы с жадностью удалить наименьшие коэффициенты в преобразованных данных, отслеживать ошибку, которую я вызвал, пока я не смогу удалить больше, не пройдя максимальную ошибку. Но я не могу найти бумаги, подтверждающие это. Может ли кто-нибудь указать мне на эту проблему?


изменить

Позвольте мне дать более подробную информацию. Я пытаюсь сжать изображения глубины из 3D-сканеров, а не обычные изображения. Цвет не является фактором. Изображения глубины имеют большие гладкие пятна, но важны точные разрывы. Некоторые пиксели будут пустыми - вне диапазона сканера или низкого уровня достоверности - и не требуют сжатия.

enter image description here

Алгоритм должен работать быстро - оптимально с частотой 30 кадров в секунду, например, с Microsoft Kinect или, по крайней мере, где-то в области 100 миллисекунд. Алгоритм будет включен в библиотеку, которую я распространяю. Я предпочитаю минимизировать зависимости, поэтому предпочтительны схемы сжатия, которые я могу реализовать самостоятельно в достаточно небольшом количестве кода.

Ответ 1

Этот ответ не удовлетворит ваш запрос на ссылки, но он слишком длинный, чтобы опубликовать его как комментарий.

Во-первых, сжатие буфера глубины для создаваемых компьютером образов может применяться к вашему делу. Обычно это сжатие выполняется на аппаратном уровне с прозрачным интерфейсом, поэтому он обычно разработан, чтобы быть простым и быстрым. Учитывая это, может потребоваться поиск для сжатия буфера глубины.

Одной из основных проблем, с которыми вам придется столкнуться с трансформаторными компрессорами (DCT, Wavelets и т.д.), является то, что нет простого способа найти компактные коэффициенты, соответствующие вашим жестким максимальным критериям. (Проблема, с которой вы в конечном итоге выглядели, похожа на линейное программирование. Вейвлеты могут иметь локализованное поведение в большинстве своих базисных векторов, которые могут несколько помочь, но это все еще довольно неудобно.) Чтобы достичь требуемой точности, вам может потребоваться добавить еще один шаг уточнения, но это также добавит больше времени вычисления, сложности и приведет к еще одному несовершенству уровня энтропийное кодирование, что приводит к потере эффективности сжатия.

То, что вы хотите, более сродни сжатию без потерь, чем сжатие с потерями. В этом свете одним из подходов было бы просто выбросить биты под ваш порог ошибки: если ваша максимально допустимая ошибка равна X, а ваши глубины представлены в виде целых чисел, integer - разделите ваши глубины на X, а затем примените сжатие без потерь.

Еще одна проблема, с которой вы сталкиваетесь, - это представление глубины - в зависимости от ваших обстоятельств это может быть число с плавающей запятой, целое число, оно может быть в проективной системе координат или даже более причудливой.

Учитывая эти ограничения, я рекомендую такую ​​схему, как BTPC, поскольку он позволяет использовать более легко адаптированную вейвлет-схему, где ошибки более четко локализованы и более понятны и учитываются. Кроме того, BTPC продемонстрировал большую устойчивость ко многим типам изображений и хорошую способность обрабатывать непрерывные градиенты и острые края с низкой потерей точности - именно те качества, которые вы ищете.

Поскольку BTPC является прогностическим, не имеет особого значения то, как хранится ваш формат глубины - вам просто нужно изменить свой предиктор, чтобы принять во внимание вашу систему координат и числовой тип (целочисленный или плавающий).

Так как BTPC не делает очень много математики, он может работать довольно быстро и на обычных процессорах, хотя это может быть не так легко в векторизации, как вам бы хотелось. (Похоже, что вы, возможно, занимаетесь оптимизацией игр на низком уровне, поэтому это может быть серьезным для вас.)

Если вы ищете что-то более простое, я бы рекомендовал подход типа "фильтр" (аналогичный PNG) с привязкой Golomb-Rice. Вместо того, чтобы кодировать дельта идеально, чтобы в итоге получить сжатие без потерь, вы можете закодировать до уровня "достаточно хорошо". Преимущество этого в сравнении с компрессором стиля с квантованием, а затем без потерь - это то, что вы можете поддерживать большую непрерывность.

Ответ 2

"жадно удалять наименьшие коэффициенты" напоминает мне сжатие SVD, где вы используете данные, связанные с первыми k наибольшими собственными значениями, для приближения данных. Остальные малые значения собственных значений не содержат существенной информации и могут быть отброшены.
Большое k → высокое качество, низкое сжатие
Маленькое k → низкое качество, высокое сжатие

(отказ от ответственности: я понятия не имею, что я здесь говорю, но это может помочь)

Редактирование:
здесь является лучшей иллюстрацией сжатия SVD

Ответ 3

Я не знаю никаких ссылок в случае проблемы, которую вы предложили.

Однако одно направление, в котором я могу думать, использует методы оптимизации для выбора лучших коэффициентов. В этом отношении можно использовать такие методы, как генетические алгоритмы, восхождение на холмы, имитируемая аннигиляция.

Учитывая, что у меня есть опыт в генетических алгоритмах, я могу предложить следующий процесс. Если вы не знаете о генетическом алгоритме, я рекомендую вам прочитать страницу вики на генетических алгоритмах.

Можно подумать о вашей проблеме, выбрав подмножество коэффициентов, которые дают минимальную ошибку восстановления. Скажем, есть N коэффициентов. Легко установить, что существует 2 ^ N подмножеств. Каждое подмножество может быть представлено строкой на N двоичных чисел. Например, для N = 5, строка 11101 представляет, что выбранное подмножество содержит все коэффициенты, кроме коэффициента coeff4. С помощью генетических алгоритмов можно найти оптимальный бит. Целевая функция может быть выбрана как абсолютная ошибка между восстановленными и исходными сигналами. Тем не менее, я знаю, что вы можете получить ошибку нуля, когда все коэффициенты взяты.

Чтобы обойти эту проблему, вы можете выбрать функцию объектной функции с соответствующей функцией, которая препятствует объективному значению функции около нуля и является монотонно увеличивающейся функцией после порога. Функция, подобная | log (\ epsion + f) | может быть достаточно.

Если то, что я предлагаю, кажется вам интересным, сообщите мне. У меня есть реализация генетического алгоритма со мной. Но он приспособлен к моим потребностям, и вы, возможно, не в состоянии его адаптировать для этой проблемы. Я готов работать с вами над этой проблемой, поскольку проблема кажется интересной для изучения.

Дайте мне знать.

Ответ 4

Я думаю, что вы очень близки к решению, но есть проблема, о которой я думаю, вы должны обратить внимание. Поскольку разные коэффициенты вейвлетов соответствуют функциям с разным масштабом (и сдвигом), поэтому ошибка, возникающая при устранении частичного коэффициента, зависит не только от его значения, но и от его положения (особенно в масштабе), поэтому вес коэффициента должен быть равен что-то вроде w(c) = amp(c) * F(scale, shift), где amp (c) - амплитуда коэффициента, а F - функция, которая зависит от сжатых данных. Когда вы определяете такие вещи, проблема сводится к проблеме рюкзака, которая может быть решена многими способами (например, переупорядочить коэффициенты и устранить самый маленький, пока не получите пороговую ошибку на пикселе, на который влияет соответствующая функция). Трудная часть состоит в определении F(scale,shift). Вы можете сделать это следующим образом. Если данные, которые вы сжимаете, относительно стабильны (например, видео наблюдения), вы можете оценить F как среднюю вероятность получить недопустимую ошибку, исключающую компонент с заданным масштабом и сдвиг от разложения вейвлетов. Таким образом, вы можете выполнить декомпозицию SVD (или PCA) по историческим данным и вычислить "F (масштаб, сдвиг)" как взвешенное (с весами, равным собственным значениям) суммирование скалярных произведений компонента с заданным масштабом и смещение в собственные векторы F(scale,shift) = summ eValue(i) * (w(scale,shift) * eVector(i)) где eValue - собственное значение, соответствующее собственному вектору - eVector (i), w (масштаб, сдвиг) - вейвлет-функция с заданным масштабом и сдвигом.

Ответ 5

Итеративная оценка различных наборов коэффициентов не поможет вашей цели сжимать кадры так быстро, как они сгенерированы, и не поможет вам сдержать сложность.

Карты глубины отличаются от карт интенсивности несколькими способами, которые могут вам помочь.

  • Большие области "без данных" могут быть обработаны очень эффективно с помощью кодирования длины строки.
  • Погрешность измерения изображений интенсивности постоянна по изображению после вычитания фиксированного шума, но карты глубин от систем Kinects и стерео зрения имеют ошибки, которые увеличиваются как обратная функция глубины. Если это сканеры, на которые вы нацеливаетесь, вы можете использовать сжатие с потерями для более близких пикселей - поскольку ошибки, которые вводит ваша функция потерь, не зависят от ошибки датчика, общая ошибка не будет увеличена до тех пор, пока ошибка функции потери больше, чем ошибка датчика.
  • Команда Microsoft имела большой успех с очень низким алгоритмом потери, который в значительной степени основывался на кодировании длины (см. статью здесь), избивая JPEG 2000 с лучшим сжатием и отличной производительностью; однако часть их успеха, казалось, отошла от относительно грубых карт глубины, которые производит их датчик. Если вы нацеливаете Kinects, вам может быть сложно улучшить их метод.

Ответ 6

Я думаю, что вы ищете что-то вроде алгоритм JPEG-LS, который пытается ограничить максимальную ошибку пикселя. Несмотря на это, он в основном предназначен для сжатия естественных или медицинских изображений и плохо разработан для изображений глубины (которые более плавные).

  • Термин "сжатие без потерь" относится к алгоритму с потерями, для которого каждый восстановленный образец изображения отличается от соответствующего образца исходного изображения не более чем на заранее заданное значение (обычно небольшая) "потеря". Без потерь сжатие соответствует потерям = 0. ссылка на исходную ссылку

Ответ 7

Я бы попытался выполнить предварительную обработку изображения, а затем сжать общий метод, например PNG.

Предварительная обработка для PNG (сначала прочитайте this)

for y in 1..height
  for x in 1..width
    if(abs(A[y][x-1] - A[y][x]) < threshold)
       A[y][x] = A[y][x-1]
    elsif (abs(A[y-1][x] - A[y][x]) < threshold)
       A[y][x] = A[y-1][x]