Как стать автором
Обновить

Миллиард точек: 3 доллара против 8 миллионов рублей

Время на прочтение8 мин
Количество просмотров22K
Вот как в реале выглядит всевидящее око


Кстати, сканер дороже автомобиля. Tesla S. С авиадоставкой до подъезда в Москве

В этом посте будет описание самого дорогого (наверное) в мире и самого дешевого в мире 3d-сканера.


Разобрать (распилить) устройство по цене тесламобиля мне не дали, поэтому я заглянул в инструкцию. Пара фоток внутренностей оттуда.
На вопрос, а может ли 3d-сканер сделать селфи (если перед ним поставить зеркало), мне ответили, что у этих приборов нелады с отражающими поверхностями. Поэтому я взял череп с соседней полки и попробовал его отсканировать.



Вот такие красивые штуки создаются при помощи сканера


3D сканер Surphaser 25HSX


3D сканер Surphaser 25HSX является трехмерным лазерным сканером со сферической системой отклонения луча, предназначенным для формирования 3-х мерных моделей реальных объектов для последующего использования в различных областях:

— изготовление чертежей проектируемых деталей по прототипам;
— создание резервных копий музейных экспонатов и интерьеров;
— разработка компьютерных игр и рекламной мультипликации;

Работа сканера основана на использовании «Сканирующей головки» (hardware сканера) и управляющего компьютера, на котором установлено «Программное обеспечение» (software сканера), с помощью которого компьютер запускает процесс сканирования, принимает поток данных измерений из сканирующей головки, а после окончания сканирования обрабатывает эти данные, переводя их в форму облака точек объекта.



ТТХ
Сканирующая головка является входным устройством 3d сканера, которое является, по сути, электронным прибором для измерения геометрических величин.

При этом головка позволяет обеспечивать 3d сканеру Surphaser 25HSX следующие параметры:

  • Дальность до измеряемого объекта – 1.5 – 60 м;
  • Зона обзора сканирующей головки со сферической системой отклонения — большая часть поверхности сферы с угловыми размерами 240х180 град;
  • Дискретность измерений – 200 000 -1 000 000 точек в секунду;
  • Плотность распределения точек отсчета дальности -17-100 точек на градус
  • Время сканирования всей зоны обзора ~ 2 минуты (при плотности 17 точек на градус и дискретности 200 000 точек в секунду);
  • Точность измерения продольная – 1 мм и менее; поперечная 20-60 угловых секунд.
  • Сканирующая головка питается от источника постоянного тока 18-22 В, обеспечивающим ток до 3,3 А.


Одновременно сканирующая головка является устройством ввода-вывода. При этом головка обеспечивает передачу данных в цифровом виде со скоростью до 200 Мбайт/с.

Интерфейс связи с управляющим компьютером: USB-2.



Составные части Сканирующей головки для 3D сканера сферического типа
расшифровка
1- Модуль оптической развертки (выделен штриховой линией)
1.1- Дальномерная головка (выделена штриховой линией)
1.1.1- Лазерный модуль
1.1.2- Фотоприѐмный модуль
1.1.3- Объектив.
1.1.4- Радиотехнический модуль
1.1.5- Плата контроля луча
1.1.6- Коммутационная плата
1.2. – Система отклонения
1.2.1- Узел быстрого вращения
1.2.1.1- Вращающееся зеркало
1.2.2- Узел медленного вращения
1.3- Шасси
2.- Устройство выделения «полезного» сигнала
2.1- Плата АЦП
2.2- Цифровая плата
3- Плата питания
4- Кожух Сканирующей головки

Работа сканирующей головки состоит в том, что луч дальномерной системы (аналоговой частью которой является Дальномерная головка) с постоянной угловой скоростью поворачивается в пространстве. Развертка луча вокруг вертикальной оси путем поворота шасси производится медленно (0,05-0,2 об/мин), а развертка луча вокруг горизонтальной оси с помощью вращающегося зеркала — быстро (4-40 об/сек). При этом непрерывно с частотой около 200 кГц (при необходимости до 1 МГц) производится отсчет времени распространения света до текущей точки объекта (точнее фазовых сдвигов у отраженного луча на частотах модуляции интенсивности света). Данные фазовых измерений, а также данные о текущих значениях углов поворота передаются во внешнее устройство – управляющий компьютер для накопления этих данных и
последующего расчета по ним геометрии отражающей поверхности объекта.




Модуль оптической развёртки для сферического 3d сканера с системой отклонения с вращением только вокруг горизонтальной оси, подготовленный для транспортировки.


Оптическая схема Модуля оптической развертки
описание по элементам


