C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Уменьшение/увеличение изображения, Использование интерполяции
Aptem
Отправлено: 08.02.2006, 05:01


Мастер участка

Группа: Участник
Сообщений: 349



Здравствуйте, коллеги.

Такая проблема. Необходимо написать функцию, которая может увеличивать и уменьшать изображение. Но использовать необходимо не функции типа StretchDraw и т.д., а написать свою на основе интерполяции. Может кто-нибудь сталкивался с подобной проблемой?

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

Спасибо за внимание.
AVC
Отправлено: 08.02.2006, 09:03


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE

функцию, которая может увеличивать и уменьшать изображение. Но использовать необходимо не функции типа StretchDraw и т.д., а написать свою на основе интерполяции. Может кто-нибудь сталкивался с подобной проблемой?

Сталкивался еще на заре проникновения "вражеской" техники. Делал подобное для CGA EGA.
Лучше воспользоваться проффесиональным пакетом
Если самому, то в первом приближении так (что вполне очевидно):
при уменьшении — вычислить средний цвет по объединяемым точкам
при увеличении точка распространяет свой цвет на захватываемую область или более сложно — рассчитать градацию цвета для ступенчатого перехода от текущего цвета к соседнему по направлению.
Aptem
  Отправлено: 08.02.2006, 14:19


Мастер участка

Группа: Участник
Сообщений: 349



QUOTE (AVC @ 08/02/2006, 09:03)
Сталкивался еще на заре проникновения "вражеской" техники. Делал подобное для CGA EGA.
Лучше воспользоваться проффесиональным пакетом
Если самому, то в первом приближении так (что вполне очевидно):
при уменьшении — вычислить средний цвет по объединяемым точкам
при увеличении точка распространяет свой цвет на захватываемую область или более сложно — рассчитать градацию цвета для ступенчатого перехода от текущего цвета к соседнему по направлению.

чо то мутно... sad.gif
Aptem
Отправлено: 11.02.2006, 19:22


Мастер участка

Группа: Участник
Сообщений: 349



И все таки, есть ли какие-нибудь осмысленные предложения по увеличению изображения собственными руками.
Grigoriy
Отправлено: 11.02.2006, 22:02


Мастер участка

Группа: Участник
Сообщений: 381



Простыми методами — качество ниже.
Сложными выше.
Я думал давно над этой проблемой, как можно меньше потерять качество при увеличении растрового изображения.
Я не могу быстро ответить, но рано или поздно отвечу и напишу алгоритм.
Aptem
Отправлено: 12.02.2006, 18:54


Мастер участка

Группа: Участник
Сообщений: 349



QUOTE (Grigoriy @ 11/02/2006, 22:02)
Простыми методами — качество ниже.
Сложными выше.
Я думал давно над этой проблемой, как можно меньше потерять качество при увеличении растрового изображения.
Я не могу быстро ответить, но рано или поздно отвечу и напишу алгоритм.

Я тоже долго думаю над этой проблемой. Есть вариант, обычная кусочно-линейная интерполяция. То есть просто восстанавливаем новые значения. Разве есть другие методы увеличения изображения?
Grigoriy
Отправлено: 12.02.2006, 21:32


Мастер участка

Группа: Участник
Сообщений: 381



QUOTE (Aptem @ 12/02/2006, 18:54)
Я тоже долго думаю над этой проблемой. Есть вариант, обычная кусочно-линейная интерполяция. То есть просто восстанавливаем новые значения. Разве есть другие методы увеличения изображения?

Есть !
Изображение нужно разделять программно на N-ое количество областей. Затем для каждой области составить аналитические выражения для кривых границ этой области. Внутри каждой такой области применить кусочно-линейную интерполяцию. А сами области просто масштабируются.
К чему это все я веду ?
Представь что тебя сфоткали.
На фото виден ты и окружающая среда.
Те пикселы, которые пренадлежат твоему изображению и граничат с пикселами изображения окружающей среды, имеют резко отличный цвет от пикселов, принадлежащих изображению окружающей среды и граничащих с твоими.
Если и для этих пикселов применить кусочно-линейную интерполяцию, то получится что при увеличении изображения твое изображение будет сливаться с изображением среды, а это неправильно.

Представим себе, что мы сфотографировали металлический шар (деталь шарикоподшипника), лежащий на черном столе, и освещаемый лампой.
Все правильное изображение этой картины должно включать в себя как минимум две четко отделенные области:
1) Область изображения шара;
2) Область изображения стола.
Программа должна узнавать форму области изображения шара и аппроксимировать границы этой области (границы — это кривые линии).
При увеличении изображения должна учитываться форма каждой области и границы должны оставаться такими же четкими, как и в оригинале. То есть цвет граничащих пикселов одной области с пикселами другой области должен резко отличаться от цвета пикселов в других граничащих с этой областью областях. (Простите за тавтологию biggrin.gif ) .
Понятно ?

