Jeffrey Cross
Jeffrey Cross

Створення лазерного різання Zoetrope з обробкою і Kinect

Ця кодова панель показує, як створити фізичну zoetrope за допомогою обробки, Kinect і лазерного різака. Ескіз буде завантажено у фільмі, записаному з камери глибини Kinect, з використанням бібліотеки обробки OpenCV, щоб перетворити цей фільм у ряд контурів, і зберегти контури у векторній формі як файл DXF, який можна надіслати на лазерний різак. Я також роз'яснить дизайн механізму перегляду, який надає зорової лінії його обертання.

Про Зоетроп

Перед тим як стрибати в код, трохи культурної історії та натхнення. Zoetrope була популярна вікторіанська оптична іграшка, яка виробляла форму анімації з паперового кола. На колі, виробники zoetrope б друкувати ряд кадрів з анімації. Потім коло було б оточене непрозорим диском з вирізаною з нього серією щілин. Коли обертається паперовий круг, глядач дивиться на нього через щілини і бачить анімацію. Розрізи діяли як кінопроектор, дозволяючи глядачеві бачити лише один кадр за один раз у швидкій послідовності, що призвело до ілюзії руху.

Останнім часом люди почали з'ясовувати, як домогтися тієї ж ілюзії з тривимірними об'єктами. Художник Григорій Барсам'ян будує скульптури, що обертаються перед стробоскопом, щоб створити ілюзію руху. Скульптури складаються з ряду різних об'єктів на різних стадіях руху, а строби діють, як щілини в зоетропі, щоб створити ілюзію руху (Барсам'ян може бути знайомий деяким фанатам «Зробити» з нашого попереднього висвітлення: «Наполегливість» Григорія Барсам'яна) .

Pixar нещодавно підібрав трюк, щоб створити фізичну зоотероп для свого лобі. Аніматори були переконані, що фізична зоетопа є неперевершеною демонстрацією принципу анімації: перетворення серії нерухомих зображень в рухомі:

Отже, який рецепт для фізичної зоотеропи? Нам потрібна серія зображень, які представляють послідовні етапи руху. Тоді нам потрібно перетворити їх у різні фізичні об'єкти. Як тільки ми отримаємо їх, нам потрібен механізм, який може обертати їх. І, останнє, але не менш важливе, нам потрібен стробоскоп для «заморожування» кожного об'єкта в один кадр анімації.

Як ми можемо це зробити самі? Ну, щоб отримати цю серію об'єктів, ми збираємося витягувати силуети з фрагмента відео, згенерованого з Kinect. Потім ми перетворимо ці силуети на векторний файл, який можна використовувати для керування лазерним різаком, щоб вирізати серію акрилових об'єктів у формі кожного кадру нашої анімації.

Давайте зануритися.

Запис фільму глибини

Перше, що потрібно зробити, це завантажити Kinect бібліотеку Dan Shiffman для обробки і помістити її в папку "Обробка бібліотек". Якщо ви не знайомі з тим, як це зробити, Ден отримав чіткі інструкції на сторінці бібліотеки Kinect.

Ми збираємося використовувати цю бібліотеку для запису фільму глибин з Kinect. (Теоретично, ви можете також використовувати звичайну камеру і добре освітлену кімнату, але що б це було весело?) На щастя, запис власного фільму глибини - це лише кілька рядків коду від прикладу Kinect, який поставляється на кораблі. з бібліотекою обробки:

Обговорення

Давайте поговоримо про те, як це працює. По-перше, ми включаємо бібліотеку Kinect і бібліотеку обробки відео; нам знадобиться це пізніше, щоб записати фільм. Потім ми оголошуємо об'єкти Kinect і MovieMaker. MovieMaker - це об'єкт, який зробить роботу над записом виводу нашого ескізу у файл фільму.

У налаштуваннях ми встановлюємо частоту кадрів до 24 так, щоб вона відповідала запису відео. Ми також налаштовуємо ескіз на 640 на 480, щоб відповідати розміру відеозображення, що надходить з Kinect. Ми робимо деякі основні налаштування Kinect: скажіть нашому kinect об'єкту, щоб почати зчитування даних з пристрою та включити зображення глибини. Потім ми ініціалізуємо клас MovieMaker, надаючи йому параметр якості, тип файлу та ім'я файлу. Докладніше про те, як MovieMaker працює в документації "Обробка". Важливо, щоб частота кадрів, яку ми передаємо до MovieMaker, збігалася з частотою ескізу, щоб наше відео відтворювалося на правильній швидкості.