Обозначения на схеме:
Оптические элементы из стекла
3 –линза 47464
4 – оптический фильтр 690.0 IF 40 U
7 – фокусирующая линза 46377
8 – защитное окно 18.105
11 – зеркало 18.106
14 – линза 18.101.
15 – линза 18.102.
16 – линза 47911 или 48692
17 – оптический фильтр 38 02 27 032
Прочие элементы
1 – корпус фотоприемного модуля
2 – приемный фотодиод
5 – корпус лазерного модуля
6 – лазерный диод
9 – деталь крепления защитного окна
10 – вращающееся зеркало
12 – фотодиод на плате контроля луча
13 – корпус объектива



Плата Лазерного модуля BL предназначена для управления полупроводниковым лазерным диодом HL6750MG. В рабочем режиме Плата обеспечивает формирование непрерывного оптического излучения с постоянной средней оптической мощностью и амплитудной модуляцией


Плата BP фотоприемного модуля предназначена для приема модулированного по интенсивности лазерного излучения с помощью лавинного фотодиода. В рабочем режиме Плата обеспечивает выделение модулирующего свет сигнала и его усиление.


Плата BR Радиотехнического модуля, являющегося частью модуля оптической развертки 3D сканера, предназначена для формирования комбинированного сигнала, модулирующего по интенсивности световой луч, преобразование (перевод на низкую частоту 1 МГц и усиление) принятого отраженного ВЧ сигнала и опорного ВЧ сигнала, выделение и усиление отраженного НЧ сигнала


Плата BS, являющаяся частью модуля оптической развертки 3D сканера, предназначена для формирования сигнала о наличии луча на выходе лазерного модуля. Для формирования сигнала используется только рассеянное излучение. В рабочем режиме выходное напряжение превышает 0,1 В при мощности луча более 3 мВт.

Сканирование



Вот так видит комнату 3д-сканер в предварительном режиме (можно выбрать нужную область, которую сканер будет зондировать)


Мир глазами 3д-сканера. Кто может разглядеть человека?


Та же комната в 3д-редакторе


Вот так видит череп обычный человек


Вся комната на этот раз не нужна, поэтому мы выбираем только тот участок с черепом в режиме предсканирования. Затем минут 5-10 сканер крутит своим оком, ищет хоббитов. Главное не попадаться на его пути, а то сожжет будет дефект. Сканер захватывает не только сам череп, но и участки которые далеко за ним. Это легко правится в редакторе.


Мимо человек проходил, попал в зону лазерного луча. Видите полосу? Не вставайте на пути когерентного света. С человеком все в порядке, а вот на скане это отразилось как «битый пиксель»