Отредактировано Grigoriy — 12/02/2006, 21:35
Aptem
Отправлено: 13.02.2006, 13:47


Мастер участка

Группа: Участник
Сообщений: 349



Да понятно. Я так понимаю, что здесь попахивает классификацией в распознавании образов. Поскольку как можно "правильно" программно определить какому объекту принадлежит тот или иной пиксель. А если предположим на столе лежит не один, а три шара, да еще один расположен за другим.
Doga
Отправлено: 13.02.2006, 15:42


Мастер участка

Группа: Участник
Сообщений: 575



Для начала посмотрите здесь, возможно Вас устроит этот вариант:
http://www.relib.com/articles/article.asp?id=65

А вот здесь представлены результаты работы гораздо более крутых алгоритмов:
http://www.itc.ua/print.phtml?ID=16523
Эта статья поможет Вам выбрать направление в котором копать дальше, если первый вариант не подойдёт
smile.gif
Aptem
Отправлено: 13.02.2006, 16:34


Мастер участка

Группа: Участник
Сообщений: 349



QUOTE (Doga @ 13/02/2006, 15:42)
Для начала посмотрите здесь, возможно Вас устроит этот вариант:
http://www.relib.com/articles/article.asp?id=65

А вот здесь представлены результаты работы гораздо более крутых алгоритмов:
http://www.itc.ua/print.phtml?ID=16523
Эта статья поможет Вам выбрать направление в котором копать дальше, если первый вариант не подойдёт
smile.gif

Спасибо большое. Интересные статьи. Примиму во внимание.
Aptem
Отправлено: 13.02.2006, 17:23


Мастер участка

Группа: Участник
Сообщений: 349



Нашел в разделе Компоненты VCL — ImageLib Corporate Suite v6.0, но пока не скачиваю, поскоку сижу на выделенке и денег мало осталось на счету, хотел бы узнать у того кто скачал данную библиотеку.

Есть ли там что-то по увеличению размеров изображения???

Заранее спасибо за помощь.
Grigoriy
Отправлено: 13.02.2006, 21:33


Мастер участка

Группа: Участник
Сообщений: 381



QUOTE (Aptem @ 13/02/2006, 13:47)
Да понятно. Я так понимаю, что здесь попахивает классификацией в распознавании образов. Поскольку как можно "правильно" программно определить какому объекту принадлежит тот или иной пиксель. А если предположим на столе лежит не один, а три шара, да еще один расположен за другим.

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

А ещё я предполагаю, что так даже можно исправлять исходные изображения.

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

И вообще, я не видел ни одной проги, которая бы увеличивает изображение и получает его таким же четким, как и исходное. Может это можно сделать в Adobe Photoshop ?
Я еще буду пробовать составлять свой алгоритм.
Посмотрю, что у меня получится !
Grigoriy
Отправлено: 13.02.2006, 21:49


Мастер участка

Группа: Участник
Сообщений: 381



QUOTE (Doga @ 13/02/2006, 15:42)
А вот здесь представлены результаты работы гораздо более крутых алгоритмов:
http://www.itc.ua/print.phtml?ID=16523
Эта статья поможет Вам выбрать направление в котором копать дальше, если первый вариант не подойдёт
smile.gif

Ну это то же самое, что и я писал, только в более растянутой форме и с лишними фактами.
Препятсятвие в том, что исходные коды ведь все равно не доступны, ге-ге biggrin.gif . И предлагают только готовый исполняемый файл — за бешенные бабки, wink.gif .
Так что ребят, надо работать самим !
Aptem
Отправлено: 17.02.2006, 16:43


Мастер участка

Группа: Участник
Сообщений: 349



Кое что разъяснил, но остались вопросы:

Если мы решили увеличить картинку в два раза, то создаем новый массив (вдвое больше второго) и через одного переписываем значения из исходного изображения в новое, т.е. что-то типа этого:
было так: 4 6 2 9 1 5
а стало так: 4 * 6 * 2 * 9 * 1 * 5 ( * — это пустые значения )
Далее просто интерполируем эти самый * — значения и вроде бы все понятно и просто. НО! Как быть если мы решили увеличить изображения не в два раза, а, например, в 2,5 раза? Как тогда разместить элементы в новом массиве?

Спасибо за внимание.
Grigoriy
Отправлено: 17.02.2006, 17:39