Наша функція малювання неймовірно проста. Все, що ми робимо, - це виклик kinect.getDepthImage () і вивести його на наш ескіз, використовуючи функцію Processing image (). Це покаже нам зображення у градаціях сірого, що представляє карту глибини, яку Kinect витягує зі сцени. Це буде чорно-біле зображення, де колір сірого кожного пікселя не відповідає кольору світла об'єкта, а від того, наскільки далеко він знаходиться від Kinect. Більш близькі об'єкти матимуть світліші пікселі, а віддалені об'єкти будуть темнішими. Пізніше ми зможемо обробити ці пікселі, щоб виділити об'єкти на певній глибині для нашого силуету.

Тепер, коли ми намалювали на екрані зображення глибини, все, що потрібно зробити, це захопити результат у новий кадр фільму, який ми записуємо (mm.addFrame ()). Останньою важливою деталлю ескізу є те, що ми використовуємо ключові події, щоб дати нам можливість зупинити і завершити фільм. Коли хтось натискає пробіл, фільм зупинить запис і збереже файл. Крім того, ми повинні пам'ятати, що на виході потрібно виконати деяку очистку Kinect, інакше ми отримаємо деякі помилки, коли ми зупиняємо наш ескіз.

Ось приклад того, як фільм, записаний за допомогою цього ескізу, виглядає так:

Тепер, якщо у вас немає Kinect, або у вас виникли проблеми з записом глибокого фільму, не впадайте у відчай! Ви можете грати разом з наступним кроком. Ви можете завантажити цей глибинний фільм про те, як я роблю стрибки з гнізд прямо з Vimeo: Kinect Test Movie для Laser Zoetrope. Я також завантажив фільм про глибину, який я використав для останньої лазерної зоотеропи, показаної вище, якщо ви хочете слідувати точно: Kinect Depth Test Movie. Цей пізній фільм включає Зака ​​Лібермана, художника і хакера в Нью-Йорку і одного з співзасновників OpenFrameworks, C ++ на основі двоюрідного брата Processing.

Створення файлу лазерного різака

Тепер, коли у нас є глибокий фільм, нам потрібно написати ще один ескіз обробки, який обробляє цей фільм, вибирає рамки для нашої анімації, знаходить контури нашої фігури і зберігає векторний файл, який ми можемо надіслати до лазерного різака.

Щоб виконати ці дії, ми використаємо функцію Обробка бібліотеки OpenCV і вбудовану функцію beginRaw () обробки. Створіть новий ескіз обробки, збережіть його, створіть папку "data" у папці "ескіз", перемістіть свій фільм глибин (названий "test_movie.mov") і вставте наступний вихідний код у ескіз (або завантажте його з файл lasercut_zoetrope_generator.pde):

Обговорення

Якщо ви запустите цей ескіз з другим тестовим фільмом, на який я зв'язався вище, він створить такий вивід:

…, А також збереже файл «full_output.dxf» у папці ескізу. Це векторний файл, який ми можемо ввести в Illustrator або будь-яку іншу програму розробки для остаточної обробки, щоб відправити на лазерний різак.

Тепер давайте подивимося на код.

У налаштуваннях ми завантажуємо файл test_movie.mov у OpenCV, що має бути знайомим з минулих повідомлень у OpenCV. Ми також називаємо beginRaw (), функцію обробки для створення векторних файлів. beginRaw () змусить наш ескіз записати весь його вивід у новий векторний файл, поки ми не викликатиме endRaw (), таким чином ми зможемо створити наш файл через кілька ітерацій циклу малювання. У цьому випадку ми створюємо файл DXF, а не PDF, оскільки цей формат легше обробляти для лазера, який потребує безперервних ліній, щоб отримати надійний вихід. PDF-файли, створені в процесі обробки, мають багато дискретних відрізків, які можуть призвести до фанк-результатів при розрізанні за допомогою лазера, включаючи повільнішу роботу та нерівномірну товщину.

Тепер, перш ніж зануритися в метод малювання, трохи про підхід. Ми хочемо витягти з нашого фільму 12 різних кадрів, які б створили хороші рамки для нашої анімації. Тоді ми хочемо, щоб OpenCV витягував їх контури (або "контур" у мові OpenCV), і, нарешті, ми хочемо намалювати їх у сітці на екрані, щоб вони не перекривалися, а остаточний DXF-файл міститиме всі кадри анімація.

