Хотелось получать стереоизображение в очки виртуальной реальности из одной камеры(ведь они делались под смартфон или планшет), чтобы дописать в нее дополненную реальность.
Поиски готового решения расстроили: лидар — дорого и громоздко; кинект — финансово и физически неподъемно; 3д сканер с лазером — время обработки.
Подумав, решил работать с тем что имеется, то есть камерой ноутбука.
Абстрагируемся пока от конкретной реализации и обратимся к алгоритму.
Все действо изначально происходит в трехмерном пространстве, есть плоскость изображения, которую можно вращать в любую сторону, у каждого приходящего пикселя берется освещенность одного из цветов или их совокупность и этот пиксель выносится перпендикулярно из плоскости изображения на число освещенности (0-255).
Получается что мы выносим пиксели исходного изображения перпендикулярно к его плоскости в зависимости от освещенности.
Как вы видите получается относительно сносное 3D, годное для получения стереоизображения.
Но это была картинка с выборкой по диапазону освещенности, вот что выйдет если фильтр снять:
Ну и в качестве бонуса пара изображений.
Исходный код довольно прост.
Используется язык Processing
Сдвиг выборки управляется sw (включите английскую раскладку).
import processing.video.*;
float rotx = 0;//переменные поворота
float roty = 0;
int countcol=1;//счетчик
float pixelBrightness=0; //освещенность пикселя
float Brightness=0;///освещеность
Capture cam;
int numPixels;//переменная количества пикселей
void setup() {
size(900,700, P3D);
cam = new Capture(this, 320,240);///запускаем камеру
cam.start();
numPixels = cam.width * cam.height;
frameRate(30);//кадры в секунду
}
void draw()
{
background(255);
translate(width/2.0, height/2.0-250, +200);//переместимся на середину
rotateY(roty);//поворот изображения
// rotateX(rotx);
if (cam.available() == true)
{
cam.read();//читаем камеру
cam.loadPixels();//загружаем пиксели
float col[]=new float[numPixels]; //создаем массив под хранение освещенности
loadPixels();
for (int i = 0; i < numPixels; i++) {
pixelBrightness =red(cam.pixels[i]); ///берем освещенность по красному цвету каждого пикселя
// pixelBrightness =brightness(cam.pixels[i]);//можете использовать любую освещенность
col[i]=pixelBrightness;//записываем освещенность в массив
// Brightness = red(cam.pixels[i]);
// float Brightness2 = blue(cam.pixels[i]);
// float Brightness3 = green(cam.pixels[i]);
updatePixels();//обновляем пиксели
}
translate(-160,120,0);//по очереди перебираем пиксели и отрисовываем их
for(int i=0;i<240;i++)
{
for(int j=0;j<320;j++)
{
if(countcol<numPixels)
{
if(col[countcol]<colfilter+50&&col[countcol]>colfilter-50)
{
fill(col[countcol]);
point(j*1.3,i*1.3,col[countcol]/2);
}
countcol++;
}}}
countcol=0;
}}
void mouseDragged() {
float rate = 0.01;
rotx += (pmouseY-mouseY) * rate;
roty += (mouseX-pmouseX) * rate;
}
void keyPressed() /////Управление положение выборки освещенности
{
if(key=='w')
{
colfilter++;
}
if(key=='s')
{
colfilter--;
}
}
Ну и сама софтина (нужны Java,JRE,x64)
Если что не так — пишите, исправлю.
Автор: Dorrin