Мастер участка

Группа: Участник
Сообщений: 381



Артём.

Я хочу поправить немного Ваши рассуждения.

Когда мы увеличиваем растровое изображение в два раза, то количество пикселов возрастает в 4 раза,
а не в два. cool.gif
А если в 2.5 раза, то — в 2.5*2.5 раза.

Значит и во столько же раз возрастет массив пикселов.

И в "дробном варианте" усреднение тоже не составляет проблем.
Алгоритм же приведен на странице
http://www.relib.com/articles/article.asp?id=65

Отредактировано Grigoriy — 17/02/2006, 17:39
Aptem
Отправлено: 17.02.2006, 18:45


Мастер участка

Группа: Участник
Сообщений: 349



QUOTE (Grigoriy @ 17/02/2006, 17:39)
Когда мы увеличиваем растровое изображение в два раза, то количество пикселов возрастает в 4 раза,
а не в два. cool.gif
А если в 2.5 раза, то — в 2.5*2.5 раза.

Вы абсолютно правы! Я просто привел пример с обычным одномерным массивом. Спасибо за замечание. Но все таки в приведенной вами ссылке не очень понятна схема получения новых значений. Не могли бы со своей стороны немного пояснить данный алгоритм. Заранее благодарен за помощь.

И еще:
QUOTE
Изображение нужно разделять программно на N-ое количество областей. Затем для каждой области составить аналитические выражения для кривых границ этой области. Внутри каждой такой области применить кусочно-линейную интерполяцию. А сами области просто масштабируются.

Как я понял вы просто хотите программно векторизовать изображение, точнее его контуры (пардон, контуры объектов), увеличить их без ухудшения качества, а то что внутри просто проинтерполировать. Правильно я вас понял?
Grigoriy
Отправлено: 17.02.2006, 22:10


Мастер участка

Группа: Участник
Сообщений: 381



Да, Артем.
Aptem
Отправлено: 18.02.2006, 18:01


Мастер участка

Группа: Участник
Сообщений: 349



Насколько я знаю, пока не существует автоматических программ-векторизаторов. Например, все растровые карты, применяемые в геологоразведке векторизуются вручную с помощью EasyTrace. Но если вы создадите подобный алгоритм, я думаю это будет существенный прорыв.
Grigoriy
Отправлено: 19.02.2006, 12:45


Мастер участка

Группа: Участник
Сообщений: 381



Например.
Знаете программу
ABBYY Fine Reader
она распознает тексты и даже тип шрифта.
Вот вам пример распознавания.

А как вам идея создания программы распознавания чертежей по эскизам, начерченным вручную ?
Aptem
Отправлено: 19.02.2006, 13:05


Мастер участка

Группа: Участник
Сообщений: 349



QUOTE (Grigoriy @ 19/02/2006, 12:45)
Например.
Знаете программу
ABBYY Fine Reader
она распознает тексты и даже тип шрифта.
Вот вам пример распознавания.

Разве FineReader векторизует изображения? А текст распознается посредством сравнения символа со стандартным набором символов (тот же файл ttf).
Aptem
Отправлено: 03.03.2006, 19:31


Мастер участка

Группа: Участник
Сообщений: 349



Хотелось бы все таки закончить данную тему. И так я наконец-то разобрался каким образом можно увеличить изображение, в качестве алгоритма интерполяции использовал так называемый метод "ближайшего соседа":
CODE

/*
 Изображение здесь представлено в виде одномерного массива (char *Array), после увеличения, данный массив достраивается до bmp-файла
*/
       double coeff = 1.5; // коэффициент увеличения
       int Height = IMAGE_HEIGHT; // исходные размеры изображения
       int Width = IMAGE_WIDTH;

       int nHeight = int((double)Height * coeff); // новые размеры
       int nWidth = int((double)Width * coeff);    // изображения
       int nLength = nWidth * nHeight;

       xFactor = (double)Width / (double)nWidth;
       yFactor = (double)Height / (double)nHeight;

       nArray = new char[nLength];

       for ( int x = 0; x < nWidth; x++ )
       {
         for ( int y = 0; y < nHeight; y++ )
         {
           temp_x = (int)( floor ( x * xFactor ) );
           temp_y = (int)( floor ( y * yFactor ) );
           nArray[ y*nWidth + x ] = Array[ temp_y*Width + temp_x ];
         }
       }

       Array = nArray;


Теперь хотелось бы узнать каким образом можно УМЕНЬШИТЬ изображение. Есть какие-нибудь идеи?

Вернуться в Вопросы программирования в C++Builder