Цей ескіз підходить до цих проблем, створюючи змінну “currentFrame”, яка визначається за межами циклу малювання. Потім, при кожному запуску циклу малювання, ця змінна збільшується, і ми використовуємо його для виконання всього, що нам потрібно: стрибати вперед у фільмі, переміщатися в іншу область ескізу, щоб малювати, і, нарешті, коли ми Завершивши малювання всіх 12 кадрів на екран, ми називаємо “endRaw ()” для завершення файлу DXF, так само, як ми назвали “mm.finish ()” у першому ескізі, щоб закрити файл фільму.

Отже, якщо врахувати загальну структуру, як нам намалювати контур для кожного кадру? Давайте розглянемо код:

opencv.jump (0,3 + карта (currentFrame * timeBetweenFrames, 0, 9, 0, 1)); opencv.read ();

Це говорить OpenCV, щоб перейти вперед у фільмі на певний проміжок часу. 0.3 - це відправна точка кадрів, які ми збираємося захопити, і це те, що я зрозумів за допомогою перевірки. Я намагався купувати різні цінності, щоразу проводити ескіз і бачити, з якими кадрами я закінчив і судити про те, чи зробили б вони хорошу анімацію. "0.3" означає час початку в секундах.

Ми хочемо, щоб всі наші кадри були рівномірно розподілені, щоб наша анімація відтворювалася чисто. Щоб досягти цього, ми додаємо збільшувану суму до нашого стрибка 0,3, залежно від того, на якому фреймі ми знаходимося. Як тільки ми підрахували час, ми читаємо фрейм фільму, використовуючи “opencv.read ()”

Наступні кілька рядків використовують оператор по модулю ("%") з номером поточного кадру, щоб намалювати кадри в сітці з чотирьох на три. Потім з'являється простий виклик OpenCV, який насправді досить прохолодний, враховуючи контекст:

opencv.threshold (150);

Це говорить нашому об'єкту opencv, щоб вирівнювати кадр до чистого чорно-білого зображення, усуваючи всі відтінки сірого. Вона вирішує, які частини буде триматися на основі значення градації сірого, яке ми переходимо, 150. Але оскільки значення градацій сірого в нашому глибинному зображенні відповідають фактичній фізичній відстані об'єктів, на практиці це означає, що ми усунули що-небудь ще надалі ніж пара футів, залишивши тільки тему, що виділяється на зображенні.

Якщо ви використовуєте своє власне зображення глибини, ви захочете експериментувати з різними значеннями, доки ви не побачите силует, який просто відображає малюнок, який потрібно захопити в анімації.

Наступні кілька рядків, перенесених між викликами "pushMatrix ()" і "popMatrix ()", є, мабуть, найбільш заплутаними в ескізі. На щастя, ми можемо розібрати їх на дві частини, щоб зрозуміти їх: переміщення та масштабування нашого образу та малювання силуету, розрахованого OpenCV.

Перші три рядки цього розділу не роблять нічого, крім зміни нашої системи відліку. pushMatrix () і popMatrix () - це дивна назва, що значно полегшує складний код малювання. Це дозволяє нам тимчасово змінити розмір і форму нашого перегляду, щоб ми могли використовувати один і той же код малювання знову і знову, щоб малювати в різних масштабах і на різних частинах екрану.

pushMatrix (); переклад (x + 20, y); шкала (0,2);

Ось як це працює. Спочатку ми називаємо pushMatrix (), що означає: «зберегти наше місце», щоб ми могли перейти до нього, коли ми називаємо popMatrix (). Потім ми називаємо “translate ()”, який переносить нас до іншої частини ескізу, використовуючи змінні x і y, встановлені вище на основі нашого поточного кадру. Потім ми називаємо "scale ()", так що все, що ми малюємо, поки наступний popMatrix () не буде на 20 відсотків від розміру, який зазвичай буде.

Результат цих трьох рядків полягає в тому, що ми можемо зробити частину OpenCV, що йде далі - обчислюючи і малюючи контур - без того, щоб думати про те, де на екрані це відбувається. Без pushMatrix ми повинні будемо додати наші значення x і y до всіх наших координат і помножити всі наші розміри на 0,2. Це робить речі набагато простішими.

Тепер код OpenCV:

Blob [] blobs = opencv.blobs (1, ширина * висота / 2, 100, true, OpenCV.MAX_VERTICES * 4); для (int i = 0; i

Цей код, звичайно, виглядає складним, але не все так погано. Найцікавішою є перша, яка називає “opencv.blobs ()”. Ця функція аналізує збережене зображення та шукає неперервні області, де всі суміжні пікселі мають однаковий колір. У випадку з нашим прикладом кіно, буде точно одна пляма, і вона буде навколо силует Зака. Використання цього порогу усунуло все інше з місця події. Якщо ви використовуєте мій інший приклад фільму або власний фільм про глибину, ви можете мати кілька крапель, і це нормально, ви просто закінчите з більш складним векторним файлом.

І як тільки ми дістанемося до цього, малювання цих крапель теж не погано. Ми перекриваємо масив з них, і кожна BLOB має матрицю точок всередині неї, яку ми отримуємо для створення векторів. В основному, ми граємо підключення точок: переходимо з кожної точки до чергової лінії малювання, поки не завершимо всю форму.

І це все, що потрібно для створення файлу DXF.

Підготовка до лазера

Після створення цього DXF-файлу вам доведеться перенести його в Illustrator або у вашу улюблену програму редагування векторних зображень для виконання деяких основних дій: групувати кожен кадр разом в один об'єкт, вирізати частини силуетів, які перекривають прямокутник, так щоб Малюнок буде фактично прикріплений до його бази, тощо. Я також вибрав 9 з цих дванадцяти кадрів, а потім дублював їх так, що я мав цикл анімації, а не той, який повертається назад до стартової постави. Тут ви завантажили остаточний файл Illustrator для перегляду: contour_animation_for_laser.ai

Як тільки ми отримаємо виріз контуру, останній крок полягає в розробці та вирізанні колеса, на якому вони будуть крутитися. Я придбав упорний підшипник (свого роду ледачий Сьюзан інженера), який дозволив би моєму диску вільно крутитися. Мій підшипник включав отвори на вершині для прикріплення до нього речей. Я виміряв відстань між ними, а потім склав конструкцію для диска, який міг би встановити на підшипник і утримувати кожний з кадрів анімації:

Отримання тільки правильного розміру для слотів так, що силуети будуть натискати вписуються в щільно без будь-якого клею взяли трохи експериментів і деякі помилкові запуски на лазер. Тут можна завантажити файл Illustrator для цього дизайну: contour_disc_for_laser.ai

Після того, як ви отримаєте ці два файли Illustrator, їх розрізання на лазері буде настільки ж простим, як натискання на друк. Буквально: ви насправді починаєте процес, натиснувши друку в Illustrator. Ви повинні заповнити кілька додаткових відомостей про налаштування потужності та швидкості лазера, але тоді ви перейдете до перегонів. Лазер виглядає таким чином у дії (не розрізаючи частину zoetrope у цьому випадку, але це той же лазер):

Сподіваємося, цей посібник дасть вам достатньо того, що потрібно для початку запису даних Kinect для глибин і використання його для створення векторних файлів, здатних до лазерного різання. Отримуйте задоволення!

Отримайте свій власний лазерний розріз Zoetropes!

У відповідь на всі великі реакції на цей проект, я запустив сайт, який фактично виробляє лазерно-розрізані zoetropes для покупки: PhysicalGIF.com. Ми пропонуємо комплекти для збирання зоопарків із анімованими дизайнерами GIF. Набори прийдуть з усім необхідним, щоб зібрати зоотероп, подібний до показаного тут: лазерно-вирізані частини, база, навіть стробоскоп. Зрештою ви навіть зможете завантажити власні GIF-файли, щоб перетворити їх у фізичну форму. Поверніться туди зараз, щоб зареєструватися, щоб отримати повідомлення, коли комплекти стануть доступними.

Докладніше: Ознайомтеся з усіма стовпцями Codebox тут. Відвідайте сторінку Make: Arduino для отримання додаткової інформації про цей популярний мікроконтролер для хобі

У сараї виробника

Початок роботи з обробкою Навчіться з комп'ютерним програмуванням легким способом за допомогою обробки, простої мови, яка дозволяє використовувати код для створення малюнків, анімації та інтерактивної графіки. Курси програмування зазвичай починаються з теорії, але ця книга дозволяє перейти безпосередньо до творчих і цікавих проектів. Це ідеальне рішення для тих, хто хоче вивчати базове програмування, і служить простим вступом до графіки для людей з деякими навичками програмування.

Поділитися

Залишити Коментар