Автостереограммы

Открытие изображений в полном разрешении может улучшить эффект
Автостереограммы, 2004.

Заметка: если вы не встречались с автостереограммами, вы можете ввести “как смотреть стереограммы” в любом интернет поисковике, чтобы получить разносторонние советы. В кратце – цель – получить сфокусированное раздвоение изображения, чтобы каждый глаз видел другой фрагмент повторяющейся текстуры. Этого может быть проще достичь начиная близко к изображению, смотря сквозь него. Затем постепенно оталяя изображение, стараясь сохранить фокус немного дальше, чем изображение в реальности.

Будучи заинтересованным в 3D и, следовательно, восприятии глубины, моё внимание привлекли стереограммы. Особенно – автостереограммы (стереокартинки) основанные на повторении изображения, конечный продукт которых технологически прост и самодостаточен, а также наиболее синтетичен, в смысле передания чистого и содержательно не привязонного восприятия глубины. Стереограммы такого типа так же известны под торговой маркой “Магический Глаз” или “Magic Eye”.

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

Исходный код главной функции:

[+] Показать

[-] Спрятать

/* Note: I was self-teaching programming at the time, hence the dreadful form. The source is mostly provided as a future note to myself :) Might replace with a proper version if I get back to stereograms. */ double emi,dem,per,dr,dg,db,x1,x2; unsigned __int8 cr,cg,cb,fr,fg,fb; emi=(double)255/100*CSpinEdit2->Value;//Depth -% of 255, UI? for(int z=(Image1->Width/CSpinEdit1->Value)-1; z>=0; z--){//CSpinEdit1: Pereod size //iterate for every pattern repetition? for(int x=Image1->Width; x>0; x--){ for(int y=0; y<Image1->Height; y++){ //get depth dem=(double)GetRValue(Image2->Canvas->Pixels[x][y])/100*CSpinEdit2->Value;//depth magnitude for(per=dem; per>=1; per--){}//I didn't know how to modulo??? x1=x-(z*CSpinEdit1->Value)-(dem-per); x2=x-(z*CSpinEdit1->Value)-(dem-per+1); if(x1<0) {cr=GetRValue(Image1->Canvas->Pixels[x1+Image1->Width][y]); cg=GetGValue(Image1->Canvas->Pixels[x1+Image1->Width][y]); cb=GetBValue(Image1->Canvas->Pixels[x1+Image1->Width][y]);} else {cr=GetRValue(Image1->Canvas->Pixels[x1][y]); cg=GetGValue(Image1->Canvas->Pixels[x1][y]); cb=GetBValue(Image1->Canvas->Pixels[x1][y]);} if(x2<0) {fr=GetRValue(Image1->Canvas->Pixels[x2+Image1->Width][y]); fg=GetGValue(Image1->Canvas->Pixels[x2+Image1->Width][y]); fb=GetBValue(Image1->Canvas->Pixels[x2+Image1->Width][y]);} else {fr=GetRValue(Image1->Canvas->Pixels[x2][y]); fg=GetGValue(Image1->Canvas->Pixels[x2][y]); fb=GetBValue(Image1->Canvas->Pixels[x2][y]);} if(per!=0)dr=(fr*per)+(cr*(1-per)); else dr=cr; if(per!=0)dg=(fg*per)+(cg*(1-per)); else dg=cg; if(per!=0)db=(fb*per)+(cb*(1-per)); else db=cb; Image1->Canvas->Pixels[x-(z*CSpinEdit1->Value)][y]=RGB(dr,dg,db); }}Image1->Refresh();} ShowMessage("Complete!");

Карты глубины:

Добавить комментарий:  (первые два поля обязательны)

Публикуя комментарий вы соглашаетесь, что ваш IP адрес будет сохранён на данном сайте, для борьбы со спамом. Адрес вашей э-почты не будет видим публично. Имя/э-почта/линк опциональны и тоже будут сохранены. Адрес э-почты не будет показан публично, и нужен для предохранения вашего комментария от ложных заявок на авторство, а также для ответных комментариев, если выберете их получать. Узнать больше.

Комментарии показываются после модерации, что может занять некоторое время.