Как сделать высокое качество масштабирования образа?

голоса
18

Я пишу код, чтобы масштабировать 32 битный RGBA изображения в C / C ++. Я написал несколько попыток, которые были довольно успешно, но они медленно и, самое главное качество изображения размером не является приемлемым.

Я сравнивал то же изображение масштабируется с помощью OpenGL (то есть мое видео карта) и моя рутина, и это миль друг от друга по качеству. Я Google Code Искал, мытой источник деревья, что я думал бы пролить некоторый свет (SDL, Allegro, WxWidgets, CxImage, GD, ImageMagick и т.д.), но, как правило, их код либо запутанным и разбросаны по всему месту или пронизана ассемблер и мало или нет комментариев. Я также прочитал несколько статей в Википедии и в других местах, и я просто не найти четкое объяснение того, что мне нужно. Я понимаю, основные понятия интерполяции и выборки, но я изо всех сил, чтобы получить правильный алгоритм. Я не хочу, чтобы полагаться на внешние библиотеки для одной обычной и должны преобразовать их формат изображения и обратно. Кроме того, я хотел бы знать, как сделать это сам так или иначе. :)

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

Вот что я ищу:

  1. Нет ассемблер (Я пишу очень переносимый код для нескольких типов процессоров).
  2. Нет зависимости от внешних библиотек.
  3. Я в первую очередь касается сворачивают, но и нужно написать подпрограмму масштаба позже.
  4. Качество результата и ясности алгоритма является наиболее важным (я могу оптимизировать его позже).

Моя процедура по существу имеет следующий вид:

DrawScaled(uint32 *src, uint32 *dst, 
      src_x, src_y, src_w, src_h, 
      dst_x, dst_y, dst_w, dst_h );

Благодаря!

UPDATE: Для уточнения, мне нужно что - то более продвинутое , чем коробка RESAMPLE для разукрупнения , которая размывает изображение слишком много. Я подозреваю , что я хочу , это какое - то бикубический (или другого) фильтра , который противоположен алгоритм бикубического UPSCALING (т.е. каждого пиксел назначения рассчитывается из всех источников способствующих пикселей в сочетании с алгоритмом взвешивания , который держит вещи острой.

пример

Вот пример того, что я получаю от алгоритма WxWidgets BoxResample против того, что я хочу на 256x256 растрового изображения масштабируется до 55x55.

  • www.free_image_hosting.net/uploads/1a25434e0b.png

И наконец:

  • www.free_image_hosting.net/uploads/eec3065e2f.png

оригинал 256x256 изображение

Задан 09/12/2008 в 16:05
источник пользователем
На других языках...                            


11 ответов

голоса
2

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

Идея заключается в том, чтобы принимать равномерно разнесенные выборки из исходного изображения; в вашем случае, 55 из 256, или один из каждых 4.6545. Просто вокруг числа, чтобы получить пиксель выбрать.

Ответил 10/12/2008 в 04:20
источник пользователем

голоса
2

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

Алгоритм бикубический может быть настроен на резкость по сравнению с артефактами - Я пытаюсь найти ссылку, я буду редактировать его, когда я делаю.

Edit: Это была работа Mitchell-Netravali, что я имел в виду, на который ссылается в нижней части этой ссылке:

http://www.cg.tuwien.ac.at/~theussl/DA/node11.html

Вы также можете посмотреть в Ланцоше передискретизацию в качестве альтернативы Bicubic.

Ответил 09/12/2008 в 19:00
источник пользователем

голоса
2

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

Ответил 09/12/2008 в 16:21
источник пользователем

голоса
2

Я нашел реализацию WxWidgets довольно легко изменить при необходимости. Это все C ++, так что никаких проблем с портативностью там. Единственное отличие состоит в том, что их реализация работает с неподписанных массивы CHAR (которые я нахожу, чтобы быть самым простым способом справиться с изображениями, так или иначе) с порядком байтов от RGB и альфа-компоненты в отдельном массиве.

Если вы обратитесь к «общему Src / / image.cpp» файл в исходном дереве WxWidgets есть функция субдискретизатор, которая использует метод выборки окна «wxImage :: ResampleBox» и функция вверх пересчетка называется «wxImage :: ResampleBicubic».

Ответил 09/12/2008 в 16:18
источник пользователем

голоса
1

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

Ответил 09/12/2008 в 20:41
источник пользователем

голоса
1

Intel имеет библиотеки IPP, которые обеспечивают высокую скорость алгоритмы интерполяции, оптимизированные для процессоров семейства Intel. Это очень хорошо, но это не бесплатно, хотя. Посмотрите на следующую ссылку:

Intel IPP

Ответил 09/12/2008 в 17:33
источник пользователем

голоса
1

Родовая статья от нашего любимого хозяина: Лучше Resizing Image , обсуждая относительные качества различных алгоритмов (и ссылки на другую статью CodeProject).

Ответил 09/12/2008 в 17:12
источник пользователем

голоса
1

Попробуйте использовать Adobe библиотеки Generic Image ( http://opensource.adobe.com/wiki/display/gil/Downloads ) , если вы хотите что - то готовое , а не только алгоритм.


Выписка из: http://www.catenary.com/howto/enlarge.html#c

Увеличить или уменьшить - С Исходный код Требует Виктор обработки изображений библиотеки для 32-разрядной Windows, V 5.3 или выше.


int enlarge_or_reduce(imgdes *image1)
{
   imgdes timage;
   int dx, dy, rcode, pct = 83; // 83% percent of original size

   // Allocate space for the new image
   dx = (int)(((long)(image1->endx - image1->stx + 1)) * pct / 100);
   dy = (int)(((long)(image1->endy - image1->sty + 1)) * pct / 100);
   if((rcode = allocimage(&timage, dx, dy,
      image1->bmh->biBitCount)) == NO_ERROR) {
      // Resize Image into timage
      if((rcode = resizeex(image1, &timage, 1)) == NO_ERROR) {
         // Success, free source image
         freeimage(image1);
         // Assign timage to image1
         copyimgdes(&timage, image1);
         }
      else // Error in resizing image, release timage memory
         freeimage(&timage);
      }
   return(rcode);
}

Этот пример изменяет область изображения и заменяет исходное изображение с новым изображением.

Ответил 09/12/2008 в 16:44
источник пользователем


голоса
0

В качестве последующих мер, Джереми Радд опубликовал эту статью выше. Он реализует фильтруется двупроходное изменения размера. Источниками являются C # , но это выглядит достаточно ясно , что я могу портировать его , чтобы дать ему попробовать. Вчера , что было гораздо труднее понять (очень плохо имена переменных) я нашел очень похожий код C. Я получил его , чтобы разобраться, из-работы, но это было очень медленно и не дает хорошие результаты , которые привели меня к мысли , что была ошибка в моей адаптации. Я , возможно, лучше удачи писать с нуля с этим в качестве ссылки, которую я буду стараться.

Но учитывая то, как два алгоритма работы проходят интересно, если есть не более быстрый способ сделать это, возможно, даже в один проход?

Ответил 09/12/2008 в 21:07
источник пользователем

голоса
0

Посмотрите на ImageMagick , которая делает все виды перемасштабирования фильтров.

Ответил 09/12/2008 в 18:57
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more