Форум программистов, компьютерный форум CyberForum.ru

Эффект линзы - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.61
kelevrat
4 / 4 / 1
Регистрация: 06.06.2010
Сообщений: 18
19.06.2010, 13:50     Эффект линзы #1
Доброго времени суток. Вопрос по алгоритму линзы и его реализации. В инете ничего полезного не нашел. Находил реализованные алгоритмы на паскале и С++, но там мало что понятно и минимум пояснений. Хотелось бы найти хотя бы не реализованный понятный алгоритм...

Заранее спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
19.06.2010, 17:04     Эффект линзы #2
Рассмотрим достаточно простой вариант. Пусть нам надо включить круглую линзу с радиусом R = N/2 на участке N*N пикселей. Пусть в этой линзе будет показан исходный рисунок с увеличением, зависящим от расстояния до центра. Допустим, в самом центре увеличение в M раз, и оно линейно убывает до 1 у самого края линзы (в дальнейшем можно перейти к нелинейной зависимости).

Будем исходить из наиболее популярной системы индексации точек: координата x по горизонтали, y - по вертикали вниз, точка с координатами (0, 0) расположена в верхнем левом углу. В такой системе координатами центра будет точка (R, R). Расстоянием от точки (x, y) до центра будет
r = sqrt((x-R)^2 + (y-R)^2)
Для удобства можно переместить нулевую точку в центр:
x' = x - R, y' = y - R

Определим формулу для фактора увеличения в зависимости от расстояния до центра r:
F(r) = 1 + r*(M-1)/R
Фактор увеличения, очевидно, определяет взаимосвязь между расстояниями от центра для одной и той же точки на исходной картинке и на результирующей: r = r_old / F. При этом угол, под которым точка расположена относительно центра, неизменен. При условии постоянства угла изменение радиуса влечёт за собой пропорциональное изменение координат x', y'.
Собрав всё это вместе, мы получим следующий алгоритм:

для каждой точки (x, y) в интересующем нас квадрате:
- вычислить (x', y') = (x-R, y-R)
- определить расстояние до центра r = sqrt(x'^2 + y'^2)
- Если r>R, то
- занести по координатам (x, y) значение цвета из исходного изображения с теми же координатами: эта точка за пределами линзы.
- иначе:
- определить координаты на старом изображении: x_old = R + x'*F(r), y_old = R + y'*F(r)
- определить цвет точки по координатам x_old, y_old и занести его в формируемое изображение по координатам (x, y)
конец

Определять цвет точки в исходном изображении можно с разной степенью точности в зависимости от потребностей: округлять полученные x_old, y_old и брать ближайшее значение из исходного рисунка; простейшая линейная (точнее, билинейная) интерполяция по четырём ближайшим точкам; кубическая или более сложная фильтрация. В зависимости от выбранного метода получится более или менее гладкий эффект.
Изменение формулы F(r) позволит регулировать "увеличение" и геометрию искажений. Наиболее очевидным шагом в этом направлении будет замена линейной зависимости от r на квадратичную.
kelevrat
4 / 4 / 1
Регистрация: 06.06.2010
Сообщений: 18
19.06.2010, 19:51  [ТС]     Эффект линзы #3
А как достать цвет пикселя в 8 битном bmp?
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
19.06.2010, 19:54     Эффект линзы #4
Для начала неплохо загрузить этот bmp в память в соответствии с его структурой, подробно описанной в MSDN. В таком bmp есть таблица из 256 цветов в формате RGB, а собственно данные - номера цветов в этой таблице.
kelevrat
4 / 4 / 1
Регистрация: 06.06.2010
Сообщений: 18
19.06.2010, 20:35  [ТС]     Эффект линзы #5
это я понимаю. Загружаю в соответствии со структурой. А теперь мне нужно получить цвет какого то конкретного пикселя, например rastr[i][j](т.е. какой номер цвета у этого пикселя.)

Код
class Bmp{
	FILE * newf;
	BITMAPFILEHEADER bfh;
	BITMAPINFOHEADER bih;
	RGBQUAD *rgb;            // указатель на палитру в памяти
    char**data;				  // указатель на картинку в памяти

public:
   void loadf(char *fname){
	    if(fopen(fname,"r+")==NULL){cout<<fname<<" - Файла с таким именем нет!"<<endl;system("pause");}
		else{newf=fopen(fname,"r+");
          unsigned count=256;
		   // bfh.bfOffBits=sizeof(bfh)+sizeof(bih)+count*sizeof(RGBQUAD);
		    if(!rgb)
		    rgb=new RGBQUAD[count];
				
		 fseek(newf,0l,SEEK_SET);
		 fread(&bfh,sizeof(BITMAPFILEHEADER),1,newf);
	     fread(&bih,sizeof(BITMAPINFOHEADER),1,newf);
		 fread(rgb,sizeof(RGBQUAD),count,newf);//}
		  
		 int height=bih.biHeight;
		 int width=bih.biWidth;
         data = new char*[height];
		 fseek(newf,bfh.bfOffBits,SEEK_SET);
         	int t;
			for (int i = height - 1; i>0; i--)		// в цикле читаем картинку и пропускаем лишние байты
			{ data[i] = new char[bih.biWidth];
			      fread(data[i],1,bih.biWidth,newf);		//чтение
				  fread(&t,1,((3*bih.biWidth)%4),newf);	// пропуск
				 }
		}
   };
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
19.06.2010, 23:04     Эффект линзы #6
C
1
2
3
4
RGBQUAD Bmp::GetPixel(int i, int j)
{
    return rgb[(unsigned char)(data[i][j])];
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.06.2010, 14:41     Эффект линзы
Еще ссылки по теме:

MS Word Эффект линзы
Задачка на линзы
Задачка на линзы

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
kelevrat
4 / 4 / 1
Регистрация: 06.06.2010
Сообщений: 18
20.06.2010, 14:41  [ТС]     Эффект линзы #7
Цвет извлекаю. Теперь трудности с присваиванием этого цвета другому пикселю. Создаю переменную типа RGBQUAD и присваиваю цвет через явное приведение

RGBQUAD color;
data[i][j]=(*(char*)&color);

цвет передается другой либо черный, либо намного темнее или еще чтонибудь...

Добавлено через 14 секунд
Цвет извлекаю. Теперь трудности с присваиванием этого цвета другому пикселю. Создаю переменную типа RGBQUAD и присваиваю цвет через явное приведение

RGBQUAD color;
data[i][j]=(*(char*)&color);

цвет передается другой либо черный, либо намного темнее или еще чтонибудь...
Yandex
Объявления
20.06.2010, 14:41     Эффект линзы
Ответ Создать тему
Опции темы

Текущее время: 23:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru