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.
Лучше воспользоваться проффесиональным пакетом
Если самому, то в первом приближении так (что вполне очевидно):
при уменьшении — вычислить средний цвет по объединяемым точкам
при увеличении точка распространяет свой цвет на захватываемую область или более сложно — рассчитать градацию цвета для ступенчатого перехода от текущего цвета к соседнему по направлению. |
чо то мутно...
|
|
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) Область изображения стола.
Программа должна узнавать форму области изображения шара и аппроксимировать границы этой области (границы — это кривые линии).
При увеличении изображения должна учитываться форма каждой области и границы должны оставаться такими же четкими, как и в оригинале. То есть цвет граничащих пикселов одной области с пикселами другой области должен резко отличаться от цвета пикселов в других граничащих с этой областью областях. (Простите за тавтологию ) .
Понятно ?
Отредактировано 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
Эта статья поможет Вам выбрать направление в котором копать дальше, если первый вариант не подойдёт
|
|
Aptem |
Отправлено: 13.02.2006, 16:34 |
|
Мастер участка
Группа: Участник
Сообщений: 349
|
Спасибо большое. Интересные статьи. Примиму во внимание.
|
|
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
Эта статья поможет Вам выбрать направление в котором копать дальше, если первый вариант не подойдёт
|
Ну это то же самое, что и я писал, только в более растянутой форме и с лишними фактами.
Препятсятвие в том, что исходные коды ведь все равно не доступны, ге-ге . И предлагают только готовый исполняемый файл — за бешенные бабки, .
Так что ребят, надо работать самим !
|
|
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 раза,
а не в два.
А если в 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 раза,
а не в два.
А если в 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;
|
Теперь хотелось бы узнать каким образом можно УМЕНЬШИТЬ изображение. Есть какие-нибудь идеи?
|
|