Немного про использование Surphaser`a в реальной жизни




еще фото














боевой корабль






часть системы охлаждения атомной станции

размер детали — несколько десятков метров


выявленные дефекты



3d-сканер за 3 доллара





  • Arduino с Arduino IDE
  • Processing IDE
  • немного LEGO
  • шаговый двигатель (например из принтера)
  • драйвер шагового двигателя и питание
  • лазер
  • веб-камера
  • работающая Meshlab


по компонентам
image
из старого OKI принтера. Делает полный оборот за 48 шагов (7,5 градусов за шаг),
3,7V, 200-250mA

image
Питание, драйвер и редуктор



image



image
CD, резиночки, клей, LEGO зеленая бумага

image
Камера — Creative Webcam Vista. она устаревшая и с плохим сенсором (640x480), и плохой оптикой (plastic lenses). Но есть одно преимущество. Автор ее имел в наличии.

image
Низкокачественный и дешевый лазер (~1$)приделан к цилиндрической линзе, сделанной из стеклянного стержня. (стержень из химической лаборатории). Угол между лазером и камерой 30 градусов

image
code
#include <Stepper.h>
Stepper oki(48,8,9); //see stepper tutorial in arduino.cc for info about that
const int ledPin = 13; // the pin that the LED is attached to
int incomingByte; // a variable to read incoming serial data into

void setup() {
// initialize serial communication:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
oki.setSpeed(60);
}

void loop() {
// see if there's incoming serial data:
if (Serial.available() > 0) {
// read the oldest byte in the serial buffer:
incomingByte = Serial.read();
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'S') {
digitalWrite(ledPin, HIGH);
oki.step(4);
}
// if it's an L (ASCII 76) turn off the LED:
if (incomingByte == 'K') {
digitalWrite(ledPin, LOW);
}
}
}


image

Processing
code:
import codeanticode.gsvideo.*;
import processing.serial.*;

//objects
PFont f;
GSCapture cam;
Serial myPort;
PrintWriter output;

//colors
color black=color(0);
color white=color(255);

//variables
int itr; //iteration
float pixBright;
float maxBright=0;
int maxBrightPos=0;
int prevMaxBrightPos;
int cntr=1;
int row;
int col;

//scanner parameters
float odl = 210; //distance between webcam and turning axle, [milimeter], not used yet
float etap = 120; //number of phases profiling per revolution
float katLaser = 25*PI/180; //angle between laser and camera [radian]
float katOperacji=2*PI/etap; //angle between 2 profiles [radian]

//coordinates
float x, y, z; //cartesian cords., [milimeter]
float ro; //first of polar coordinate, [milimeter]
float fi; //second of polar coordinate, [radian]
float b; //distance between brightest pixel and middle of photo [pixel]
float pxmmpoz = 5; //pixels per milimeter horizontally 1px=0.2mm
float pxmmpion = 5; //pixels per milimeter vertically 1px=0.2mm

//================= CONFIG ===================

void setup() {
size(800, 600);
strokeWeight(1);
smooth();
background(0);

//fonts
f=createFont(«Arial»,16,true);

//camera conf.
String[] avcams=GSCapture.list();
if (avcams.length==0){
println(«There are no cameras available for capture.»);
textFont(f,12);
fill(255,0,0);
text(«Camera not ready»,680,32);
}
else{
println(«Available cameras:»);
for (int i = 0; i < avcams.length; i++) {
println(avcams[i]);
}
textFont(f,12);
fill(0,255,0);
text(«Camera ready»,680,32);
cam=new GSCapture(this, 640, 480,avcams[0]);
cam.start();
}

//Serial (COM) conf.
println(Serial.list());
myPort=new Serial(this, Serial.list()[0], 9600);

//output file
output=createWriter(«skan.asc»); //plik wynikowy *.asc


}

//============== MAIN PROGRAM =================

void draw() {

PImage zdjecie=createImage(cam.width,cam.height,RGB);
cam.read();
delay(2000);
for (itr=0;itr<etap;itr++) {
cam.read();
zdjecie.loadPixels();
cam.loadPixels();
for (int n=0;n<zdjecie.width*zdjecie.height;n++){
zdjecie.pixels[n]=cam.pixels[n];
}
zdjecie.updatePixels();
set(20,20,cam);
String nazwaPliku=«zdjecie-»+nf(itr+1, 3)+".png";
zdjecie.save(nazwaPliku);
obroc();
delay(500);
}
obroc();
licz();
noLoop();

}

void licz(){
for (itr=0; itr<etap; itr++){

String nazwaPliku=«zdjecie-»+nf(itr+1, 3)+".png";
PImage skan=loadImage(nazwaPliku);
String nazwaPliku2=«odzw-»+nf(itr+1, 3)+".png";
PImage odwz=createImage(skan.width, skan.height, RGB);
skan.loadPixels();
odwz.loadPixels();
int currentPos;
fi=itr*katOperacji;
println(fi);

for(row=0; row<skan.height; row++){ //starting row analysis
maxBrightPos=0;
maxBright=0;
for(col=0; col<skan.width; col++){
currentPos = row * skan.width + col;
pixBright=brightness(skan.pixels[currentPos]);
if(pixBright>maxBright){
maxBright=pixBright;
maxBrightPos=currentPos;
}
odwz.pixels[currentPos]=black; //setting all pixels black
}

odwz.pixels[maxBrightPos]=white; //setting brightest pixel white

b=((maxBrightPos+1-row*skan.width)-skan.width/2)/pxmmpoz;
ro=b/sin(katLaser);
//output.println(b + ", " + prevMaxBrightPos + ", " + maxBrightPos); //I used this for debugging

x=ro * cos(fi); //changing polar coords to kartesian
y=ro * sin(fi);
z=row/pxmmpion;

if( (ro>=-30) && (ro<=60) ){ //printing coordinates
output.println(x + "," + y + "," + z);
}

}//end of row analysis

odwz.updatePixels();
odwz.save(nazwaPliku2);

}
output.flush();
output.close();
}

void obroc() { //sending command to turn
myPort.write('S');
delay(50);
myPort.write('K');
}


image
сканирование

image
облако точек

image
исходный объект

image
некое подобие облако точек и совы заметно невооруженным глазом

image
после обработки в MeshLab



еще один проект
image

image
hackaday.io/project/2021-3dollar-scanner

И все же у меня вопрос к знатокам: что составляет большую часть стоимости устройства за 8 миллионов рублей?

P.S.
Идея.
Есть задумка сделать обучающий проект (для школьников и студентов) с выходом на краудсорсинг. Можно вытащить 3d-сканер на ВДНХ и отсканировать «Рабочего и колхозницу», а потом напечатать много брелков и статуэток тем, кто сделал взнос. А еще фильм-обучалку снять и на youtube выложить.
Студентам — знания, компаниям — пиар, 3d-сообществу — полезная движуха.
Если есть ли у кого знакомые из администрации ВДНХ или может у кого есть подъемная платформа, пишите.

P.P.S.
Применение 3d-сканеров в играх



Теги:
Хабы:
Всего голосов 14: ↑13 и ↓1+12
Комментарии34

Публикации

Истории

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань