{"id":2961,"date":"2013-08-16T12:54:00","date_gmt":"2013-08-16T19:54:00","guid":{"rendered":"https:\/\/pkmital.com\/home\/?post_type=pkm_teaching&#038;p=2961"},"modified":"2023-08-22T18:00:04","modified_gmt":"2023-08-23T01:00:04","slug":"workshops-in-creative-coding-mobile-and-computer-vision","status":"publish","type":"pkm_teaching","link":"https:\/\/pkmital.com\/home\/teaching\/workshops-in-creative-coding-mobile-and-computer-vision\/","title":{"rendered":"Goldsmiths, University of London | Workshops in Creative Coding \u2013 Mobile and Computer Vision"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">About<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is a 10-week Master\u2019s course covering Mobile and Computer Vision development using the openFrameworks creative coding toolkit at Goldsmiths, Department of Computing. Taught to MSc Computer Science, MSc Cognitive Computing, MSc Games and Entertainment, MA Computational Arts, and MFA Computational Studio Arts students.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Introduction<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is the homepage for the Master\u2019s course in Mobile and Computer Vision development using the openFrameworks platform hosted at Goldsmiths, University of London. This site will hold lecture material, code samples and additional resources.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">[UPDATE]: Final presentations are on Monday (April 22nd) and Wednesday (April 24th) from 5 \u2013 7 p.m. in RHB 251. Make sure your group has e-mailed me to say which presentation time slot you\u2019d like.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Resources<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Helpful C++ Resources &amp; Books<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">I often Google search things like how to manipulate&nbsp;<code>strings<\/code>,&nbsp;<code>vectors<\/code>, data structures like&nbsp;<code>lists<\/code>&nbsp;or&nbsp;<code>maps<\/code>&nbsp;and find resources on&nbsp;<a href=\"http:\/\/stackexchange.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">stackexchange<\/a>&nbsp;or&nbsp;<a href=\"http:\/\/stackoverflow.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">stackoverflow<\/a>. But it is also helpful to have some concrete resources for C++. Here are some that I\u2019ve been recommended before:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/www.cplusplus.com\/doc\/tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">C++ Tutorial<\/a><br><a href=\"http:\/\/www.cprogramming.com\/tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Another C++ Tutorial<\/a><br><a href=\"http:\/\/books.google.co.uk\/books?id=tTFhAAAACAAJ&amp;dq=Bjarne+Stroustrup&amp;hl=en&amp;sa=X&amp;oi=book_result&amp;ct=result&amp;redir_esc=y\" target=\"_blank\" rel=\"noreferrer noopener\">Bjarne Stroustrup\u2019s The C++ Programming Language<\/a><br><a href=\"http:\/\/books.google.co.uk\/books?id=4UrFQFZWmqsC&amp;dq=Bjarne+Stroustrup&amp;source=gbs_book_similarbooks\" target=\"_blank\" rel=\"noreferrer noopener\">Deitel &amp; Deitel\u2019s C++ How to Program<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For developing on the iPhone, the Apple developer pages are essential reading:&nbsp;<a href=\"https:\/\/developer.apple.com\/library\/ios\/navigation\/\">Apple iOS Developer Library<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also some openFrameworks specific resources:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/www.jeffcrouse.info\/teaching\/intro-to-of.html\" target=\"_blank\" rel=\"noreferrer noopener\">Jeff Crouse\u2019s Introduction to openFrameworks<\/a><br><a href=\"http:\/\/forum.openframeworks.cc\/\" target=\"_blank\" rel=\"noreferrer noopener\">openFrameworks Forum<\/a>&nbsp;(ask questions, find answers to questions already asked)<br><a href=\"http:\/\/www.openframeworks.cc\/documentation\/\" target=\"_blank\" rel=\"noreferrer noopener\">openFrameworks Documentation<\/a><br><a href=\"http:\/\/ofxaddons.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">oepnFrameworks addons<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Places to find interesting applications:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/creativeapplications.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">creativeapplications.net<\/a><br><a href=\"http:\/\/createdigitalmotion.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">createdigitalmotion.com<\/a><br><a href=\"http:\/\/createdigitalmusic.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">createdigitalmusic.com<\/a><br><a href=\"http:\/\/thecreatorsproject.com\/en-uk\/\" target=\"_blank\" rel=\"noreferrer noopener\">thecreatorsproject.com<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And my previous courses using openFrameworks:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/archive.pkmital.com\/teaching\/va-workshop-audiovisual-processing-for-ios\/\">Audiovisual Processing for iOS<\/a><br><a href=\"http:\/\/archive.pkmital.com\/teaching\/\">More\u2026<\/a><\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Assignments<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Assignment 1<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/archive.pkmital.com\/wp-content\/uploads\/2013\/01\/mobile-project.pdf\">Assignment 1: Mobile<\/a><br>EDIT: Note that group presentations will occur in RHB256 on Monday the 18th and Tuesday the 19th at 6 p.m.<\/p>\n\n\n\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-1.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-1.\"><\/object><a id=\"wp-block-file--media-7b4015cb-dfc5-448f-8da8-2250ade627eb\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-1.pdf\">Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-1<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-1.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-7b4015cb-dfc5-448f-8da8-2250ade627eb\">Download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Assignment 2<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/archive.pkmital.com\/wp-content\/uploads\/2013\/01\/cv-project.pdf\">Assignement 2: Computer Vision<\/a><\/p>\n\n\n\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-2.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-2.\"><\/object><a id=\"wp-block-file--media-b1627627-93ca-4b70-a89a-3d5a7fd1bd58\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-2.pdf\">Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-2<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-2.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-b1627627-93ca-4b70-a89a-3d5a7fd1bd58\">Download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Mobile Module Introduction<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Introduction<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">For the first 5 weeks, we will cover mobile development. Please make sure you already have a coding environment setup to use the iOS branch of openFrameworks v0073:&nbsp;<a href=\"http:\/\/openframeworks.cc\/download\" target=\"_blank\" rel=\"noreferrer noopener\">openFrameworks<\/a>. You will want to get the iOS version which only works on OSX for these first 5 weeks. The latter 5 weeks we will work on Computer Vision. For this portion, you will need to get another branch of openFrameworks suitable for your operating system (OSX\/Windows\/Linux). NOTE: when you download openFrameworks, there is no application included which you run (like Processing). You basically get a zip file with a bunch of code in different directories.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To start programming in openFrameworks, we usually start with a \u201cproject file\u201d. In OSX, this is an extension of \u201c.xcodeproj\u201d and for Visual Studio, it is \u201c.vcproj\u201d or \u201c.sln\u201d. We open this project file using an IDE, an integrated development environment. For OSX, this is XCode, and for Windows, this is Code Blocks or Visual Studio. You can get all of these programs for free as a student (and legally too). The IDE comes with a lot of tools to help us program and has nothing to do with openFrameworks at all. openFrameworks is simply a huge set of libraries that make it easy to code complicated programs quickly. The IDE gives us a lot of features like code completion (automatically guessing what we want to code), compiler (turning our C++ code into assembly\/machine code), linker (combining all of our compiled code into an executable program), and debugger (executing a program and being able to look at where the program is in your code at the same time).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 1: XCode, openFrameworks<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Introduction to iOS, openFrameworks, and XCode.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>iOS<\/strong><\/p>\n\n\n\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-3.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-3.\"><\/object><a id=\"wp-block-file--media-a75079f4-5faf-4ee0-94c3-9494ccd92ac9\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-3.pdf\">Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-3<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-3.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-a75079f4-5faf-4ee0-94c3-9494ccd92ac9\">Download<\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/archive.pkmital.com\/wp-content\/uploads\/2013\/01\/week1.pdf\">Week 1 Slides<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>openFrameworks<\/strong>:<br>\u2013&nbsp;<a href=\"http:\/\/www.openframeworks.cc\/\">http:\/\/www.openframeworks.cc\/<\/a><br>\u2013 open-source creative coding toolkit for writing software<br>\u2013 provides many high-level classes and abstractions which are cross-platform for a collection of libraries including:&nbsp;<em>OpenCV, Vector\/Matrix Math, Graphics using OpenGL, Mesh, OBJ, VBO, Shaders, Audio\/Video input\/output\/saving, Kinect, File\/Directory access\/manipulation, TCP\/IP\/UDP\/OSC, Threading, Physics engine, Synthesizers, iPhone\/Android integration (GPS\/Compass\/UI\/OpenGL\/Maps\/Audio\/Video), \u2026<\/em><br>\u2013 project generator (v0072+) gets you started with a new openFrameworks project quickly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>XCode<\/strong><br>\u2013 how to set the current \u201cscheme\u201d, \u201ctarget settings\u201d, \u201cbuild settings\u201d, and \u201carchitecture\u201d.<br>\u2013 including header\/source files<br>\u2013 including frameworks<br>\u2013 creating new files<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>obj-c + c++<\/strong>:<br>\u2013 ability to retain cross-platform functionality in c++ code<br>\u2013 no need to touch obj-c unless doing specific interface code or extending functionality of existing openFramework classes<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lab<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Try running the following examples included with openFrameworks:&nbsp;<em>emptyExample, graphicsExample, fontsExample<\/em>. Spend a 4-5 minutes looking at the&nbsp;<code>testApp.h<\/code>&nbsp;and&nbsp;<code>testApp.mm<\/code>&nbsp;files for each project to get an idea for how the program was created. Be sure to have a look at the&nbsp;<code>touchDown<\/code>,&nbsp;<code>touchUp<\/code>, and&nbsp;<code>touchMoved<\/code>&nbsp;methods to get an idea for how to access where the user is touching on a screen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now use the project generator to create a new openFrameworks project that we\u2019ll open using XCode. The project generator is an application which creates an XCode project and sets up all the openFrameworks libraries and path settings within the project so we don\u2019t have to. You can find it inside your openFrameworks download inside the directory, \u201cprojectGenerator\u201d. Give your sketch any name, such as \u201clab1-ex1\u201d, use the default location of \u201cmyApps\u201d, and click the \u201cGENERATE\u201d button. We won\u2019t need to use any other features of the project generator at this time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Navigate to the directory where you told the projectGenerator to create an app and open the \u201c.xcodeproj\u201d file. For your first exercise, create a class which draws a button (e.g. using&nbsp;<code>ofRect<\/code>). Have the button change color (<code>ofSetColor<\/code>) when a user presses within the boundaries of the button. You\u2019ll want to define points for the button using&nbsp;<code>ofPoint<\/code>&nbsp;and test whether the touch coordinates are within the button\u2019s boundaries using&nbsp;<code>ofWithin<\/code>. Try having more than one on the screen. See if you can have the button perform a specific action, such as making a sound, or recording the camera image.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Please, while trying this exercise, DO NOT COPY AND PASTE FROM EXISTING CODE. You may use existing code as a reference, but manually type every single character and refer to what you are typing mentally in your mind. Reflect on what each statement is doing and if you have *ANY* doubt, please ask someone next to you or feel free to ask me. Don\u2019t give up if you do not finish by the end of the lab. As a baseline, if you have about 12 hours of lecture\/lab time per week between 5 courses, you should be spending 6 hours at home per week for this course outside of lectures\/labs reflecting on this material and pursuing the lab\/lecture material in greater detail.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 2: Maximilian, Box2D<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Introduction to ofxMaximilian and ofxBox2D.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ofxMaximilian<\/strong><br><a href=\"http:\/\/maximilian.strangeloop.co.uk\/\" target=\"_blank\" rel=\"noreferrer noopener\">Maximilian<\/a>&nbsp;is an open-source, lightweight, c++ audio library developed here at Goldsmiths, University of London by Mick Grierson and Chris Kiefer. You can use it for doing synthesis (oscillators, granular time\/pitch stretching\/shifting, atomic), filtering (LPF, band, HPF, envelope), compression, limiting, mixing, sound fx (delay, flanging, chorus, distortion), FFT\/IFFT, and sample loading\/writing (WAVE).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Have a look at the basic library here:<br><a href=\"https:\/\/github.com\/micknoise\/Maximilian\/blob\/master\/ofxMaxim\/ofxMaxim\/libs\/maximilian.h\" target=\"_blank\" rel=\"noreferrer noopener\">maximilian.h<\/a><br><a href=\"https:\/\/github.com\/micknoise\/Maximilian\/blob\/master\/ofxMaxim\/ofxMaxim\/libs\/maximilian.cpp\" target=\"_blank\" rel=\"noreferrer noopener\">maximilian.cpp<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And some&nbsp;<a href=\"https:\/\/github.com\/micknoise\/Maximilian\/tree\/master\/maximilian_examples\" target=\"_blank\" rel=\"noreferrer noopener\">examples<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ofxBox2D<\/strong><br><a href=\"http:\/\/box2d.org\/about\/\" target=\"_blank\" rel=\"noreferrer noopener\">Box2D<\/a>&nbsp;is an open-source library for 2D physical modeling. With it, you can easily simulate 2D physics and collisions using really highly optimized code.<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lab<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>Part 1<\/strong><br>If you were having trouble in last week\u2019s assignment, feel free to have a look at my code for the button class below. I\u2019ve commented it so read through the functions and try to understand what they do.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>myButton.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2013 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n\/\/ header files declare classes...\n \n#pragma once\n \n#include &quot;ofMain.h&quot; \/\/ this lets us use openFrameworks\n \n\/\/ enum&#039;s are like integers but have names for their values instead of numbers.\n\/\/ so instead of an int being equal to 0, you have a buttonState equal to button_default...\n\/\/ and instead of an int being equal to 1, you have a buttonState equal to button_pressed...\nenum buttonState {\n    button_default = 0,\n    button_pressed = 1\n};\n \nclass myButton\n{\npublic:\n \n    \/\/--------------------------------------------------------------\n    \/\/ this is a constructor.  every c++ class has one.  it is the same name as the class\n    \/\/ it is automagically called when you create a new instance of this class.  you\n    \/\/ can put any setup of your object inside of this function.\n    myButton();\n \n    \/\/--------------------------------------------------------------\n    \/\/ we&#039;ll draw our button inside this function\n    void draw();\n \n    \/\/--------------------------------------------------------------\n    \/\/ we create a few &quot;setters&quot; which will change our internal variables (like color, position, size).\n    void setColorForState(buttonState stateToChange, ofColor colorToChangeItTo);\n    void setPosition(int x, int y);\n    void setPosition(ofPoint pt);\n    void setSize(int w, int h);\n \n    \/\/--------------------------------------------------------------\n    \/\/ we provide a method to easily get access to our button&#039;s position\n    ofPoint getPosition();\n \n    \/\/--------------------------------------------------------------\n    \/\/ check if the button&#039;s state is currently &quot;pressed&quot;\n    bool isPressed();\n \n    \/\/--------------------------------------------------------------\n    \/\/ a method to call whenever the user is touching the screen...\n    \/\/ we can test if the user touched our button and change the state of our button accordingly...\n    \/\/ we return true if the button was pressed.\n    bool touchDown(ofTouchEventArgs touch);\n \n    \/\/--------------------------------------------------------------\n    \/\/ Our button class holds a few variables which help us keep track of our state, location and color...\n    buttonState             myState;\n    ofRectangle             myLocation;\n    ofColor                 myColorForDefault, myColorForPressed;\n};\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>myButton.cpp<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2013 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#include &quot;myButton.h&quot;\n \n\/\/--------------------------------------------------------------\nmyButton::myButton() {\n    \/\/ our constructor is called automagically.\n    \/\/ we put our initialization inside of here.\n \n    \/\/ let&#039;s set every state&#039;s color to be white\n    myColorForDefault = ofColor::white;\n    myColorForPressed = ofColor::white;\n \n    \/\/ and set our state to be the default one\n    myState = button_default;\n \n    \/\/ and set a simple default position and size for our button\n    myLocation.x = 0;\n    myLocation.y = 0;\n    myLocation.width = 0;\n    myLocation.height = 0;\n}\n \n\/\/--------------------------------------------------------------\nvoid myButton::draw() {\n \n    \/\/ set the color based on our current state\n    if (myState == button_default) {\n        ofSetColor(myColorForDefault);\n    }\n    else if(myState == button_pressed) {\n        ofSetColor(myColorForPressed);\n    }\n \n    \/\/ then draw a simple rectangle using our position.\n    ofRect(myLocation.x,\n           myLocation.y,\n           myLocation.width,\n           myLocation.height);\n}\n \n\/\/--------------------------------------------------------------\nvoid myButton::setColorForState(buttonState stateToChange,\n                                ofColor colorToChangeItTo)\n{\n    \/\/ we check which state is being changed\n    if (stateToChange == button_default) {\n        \/\/ and change the color accordingly\n        myColorForDefault = colorToChangeItTo;\n    }\n    else if(stateToChange == button_pressed) {\n        myColorForPressed = colorToChangeItTo;\n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid myButton::setPosition(int x, int y)\n{\n    \/\/ constrain the location to be within the bounds of the application window\n    myLocation.x = MIN(ofGetWidth() - myLocation.width, MAX(0,x));\n    myLocation.y = MIN(ofGetHeight() - myLocation.height, MAX(0,y));\n}\n \n\/\/--------------------------------------------------------------\nvoid myButton::setPosition(ofPoint pt)\n{\n    \/\/ constrain the location to be within the bounds of the application window\n    myLocation.x = MIN(ofGetWidth() - myLocation.width, MAX(0,pt.x));\n    myLocation.y = MIN(ofGetHeight() - myLocation.height, MAX(0,pt.y));\n}\n \n\/\/--------------------------------------------------------------\nvoid myButton::setSize(int w, int h)\n{\n    \/\/ change our internal variables to match what size the user told us to be\n    myLocation.width = w;\n    myLocation.height = h;\n}\n \n\/\/--------------------------------------------------------------\nofPoint myButton::getPosition()\n{\n    \/\/ return our internal position\n    return myLocation.position;\n}\n \n\/\/--------------------------------------------------------------\nbool myButton::touchDown(ofTouchEventArgs touch)\n{\n    bool bTouched = false;\n    \/\/ check if the touch&#039;s x,y position is inside the button\n    if (myLocation.inside(touch.x, touch.y)) {\n        bTouched = true;\n        \/\/ if so, the user touched us!  let&#039;s change states by simply adding 1\n        \/\/ to our current value.  this &quot;cycles&quot; through all the possible values (only 2).\n        \/\/ if we had more possible values for buttonState, we would use a modulus of\n        \/\/ however many different states we had, rather than 2...\n        myState = (buttonState)((myState + 1) % 2);\n    }\n    return bTouched;\n}\n \n\/\/--------------------------------------------------------------\nbool myButton::isPressed()\n{\n    \/\/ check if we are being pressed\n    return myState == button_pressed;\n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>Part 2<\/strong><br>If you are comfortable using the above class, now try integrating some maximilian objects to do some synthesis or sample loading\/playback. Try just a simple oscillator using&nbsp;<code>maxiOsc<\/code>&nbsp;to begin with. See if you can create a button which outputs a sine tone. Can you also modulate it based on your touch coordinates? How about delay?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Part 3 [optional]<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now try to record using the&nbsp;<code>audioIn<\/code>&nbsp;function. Remember to change&nbsp;<code>ofSoundStreamSetup<\/code>&nbsp;to use a single channel for input. Can you record sound from the microphone and use a button to play it back? Try also changing the drawing of the buttons to use more descriptive images instead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Part 4 [super optional]<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create an application which creates buttons where the user pressed down, recording samples from the microphone as the user holds down. When they release, create the final button in the position where the user let go. Can you use ofxAccelerometer or ofxBox2D to model the physics of this button? Perhaps the button can play whenever it bounces off a wall (have a look at the \u201cContact Listener\u201d example in ofxBox2d). You could also use the physically modeled speed of the button to change the speed of playback.<\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 3: Provisioning, Certificates, Addons, Map Kit<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>Provisioning<\/strong><br>Certificates and provisioning profiles. Apple Developer program and Development Provisioning Assistant.<br><strong>ofxAddons<\/strong><br>Great place to find additional code you can import into your application.<br><a rel=\"noreferrer noopener\" href=\"http:\/\/ofxaddons.com\/\" target=\"_blank\">http:\/\/ofxaddons.com<\/a><br><strong>Map Kit<\/strong><br>GPS, Maps API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lab<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>Part 1<\/strong><br>If you were having trouble in last week\u2019s assignment, feel free to have a look at my code for the \u201csuper optional\u201d part of the lab. This depends on having the ofxBox2d addon included in your project.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2013 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxiPhone.h&quot;\n#include &quot;ofxiPhoneExtras.h&quot;\n \n#include &quot;maximilian.h&quot;\n \n#include &quot;ofxBox2d.h&quot;\n \n\/\/ we create an additional class here that will be used to help us keep track of every\n\/\/ recorded sound.  \nclass customData {\npublic:\n    customData()\n    {\n        myID = currentSoundLUT;\n        currentSoundLUT++;\n    }\n    \/\/ this id stores a number that corresponds to a number in a list \n    int myID;\n    static int currentSoundLUT;\n};\n \n \nclass testApp : public ofxiPhoneApp{\n     \n    public:\n        void setup();\n        void update();\n        void draw();\n        void exit();\n     \n        void touchDown(ofTouchEventArgs &amp;amp; touch);\n        void touchMoved(ofTouchEventArgs &amp;amp; touch);\n        void touchUp(ofTouchEventArgs &amp;amp; touch);\n        void touchDoubleTap(ofTouchEventArgs &amp;amp; touch);\n        void touchCancelled(ofTouchEventArgs &amp;amp; touch);\n \n        void lostFocus();\n        void gotFocus();\n        void gotMemoryWarning();\n        void deviceOrientationChanged(int newOrientation);\n     \n        void audioOut(float *buf, int size, int ch);\n        void audioIn(float *buf, int size, int ch);\n     \n         \n        \/\/ this is the function for contacts\n        void contactStart(ofxBox2dContactArgs &amp;amp;e);\n        void contactEnd(ofxBox2dContactArgs &amp;amp;e);\n     \n    \/\/  the box2d world\n    ofxBox2d                        box2d;\n    \/\/  default box2d circles\n    vector      &amp;lt;ofxBox2dCircle&gt;  circles;          \n    \/\/  storage for all the recordings we make\n    vector&amp;lt;vector&amp;lt;float&gt; &gt;          recordings;\n     \n    \/\/ keep a buffer of audio samples for the current recording in progress\n    vector&amp;lt;float&gt;                   currentRecording;\n     \n    \/\/ and the current offset for this recording as it is being recorded\n    int                             currentRecordingOffset;\n     \n    \/\/ also keep a table of indexes which store all sounds being played back\n    vector&amp;lt;int&gt;                     currentPlayingSounds;\n     \n    \/\/ and the offsets or the current sample being played from these sounds\n    vector&amp;lt;int&gt;                     currentPlayingSoundsOffset;\n     \n    \/\/ maximilian&#039;s maxiDyn which gives us a compressor to compress our sounds\n    maxiDyn                         dyn;\n     \n    \/\/ and a boolean to check if we are currently recording\n    bool                            bRecording;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2013 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n#include &quot;testApp.h&quot;\n \nint customData::currentSoundLUT = 0;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup() {\n    bRecording = false;\n     \n    \/\/ initialize the accelerometer\n    ofxAccelerometer.setup();\n     \n    \/\/ we initalize the box2d world.  there are parameters for the gravity and the bounding box of this world.\n    \/\/ we also tell box2d how fast we need it to be.  it will try to run at this speed at best.\n    \/\/ we also &quot;register grabbing&quot; which means we are able to interact with any objects we add to the box2d world.\n    box2d.init();\n    box2d.setGravity(0, 10);\n    box2d.createBounds();\n    box2d.setFPS(30.0);\n    box2d.registerGrabbing();\n \n    \/\/ add listeners. these are functions that are called only when a certain action is performed\n    \/\/ we add 2 listeners that are executed whenever box2d&#039;s world discovered that some objects\n    \/\/ have contacted each other.  for instance, a ball hit a wall, or a ball hit another ball.\n    \/\/ we get 2 listeners, one for the start of the contact, and one for the end of it..\n    ofAddListener(box2d.contactStartEvents, this, &amp;amp;testApp::contactStart);\n    ofAddListener(box2d.contactEndEvents, this, &amp;amp;testApp::contactEnd);\n \n    \/\/ setup maximilian audio settings\n    maxiSettings::setup(44100, 1, 512);\n     \n    \/\/ setup openframeworks audio setings\n    \/\/ (gives us the audioIn\/audioOut callbacks)\n    ofSoundStreamSetup(1, 1, 44100, 512, 3);\n     \n    \/\/ this forces audio output to the speaker rather than the headphone jack\n    \/\/ (better to have these commands execute in response to a button press)\n    \/\/UInt32 category = kAudioSessionOverrideAudioRoute_Speaker;\n    \/\/AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(category), &amp;amp;category);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update()\n{\n    \/\/ get the current accelerometer reading as an ofPoint\n    ofPoint currentForce = ofxAccelerometer.getForce();\n     \n    \/\/ reverse the y-direction as our screen coordinates are upside down in y\n    currentForce.y = -currentForce.y;\n     \n    \/\/ and multiply by a factor to make the force &quot;heavier&quot;\n    currentForce *= 9.8;\n     \n    \/\/ now we update our box2d world with the readings from our accelerometer\n    box2d.setGravity(currentForce);\n     \n    \/\/ and tell box2d to update everything else\n    box2d.update();\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n    \/\/ set the background to be black every draw iteration\n    ofBackground(0);\n \n    \/\/ let&#039;s draw all circles - they know their internal position\n    for(int i=0; i&amp;lt;circles.size(); i++) {\n        ofFill();\n        ofSetHexColor(0xf6c738);\n        circles&#x5B;i].draw();\n    }\n     \n    \/\/ draw the box2d ground\n    box2d.drawGround();\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::exit(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::audioOut(float *buf, int size, int ch)\n{\n    \/\/ first clear the sound output to be 0 by default\n    memset(buf, 0, sizeof(float)*size*ch);\n     \n    \/\/ we create an iterator which goes through the list of sounds\n    vector&amp;lt;int&gt;::iterator it = currentPlayingSounds.begin();\n     \n    \/\/ and keep an iterator which keeps the current offset of that sound\n    vector&amp;lt;int&gt;::iterator it2 = currentPlayingSoundsOffset.begin();\n     \n    \/\/ now loop through all sounds that are playing\n    while(it != currentPlayingSounds.end())\n    {\n        \/\/ we loop through the current audio frame&#039;s size and add all recordings that are currently playing\n        for (int i = 0; i &amp;lt; size; i++) {\n            \/\/ we use the currentPlayingSound&#039;s iterator to pick out the recording\n            \/\/ and the offset to index the recording\n            buf&#x5B;i] += (recordings&#x5B;(*it)]&#x5B;i + *it2]);\n        }\n         \n        \/\/ and update the offset&#039;s to reflect that we just read &quot;size&quot; number of samples\n        \/\/ this way, the next audio frame will play the recorded samples &quot;size&quot; samples farther than\n        \/\/ this audio frame has played\n        (*it2) += size;\n         \n        \/\/ we now check if the recorded sample has finished playing\n        if((*it2) &gt;= recordings&#x5B;(*it)].size())\n        {\n            \/\/ if so, we delete it from the sounds that are playing\n            it = currentPlayingSounds.erase(it);\n            it2 = currentPlayingSoundsOffset.erase(it2);\n        }\n        else\n        {\n            \/\/ otherwise, keep it in the list, and move on to the next sound\n            it++;\n            it2++;\n        }\n    }\n     \n    \/\/ we use a compressor to keep the sound within &#x5B;-1,1] bounds. otherwise, the sound will clip\n    \/\/ if we add more than 1 sound to the output... \n    for (int i = 0; i &amp;lt; size; i++) {\n        buf&#x5B;i] = dyn.compressor(buf&#x5B;i], 0.7);\n    }\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::audioIn(float *buf, int size, int ch){\n     \n    \/\/ check if the user is recording a sound (pushed down on the screen)\n    if (bRecording)\n    {\n        \/\/ get the current recording&#039;s size\n        int idx = currentRecording.size();\n         \n        \/\/ now change it to be &quot;size&quot; samples bigger\n        currentRecording.resize(idx + size);\n         \n        \/\/ loop through the length of size\n        for (int i = 0; i &amp;lt; size; i++) {\n             \n            \/\/ and add all the samples of the current audio frame to the current recording\n            currentRecording&#x5B;idx + i] = buf&#x5B;i];\n        }\n    }\n}\n \n \n \n\/\/--------------------------------------------------------------\nvoid testApp::contactStart(ofxBox2dContactArgs &amp;amp;e) {\n    if(e.a != NULL &amp;amp;&amp;amp; e.b != NULL) {\n \n    }\n}\n \n \n \n\/\/--------------------------------------------------------------\nvoid testApp::contactEnd(ofxBox2dContactArgs &amp;amp;e) {\n     \n    \/\/ .a and .b store the contacting objects\n    \/\/ we make sure they are not null, not sure why, but we do... \n    if(e.a != NULL &amp;amp;&amp;amp; e.b != NULL) {\n         \n        \/\/ we get the data for each of these objects and CAST it to our custom data type\n        customData * aData = (customData*)e.a-&gt;GetBody()-&gt;GetUserData();\n        customData * bData = (customData*)e.b-&gt;GetBody()-&gt;GetUserData();\n         \n        \/\/ we first make sure that it is a circle, as the walls do not have custom data\n        if(e.a-&gt;GetType() == b2Shape::e_circle &amp;amp;&amp;amp; aData) {\n            \/\/ then add to our table of playing sounds the circle&#039;s ID\n            currentPlayingSounds.push_back(aData-&gt;myID);\n            \/\/ also initialize the offset of this sound to be the 0th sample so it starts from the beginning\n            currentPlayingSoundsOffset.push_back(0);\n        }\n         \n        \/\/ we first make sure that it is a circle, as the walls do not have custom data\n        if(e.b-&gt;GetType() == b2Shape::e_circle &amp;amp;&amp;amp; bData) {\n            \/\/ then add to our table of playing sounds the circle&#039;s ID\n            currentPlayingSounds.push_back(bData-&gt;myID);\n            \/\/ also initialize the offset of this sound to be the 0th sample so it starts from the beginning\n            currentPlayingSoundsOffset.push_back(0);\n        }\n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDown(ofTouchEventArgs &amp;amp; touch){\n \n    bRecording = true;\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchMoved(ofTouchEventArgs &amp;amp; touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchUp(ofTouchEventArgs &amp;amp; touch){\n     \n    \/\/ done recording\n    bRecording = false;\n     \n    \/\/ let&#039;s add the recorded sound to all of our recordings\n    recordings.push_back(currentRecording);\n     \n    \/\/ and erase the buffer which helps us record sounds\n    currentRecording.resize(0);\n     \n    \/\/ here we keep a circle that will be modeled by box2d\n    float r = 20;\n    ofxBox2dCircle circle;\n    circle.setPhysics(3.0, 0.53, 0.1);\n    circle.setup(box2d.getWorld(), touch.x, touch.y, r);\n    circle.setData(new customData());\n    circles.push_back(circle);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDoubleTap(ofTouchEventArgs &amp;amp; touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchCancelled(ofTouchEventArgs &amp;amp; touch){\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::lostFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotMemoryWarning(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::deviceOrientationChanged(int newOrientation){\n \n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Part 2<\/strong><br>Before you can develop on a particular device however, you must obtain a certificate for development and a provisioning profile for each device you want to develop on. E-mail me your e-mail address and first and last name. I will send you an invitation to join our developer account so you don\u2019t have to pay for one. After you\u2019ve registered for an iOS account (you should have received an e-mail from me in the lab), log on developer.apple.com and find the iOS Provisioning Portal. If you can\u2019t find the iOS Provisioning Portal, make sure you have been invited to join the team iOS account, and you have signed in with the account you created with this invitation. Try re-logging into developer.apple.com as well. Once you find the iOS Provisioning Portal, click on \u201ccertificates\u201d, then the button for \u201crequest a certificate\u201d, and follow the steps for requesting a certificate. (You will be asked to upload a \u201cCertificate Signing Request\u201d. For the CA e-mail address, leave it blank. Make sure you save the CSR to disk.) Next, in the iOS Provisioning Portal, find the devices section. Now click on how-to. This will tell you how to locate your device id for your iPad\/iPod\/iPhone. Send me this 40-bit hex key in an e-mail.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After I\u2019ve received your certificate signing request and device id, I will update your information in the system. You can then go to the iOS Provisioning Portal and download your certificate. Do not do this before I have updated the system. Simply open this certificate and it will be installed in your KeyChain. If your certificate does not appear here, then either you have not submitted a signing request to me, or I have not yet accepted it. Next, in the iOS Provisioning Portal, navigate to \u201cProvisioning\u201d. Find the profile called, \u201cwcc\u201d, and download this file. Open it and it should appear in your XCode\u2019s Organizer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Part 3<\/strong><br>Try installing an application you have made on a device.<\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 4: Provisioning, CoreMotion, CoreLocation, OSC, ImagePicker, Twitter, Group Projects Discussion<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>Provisioning<\/strong><br>Please have a look at last week\u2019s lab notes on how to get applications installed on your phone. If you are not an \u201ciOS developer\u201d on our team account, or have not submitted a \u201ccertificate signing request\u201d, or have not submitted your device\u2019s identifier to me, you will not be able to develop on a device. Make sure you do these things before downloading a certificate and provisioning profile from the iOS Provisioning Portal.<br><strong>Core Motion<\/strong><br>The ofxUIAccelerometer which ships with openFrameworks v0073 uses a deprecated library for accessing the accelerometer. Please download&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/trentbrooks\/ofxCoreMotion\" target=\"_blank\">ofxCoreMotion<\/a>&nbsp;instead. This gives you access to the Accelerometer, Gyrometer, Magnetometer, Digital Compass.<br><strong>Core Location<\/strong><br>Using core location, you can access the device\u2019s latitude, longitude, and altitude. This is particularly useful when using MapKit, as you can add annotations or reposition the map to particular latitudes and longitudes. You may also think of logging the GPS information, creating a path, for instance, which you could use for any variety of applications (e.g. drawing, 3D printing maybe, I don\u2019t know really).<br><strong>OSC<\/strong><br>Have a look at the oscReceiver and oscSender examples for how to receive and send information from your app across a network. You could talk to a program on your laptop, another iOS device, or through a web server, for instance.<br><strong>Image Picker<\/strong><br>openFrameworks provides a simple interface to the iOS Image Picker,&nbsp;<code>ofxiPhoneImagePicker<\/code>. This is a handy little class which lets you access the photo library and take images\/videos.<br><strong>Twitter<\/strong><br>Starting in iOS 5, it is very easy to send twitter message, get a list of tweets for a user, and attach photos or links to a tweet, using the&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/developer.apple.com\/library\/ios\/#documentation\/Twitter\/Reference\/TwitterFrameworkReference\/_index.html\" target=\"_blank\">Twitter Framework<\/a>. In iOS 6, there is also&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/developers.facebook.com\/docs\/howtos\/ios-6\/\" target=\"_blank\">native Facebook integration<\/a>.<br><strong>Twitter + Image Picker example<\/strong><br>You\u2019ll have to add the \u201cTwitter\u201d framework to your project (Build Phases\/Link Binary With Libraries). Also, I edited the&nbsp;<code>ofxiPhoneImagePicker<\/code>&nbsp;(addons\/ofxiPhone\/src\/utils) class to include the function on lines 118:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nUIImage * getUIImage()\n{\n    return &#x5B;imagePicker getUIImage];\n}\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxiPhone.h&quot;\n#include &quot;ofxiPhoneExtras.h&quot;\n \nclass testApp : public ofxiPhoneApp{\n     \n    public:\n        void setup();\n        void update();\n        void draw();\n        void exit();\n     \n        void touchDown(ofTouchEventArgs &amp;amp; touch);\n        void touchMoved(ofTouchEventArgs &amp;amp; touch);\n        void touchUp(ofTouchEventArgs &amp;amp; touch);\n        void touchDoubleTap(ofTouchEventArgs &amp;amp; touch);\n        void touchCancelled(ofTouchEventArgs &amp;amp; touch);\n \n        void lostFocus();\n        void gotFocus();\n        void gotMemoryWarning();\n        void deviceOrientationChanged(int newOrientation);\n     \n    ofImage img;\n    ofxiPhoneImagePicker imgPicker;\n \n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#include &quot;testApp.h&quot;\n#import &amp;lt;Twitter\/TWTweetComposeViewController.h&gt;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){  \n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n    if (imgPicker.imageUpdated) {\n        imgPicker.imageUpdated = false;\n         \n        TWTweetComposeViewController *tweetView = &#x5B;&#x5B;TWTweetComposeViewController alloc] init];\n         \n        TWTweetComposeViewControllerCompletionHandler\n        completionHandler =\n        ^(TWTweetComposeViewControllerResult result) {\n            switch (result)\n            {\n                case TWTweetComposeViewControllerResultCancelled:\n                    NSLog(@&quot;Twitter Result: canceled&quot;);\n                    break;\n                case TWTweetComposeViewControllerResultDone:\n                    NSLog(@&quot;Twitter Result: sent&quot;);\n                    break;\n                default:\n                    NSLog(@&quot;Twitter Result: default&quot;);\n                    break;\n            }\n            &#x5B;ofxiPhoneGetViewController() dismissModalViewControllerAnimated:YES];\n        };\n        &#x5B;tweetView setCompletionHandler:completionHandler];\n        &#x5B;tweetView addImage:imgPicker.getUIImage()];    \/\/ i added a simple &quot;getter&quot; to the image picker class to return the UIImage\n        &#x5B;tweetView setInitialText:@&quot;Look how freaking easy it is to send a tweet using openFrameworks and iOS 5+&quot;];\n \n        &#x5B;ofxiPhoneGetViewController() presentModalViewController:tweetView animated:YES];\n                                    \n        imgPicker.close();\n \n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::exit(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDown(ofTouchEventArgs &amp;amp; touch){\n    imgPicker.openCamera();\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchMoved(ofTouchEventArgs &amp;amp; touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchUp(ofTouchEventArgs &amp;amp; touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDoubleTap(ofTouchEventArgs &amp;amp; touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchCancelled(ofTouchEventArgs &amp;amp; touch){\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::lostFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotMemoryWarning(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::deviceOrientationChanged(int newOrientation){\n \n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lab<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Please make sure you have organized a group and have discussed with me what you plan to do. You have to submit a 300 word document as a group to me by the end of the night. Make sure you say what you plan on doing, how you plan to do it, and why it is interesting. A good structure for writing this document should start with a context (who cares about it?), a motivation (why is it important?), your approach (how will you do it?), how your approach is integral to what you set out to do (why your approach is a good idea?), and what you plan to achieve (what will your approach achieve?). Remember I don\u2019t expect miracles, but I do expect well thought out ideas. Be sure to also include who the group members are, how many devices you have, and if you need a device.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 5: CaptiveNetwork, Annotations, Alternatives, Group Projects Discussion<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>Obtaining the current network SSID<\/strong><br>You can use the short code fragment below to figure out the SSID of the current WiFi connection. You will have to add the framework, SystemConfiguration, for this to work.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n...\n \n#import &amp;lt;SystemConfiguration\/CaptiveNetwork.h&gt;\n \n...\n \n{\n \n...\n \n    \/\/ getting an array of supported networking interfaces\n    NSArray *ifs = (id)CNCopySupportedInterfaces();\n     \n    \/\/ now output them \n    NSLog(@&quot;%s: Supported interfaces: %@&quot;, __func__, ifs);\n     \n    \/\/ can also get info about each interface\n    id info = nil;\n     \n    \/\/ let&#039;s loop through each interface\n    for (NSString *ifnam in ifs) {\n         \n        \/\/ get the info for it\n        info = (id)CNCopyCurrentNetworkInfo((CFStringRef)ifnam);\n         \n        \/\/ and output its info, such as what network SSID it is currently connected to\n        NSLog(@&quot;%s: %@ =&gt; %@&quot;, __func__, ifnam, info);\n        if (info &amp;amp;&amp;amp; &#x5B;info count]) {\n            break;\n        }\n         \n        \/\/ release the memory\n        &#x5B;info release];\n    }\n    &#x5B;ifs release];\n \n...\n \n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Adding Annotations to MapKit<\/strong><br>You\u2019ll have to modify ofxiPhoneMapKit.h and ofxiPhoneMapKit.mm to include the following (note, do not add the ellipses, \u2026, obviously):<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ofxiPhoneMapKit.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n...\n \nclass ofxiPhoneMapKit : public ofxiPhoneMapKitListener {\npublic:\n \n...\n \n    void selectedAnnotation(string title, string subtitle);\n    void unselectedAnnotation(string title, string subtitle);\n    void addAnnotation(double latitude, double longitude, string title, string subtitle);\n    void removeAnnotation(double latitude, double longitude, string title, string subtitle);\n    void removeAnnotation(string title, string subtitle);\n \n...\n \nprivate:\n \n...\n \n    vector&amp;lt; MKPointAnnotation * &gt; annotations;\n \n...\n \n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>ofxiPhoneMapKit.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n...\n \nvoid ofxiPhoneMapKit::selectedAnnotation(string title, string subtitle) {\n    for(std::list&amp;lt;ofxiPhoneMapKitListener*&gt;::iterator it=listeners.begin(); it!=listeners.end(); ++it) {\n        ofxiPhoneMapKitListener* o = *it;\n        o-&gt;selectedAnnotation(title, subtitle);\n    }\n}\n \n \nvoid ofxiPhoneMapKit::unselectedAnnotation(string title, string subtitle) {\n    for(std::list&amp;lt;ofxiPhoneMapKitListener*&gt;::iterator it=listeners.begin(); it!=listeners.end(); ++it) {\n        ofxiPhoneMapKitListener* o = *it;\n        o-&gt;unselectedAnnotation(title, subtitle);\n    }\n}\n \n \nvoid ofxiPhoneMapKit::addAnnotation(double latitude,\n                                    double longitude,\n                                    string title,\n                                    string subtitle)\n{\n    CLLocationCoordinate2D annotationCoord;\n     \n    annotationCoord.latitude = latitude;\n    annotationCoord.longitude = longitude;\n     \n    MKPointAnnotation *annotationPoint = &#x5B;&#x5B;MKPointAnnotation alloc] init];\n    annotationPoint.coordinate = annotationCoord;\n    annotationPoint.title = ofxStringToNSString(title);\n    annotationPoint.subtitle = ofxStringToNSString(subtitle);\n    &#x5B;mapView addAnnotation:annotationPoint];\n    annotations.push_back(annotationPoint);\n}\n \nvoid ofxiPhoneMapKit::removeAnnotation(string title,\n                                       string subtitle)\n{\n     \n    for (vector&amp;lt;MKPointAnnotation *&gt;::iterator it = annotations.begin(); it != annotations.end(); it++) {\n        if (&#x5B;(*it).title isEqualToString:ofxStringToNSString(title)] &amp;amp;&amp;amp;\n            &#x5B;(*it).subtitle isEqualToString:ofxStringToNSString(subtitle)]) {\n            ofLog(OF_LOG_NOTICE, &quot;Removing annotation\\n&quot;);\n            &#x5B;mapView removeAnnotation:(*it)];\n            &#x5B;(*it) release];\n            annotations.erase(it);\n            break;\n        }\n    }\n     \n}\n \nvoid ofxiPhoneMapKit::removeAnnotation(double latitude,\n                                       double longitude,\n                                       string title,\n                                       string subtitle)\n{\n     \n    for (vector&amp;lt;MKPointAnnotation *&gt;::iterator it = annotations.begin(); it != annotations.end(); it++) {\n        if ((*it).coordinate.latitude == latitude &amp;amp;&amp;amp;\n            (*it).coordinate.longitude == longitude &amp;amp;&amp;amp;\n            &#x5B;(*it).title isEqualToString:ofxStringToNSString(title)] &amp;amp;&amp;amp;\n            &#x5B;(*it).subtitle isEqualToString:ofxStringToNSString(subtitle)]) {\n            &#x5B;mapView removeAnnotation:(*it)];\n            &#x5B;(*it) release];\n            annotations.erase(it);\n            break;\n        }\n    }\n     \n}\n \n...\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now we register the 2 new callbacks to be part of the&nbsp;<code>ofxiPhoneMapKitListener<\/code>&nbsp;class by editing the ofxiPhoneMapKitListener.h file to look like:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ofxiPhoneMapKit.Listener.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n...\n \nclass ofxiPhoneMapKitListener { \npublic:\n    virtual ~ofxiPhoneMapKitListener() {};\n    virtual void regionWillChange(bool animated) {}\n    virtual void regionDidChange(bool animated) {}\n    virtual void willStartLoadingMap() {}\n    virtual void didFinishLoadingMap() {}\n    virtual void errorLoadingMap(string errorDescription) {}\n    virtual void selectedAnnotation(string title, string subtitle) {}\n    virtual void unselectedAnnotation(string title, string subtitle) {}\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">These functions are virtual, meaning they are allowed to be overridden by any classes that inherit from this one. By default, if you do not override them, they are defined to be {}, meaning they do nothing. If you want them to do something more, you can edit your testApp.h and add the declaration of these two functions. They will get called whenever the user selects\/unselects any annotations that have been added to the mapkit. Add them to testApp.h and testApp.mm like so:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n...\n \nclass testApp : public ofxiPhoneApp, ofxiPhoneMapKitListener{\npublic:\n \n...\n \n        \/\/ additional optional callbacks for annotations\n        void selectedAnnotation(string title, string subtitle);\n        void unselectedAnnotation(string title, string subtitle);\n \n...\n \n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n...\n \n\/\/--------------------------------------------------------------\nvoid testApp::selectedAnnotation(string title, string subtitle){\n    printf(&quot;testApp::selectedAnnotation | title: %s, subtitle: %s\\n&quot;, title.c_str(), subtitle.c_str());\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::unselectedAnnotation(string title, string subtitle){\n    printf(&quot;testApp::unselectedAnnotation | title: %s, subtitle: %s\\n&quot;, title.c_str(), subtitle.c_str());\n}\n \n...\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Assuming you have created an object mapKit of type ofxiPhoneMapKit and coreLocation of type ofxiPhoneCoreLocation and did all the proper setup (have a look at the examples if you are unsure), you can easily add annotations to the map by writing:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nmapKit.addAnnotation(coreLocation.getLatitude(), coreLocation.getLongitude(), &quot;This is the Title&quot;, &quot;I&#039;m the subtitle...&quot;);\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Gestures<\/strong><br>If you want to use some of the SDK\u2019s inbuilt gesture recognizers, you can easily get started with this addon,&nbsp;<a href=\"http:\/\/github.com\/rjraffa\/ofxGestureRecognizer\/zipball\/master\">ofxGestureRecognizer<\/a>. This lets you detect pan, pinch, swipe, and tap gestures.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Alternatives<\/strong><br>Being the last lecture focusing on iOS development with openFrameworks, I wanted to give you a few other popular approaches you could take for programming 2d\/3d audiovisual interaction\/games.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><a href=\"http:\/\/developer.apple.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Native<\/a><\/strong><br>Meaning only using the iOS SDK. Of course you can create graphics in CoreAnimation etc\u2026 and interact with the device using the native libraries. If you require physics however you may not want to recreate these libraries, as they don\u2019t exist in the iOS SDK. Requires the most amount of time\/effort.<br><strong><a href=\"http:\/\/www.cocos2d-iphone.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">cocos2d<\/a><\/strong><br>Focuses on extending 2D interaction. Community-driven github repository. OpenGLES 2.0ES support. Very popular so lots of community resources. Also has HTML5 implementation.<br><strong><a href=\"https:\/\/code.google.com\/p\/oolongengine\/\" target=\"_blank\" rel=\"noreferrer noopener\">oolong<\/a><\/strong><br>Focus on extending 3D interaction. Incorporates Bullet Physics Engine. Very open google code repository. OpenGLES 2.0ES support. Good for those that already program OpenGLES. Not much documentation.<br><strong><a href=\"http:\/\/libcinder.org\/about\/\">libcinder<\/a><\/strong><br>Very similar to openFrameworks. Very nicely written code. Templated. Generally not as targeted for education\/learning as openFrameworks is, so for people more comfortable with coding. OpenGLES 2.0+ support.<br><strong><a href=\"http:\/\/unity3d.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Unity3D<\/a><\/strong><br>OpenGL 2.0ES+ support. Focus on 3D interaction. Very powerful and simple to use.&nbsp;<a href=\"http:\/\/unity3d.com\/unity\/licenses\" target=\"_blank\" rel=\"noreferrer noopener\">Licensing options<\/a>&nbsp;required for all features and depending on how you sell your app\/game.<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lab<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Work on your project!<\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Computer Vision Module Introduction<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Introduction<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">The next 5 weeks will focus on developing an understanding of what is possible with computer vision. In particular, we will focus on using Intel\u2019s OpenCV within the openFrameworks library. Your final project will be similar to the mobile module where you will work in groups to create an application\/game\/installation\/experience based in computer vision. For the next 5 weeks, makes sure you have a working version of openFrameworks v074+ for your operating system. Note that we will not be restricted to using XCode\/OSX for these weeks (HOORAY!).<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>OpenCV Links<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Keep in mind links for the OpenCV&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/opencv.willowgarage.com\/documentation\/cpp\/\" target=\"_blank\">documentation<\/a>&nbsp;and&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/opencv.willowgarage.com\/wiki\/FullOpenCVWiki\" target=\"_blank\">Wiki<\/a>&nbsp;pages. Actually,&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/public.cranfield.ac.uk\/c5354\/teaching\/dip\/opencv\/manual\/\" target=\"_blank\">this page<\/a>&nbsp;is a good compendium of different resources, and also includes a link to a&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/public.cranfield.ac.uk\/c5354\/teaching\/dip\/opencv\/manual\/opencv2refman.pdf\" target=\"_blank\">PDF Manual of OpenCV 2.3.1<\/a>. More information is also in each of the lab sheets below.<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Other Computer Vision courses<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Bob Fisher\u2019s&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/www.inf.ed.ac.uk\/teaching\/courses\/ivr\/\" target=\"_blank\">IVR Introduction to Vision and Robotics<\/a>&nbsp;&amp;&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/www.inf.ed.ac.uk\/teaching\/courses\/av\/\" target=\"_blank\">AV Advanced Vision<\/a>&nbsp;classes at University of Edinburgh<br>James Hays\u2019s&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/www.cs.brown.edu\/courses\/cs143\/\" target=\"_blank\">CS 143 Introduction to Computer Vision<\/a>&nbsp;class at Brown<br>Trevor Darrell\u2019s&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/www.eecs.berkeley.edu\/~trevor\/CS280.html\" target=\"_blank\">CS 280 Computer Vision<\/a>&nbsp;class at University of California, Berkeley<br>Antonio Torralba\u2019s&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/groups.csail.mit.edu\/vision\/courses\/6.869\/\" target=\"_blank\">6.869 Advances in Computer Vision<\/a>&nbsp;class at MIT<br>Kristen Grauman\u2019s&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/www.cs.utexas.edu\/~grauman\/courses\/fall2009\/main.htm\" target=\"_blank\">CS 378 Computer Vision<\/a>&nbsp;class at University of Texas, Austin<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Recommended Books<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Forsyth &amp; Ponce \u2013 Computer Vision: a Modern Approach<br>Norvig \u2013 Artificial Intelligence: a Modern Approach<br>Bishop \u2013 Pattern Recognition and Machine Learning<br>Ballard &amp; Brown \u2013 Computer Vision [<a rel=\"noreferrer noopener\" href=\"http:\/\/homepages.inf.ed.ac.uk\/rbf\/BOOKS\/BANDB\/bandb.htm\" target=\"_blank\">free eBook<\/a>]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 1: Introduction to Computer Vision, OpenCV, and ofxOpenCV<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-4.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-4.\"><\/object><a id=\"wp-block-file--media-087d9085-5b94-4486-b655-47be002e7637\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-4.pdf\">Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-4<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-4.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-087d9085-5b94-4486-b655-47be002e7637\">Download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lab<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-5.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-5.\"><\/object><a id=\"wp-block-file--media-c4ae14ed-ab05-4cb5-ac2e-fb6178330209\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-5.pdf\">Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-5<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-5.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-c4ae14ed-ab05-4cb5-ac2e-fb6178330209\">Download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Interactive RGB Colorspace<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxCvMain.h&quot;\n \nclass testApp : public ofBaseApp{\n \npublic:\n         \n    \/\/ redeclaration of functions (declared in base class)\n    void setup();\n    void update();\n    void draw();\n \n    void keyPressed(int key);\n \n    ofVideoGrabber camera;\n     \n    ofxCvColorImage im_color;\n    ofxCvGrayscaleImage im_red, im_green, im_blue;\n    ofxCvGrayscaleImage im_gray;\n    ofxCvGrayscaleImage im_value;\n     \n \n    int imgWidth, imgHeight;\n     \n    bool bShowBlended;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.cpp<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#include &quot;testApp.h&quot;\n \n\/\/ here we &quot;define&quot; the methods we &quot;declared&quot; in the &quot;testApp.h&quot; file\n \n\/\/ i get called once\nvoid testApp::setup(){\n     \n    \/\/ do some initialization\n    imgWidth = 320;\n    imgHeight = 240;\n     \n    bShowBlended = false;\n     \n    \/\/ set the size of the window\n    ofSetWindowShape(imgWidth * 6, imgHeight);\n     \n    \/\/ the rate at which the program runs (FPS)\n    ofSetFrameRate(30);\n     \n    \/\/ setup the camera\n    camera.initGrabber(imgWidth, imgHeight);\n    im_color.allocate(imgWidth, imgHeight);\n    im_red.allocate(imgWidth, imgHeight);\n    im_green.allocate(imgWidth, imgHeight);\n    im_blue.allocate(imgWidth, imgHeight);\n    im_gray.allocate(imgWidth, imgHeight);\n    im_value.allocate(imgWidth, imgHeight);\n}\n \n\/\/ i get called in a loop that runs until the program ends\nvoid testApp::update(){\n    camera.update();\n     \n    if(camera.isFrameNew())\n    {\n        \/\/ copy the pixels from the camera object into an ofxCvColorImage object\n        im_color.setFromPixels(camera.getPixels(), imgWidth, imgHeight);\n         \n        im_gray = im_color;\n         \n        \/\/ get each color channel\n        im_color.convertToGrayscalePlanarImages(im_red, im_green, im_blue);\n         \n        im_color.convertRgbToHsv();\n        im_color.convertToGrayscalePlanarImage(im_value, 2);\n    }\n}\n \n\/\/ i also get called in a loop that runs until the program ends\nvoid testApp::draw(){\n    \/\/ background values go to 0\n    ofBackground(0);\n     \n    \/\/ draw the camera\n    ofSetColor(255, 255, 255);\n    camera.draw(imgWidth * 0,0);\n     \n    if(bShowBlended)\n    {\n        \/\/ blending mode for adding pictures together\n        ofEnableAlphaBlending();\n        ofEnableBlendMode(OF_BLENDMODE_ADD);\n         \n        \/\/ full red energy\n        ofSetColor(255, 0, 0);\n        im_red.draw(imgWidth * 1,0);\n         \n        \/\/ full green energy\n        ofSetColor(0, 255, 0);\n         \n        \/\/ draw using an offset from the center of the screen determined by the mouse position\n        im_green.draw(imgWidth * 1 + (mouseX - ofGetScreenWidth()\/2) \/ 10.0,0);\n         \n        \/\/ full blue energy\n        ofSetColor(0, 0, 255);\n         \n        \/\/ offset just like above, but 2x as much\n        im_blue.draw(imgWidth * 1 + (mouseX - ofGetScreenWidth()\/2) \/ 5.0,0);\n         \n        ofDisableAlphaBlending();\n    }\n    else\n    {\n        ofSetColor(255, 0, 0);\n        im_red.draw(imgWidth * 1,0);\n         \n        ofSetColor(0, 255, 0);\n        im_green.draw(imgWidth * 2,0);\n         \n        ofSetColor(0, 0, 255);\n        im_blue.draw(imgWidth * 3,0);\n    }\n     \n    ofSetColor(255, 255, 255);\n    im_gray.draw(imgWidth * 4, 0);\n    im_value.draw(imgWidth * 5, 0);\n}\n \nvoid testApp::keyPressed(int key)\n{\n    switch (key) {\n        case &#039;s&#039;:\n            camera.videoSettings();\n            break;\n             \n        \/\/ press space to switch between modes    \n        case &#039; &#039;:\n            bShowBlended = !bShowBlended;\n            break;\n        default:\n            break;\n    }\n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Motion Tracking + Interactive Video Player<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxOpenCv.h&quot;\n \nclass testApp : public ofBaseApp{\n \npublic:\n    void setup();\n    void update();\n    void draw();    \n      \n    float                   alpha;\n    float                   sum;\n    ofVideoGrabber          camera;\n \n    ofxCvColorImage         color_img;\n \n    ofxCvGrayscaleImage     gray_img;\n    ofxCvGrayscaleImage     gray_previous_img;\n    ofxCvGrayscaleImage     gray_diff;\n \n    ofVideoPlayer           video;\n \n    vector&amp;lt;ofxCvGrayscaleImage&gt; previous_imgs;\n \n    int                     img_width, img_height;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.cpp<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#include &quot;testApp.h&quot;\n \nusing namespace cv;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){\n \n    \/\/ keep variables for our image size\n    img_width = 320;\n    img_height = 240;\n     \n    \/\/ value for our first order linear filter\n    \/\/ this controls how much we mix in previous results\n    \/\/ the larger the value, the larger the weight of the \n    \/\/ previous result.  this is a very essential and basic\n    \/\/ technique in digital signal processing also known as a \n    \/\/ low pass filter.\n    alpha = 0.5;\n     \n    \/\/ change the window to hold enough space for 2 movies (1 row x 2 columns of movies)\n    ofSetWindowShape(img_width * 2, img_height);\n     \n    ofSetFrameRate(30);\n     \n    \/\/ initialize our camera with a resolution of 320z240\n    camera.initGrabber(img_width, img_height);\n     \n    \/\/ load a movie in and set it to loop, and then start it (play())\n    video.loadMovie(&quot;sunra_pink.mov&quot;);\n    video.setLoopState(OF_LOOP_NORMAL);\n    video.play();\n     \n    sum = 0;\n     \n    \/\/ these are (wrappers for) opencv image containers \n    \/\/ we&#039;ll use for image processing\n    \/\/ we are going to find the difference between successive frames\n    color_img.allocate(img_width, img_height);\n    gray_img.allocate(img_width, img_height);\n    gray_previous_img.allocate(img_width, img_height);\n    gray_diff.allocate(img_width, img_height);\n    previous_imgs.push_back(gray_previous_img);\n    previous_imgs.push_back(gray_previous_img);\n    previous_imgs.push_back(gray_previous_img);\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n    \/\/ background to black\n    ofBackground(0);\n     \n    \/\/ update the camera\n    camera.update();\n     \n    if (camera.isFrameNew()) {\n        \/\/ set the color image (opencv container) to the camera image\n        color_img.setFromPixels(camera.getPixels(), img_width, img_height);\n        \/\/ convert to grayscale\n        gray_img = color_img;\n        \/\/ calculate the difference image\n        gray_diff = gray_img;\n        \/\/ compute the absolute difference with the previous frame&#039;s grayscale image\n        gray_diff.absDiff(previous_imgs&#x5B;0]);\n         \n        Mat diff_mat(gray_diff.getCvImage());\n        Scalar s1 = mean(diff_mat);\n         \n         \n        \/\/ store the current grayscale image for the next iteration of update()\n        previous_imgs.push_back(gray_img);\n        if (previous_imgs.size() &gt; 10) {\n            previous_imgs.erase(previous_imgs.begin());\n        }\n         \n        \/\/ let&#039;s threshold the difference image,\n        \/\/ all values less than 10 are 0, all values above 10 become 255\n        \/\/gray_diff.threshold(10);\n         \n        \/\/ here we will find the sum and then average of all the pixels in the difference image\n        \/\/ this will be used for a simple measure of &quot;motion&quot; \n        \/\/ we use a low-pass filter, a first order filter which combines the current \n        \/\/ value with the previous one, using a linear weighting.\n        sum = (alpha) * sum + \n        (1 - alpha) * s1&#x5B;0] \/ 10.0f;\/\/cvSum(gray_diff.getCvImage()).val&#x5B;0] \/ (float)img_width \/ (float)img_height \/ 10.0;\n         \n         \n        \/\/ let&#039;s change the speed of our movie based on the motion value we calculated\n        video.setSpeed(sum);\n        video.update();\n    }\n     \n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n    ofEnableAlphaBlending();\n    ofEnableBlendMode(OF_BLENDMODE_ADD);\n     \n    color_img.draw(0, 0, img_width, img_height);\n    gray_diff.draw(0, 0, img_width, img_height);\n \n    ofDisableAlphaBlending();\n     \n    video.draw(img_width, 0);\n     \n    \/\/ draw the sum of the motion pixels divided by the number of motion pixels \n    \/\/ (average of difference values)\n    char buf&#x5B;256];\n    sprintf(buf, &quot;%f&quot;, sum);\n    ofDrawBitmapString(buf, 20, 20);\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 2: Image Features, Object Tracking<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-6.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-6.\"><\/object><a id=\"wp-block-file--media-28dbd3ac-a19e-4fbf-9cce-fc47f052d2ef\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-6.pdf\">Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-6<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-6.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-28dbd3ac-a19e-4fbf-9cce-fc47f052d2ef\">Download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lab<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">You\u2019ll need this zip file for the second part of the lab:&nbsp;<a href=\"http:\/\/archive.pkmital.com\/wp-content\/uploads\/2013\/01\/pkmImageFeatureDetector.zip\">[pkmImageFeatureDetector.zip]<\/a><\/p>\n\n\n\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-7.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-7.\"><\/object><a id=\"wp-block-file--media-4132ddfe-4c9e-4987-83f6-bdc47312f58e\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-7.pdf\">Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-7<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-7.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-4132ddfe-4c9e-4987-83f6-bdc47312f58e\">Download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Detecting and Drawing Image Features<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxCvMain.h&quot;\n \nusing namespace cv;\n \nclass testApp : public ofBaseApp{\n \npublic:\n         \n    \/\/ redeclaration of functions (declared in base class)\n    void setup();\n    void setupFeatures();\n     \n    void update();\n    void draw();\n \n    void keyPressed(int key);\n     \n    int width, height;\n    float scalar;\n     \n    ofVideoGrabber camera;\n \n    ofxCvColorImage cv_color_img;\n    ofxCvGrayscaleImage cv_luminance_img;\n     \n    Mat mat_image;\n     \n    unsigned int current_detector; \n    vector&amp;lt;string&gt; feature_detectors;\n     \n    cv::Ptr&amp;lt;FeatureDetector&gt; feature_detector;\n    vector&amp;lt;KeyPoint&gt; keypoints;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.cpp<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#include &quot;testApp.h&quot;\n \n\/\/ here we &quot;define&quot; the methods we &quot;declared&quot; in the &quot;testApp.h&quot; file\n \n\/\/ i get called once\nvoid testApp::setup(){\n     \n    scalar = 1.0f;\n    width = 640;\n    height = 480;\n     \n    camera.initGrabber(width, height);\n     \n    cv_color_img.allocate(width, height);\n    cv_luminance_img.allocate(width, height);\n     \n    feature_detectors.push_back(&quot;SURF&quot;);\n    feature_detectors.push_back(&quot;DynamicSURF&quot;);\n    feature_detectors.push_back(&quot;PyramidSURF&quot;);\n    feature_detectors.push_back(&quot;GridSURF&quot;);\n    feature_detectors.push_back(&quot;SIFT&quot;);\n    feature_detectors.push_back(&quot;STAR&quot;);\n    feature_detectors.push_back(&quot;DynamicSTAR&quot;);\n    feature_detectors.push_back(&quot;PyramidSTAR&quot;);\n    feature_detectors.push_back(&quot;GridSTAR&quot;);\n    feature_detectors.push_back(&quot;FAST&quot;);\n    feature_detectors.push_back(&quot;DynamicFAST&quot;);\n    feature_detectors.push_back(&quot;PyramidFAST&quot;);\n    feature_detectors.push_back(&quot;GridFAST&quot;);\n    feature_detectors.push_back(&quot;GFTT&quot;);\n    feature_detectors.push_back(&quot;PyramidGFTT&quot;);\n    feature_detectors.push_back(&quot;MSER&quot;);\n    feature_detectors.push_back(&quot;PyramidMSER&quot;);\n    feature_detectors.push_back(&quot;HARRIS&quot;);\n    feature_detectors.push_back(&quot;PyramidHARRIS&quot;);\n     \n    current_detector = 0;\n    feature_detector = FeatureDetector::create(feature_detectors&#x5B;current_detector]);\n     \n    ofSetFrameRate(60.0f);\n    ofSetWindowShape(width * scalar, height * scalar);\n}\n \n\/\/ i get called in a loop that runs until the program ends\nvoid testApp::update(){\n    camera.update();\n    if (camera.isFrameNew()) {\n        cv_color_img.setFromPixels(camera.getPixelsRef());\n        cv_color_img.convertRgbToHsv();\n        cv_color_img.convertToGrayscalePlanarImage(cv_luminance_img, 2);\n         \n        mat_image = Mat(cv_luminance_img.getCvImage());\n         \n        keypoints.clear();\n        feature_detector-&gt;detect(mat_image, keypoints);\n    }\n}\n \n\/\/ i also get called in a loop that runs until the program ends\nvoid testApp::draw(){\n    ofBackground(0);\n     \n    ofPushMatrix();\n    ofScale(scalar, scalar);\n     \n    ofSetColor(255, 255, 255);\n    camera.draw(0, 0);\n     \n    ofNoFill();\n    ofSetColor(200, 100, 100);\n    vector&amp;lt;KeyPoint&gt;::iterator it = keypoints.begin();\n    while(it != keypoints.end())\n    {\n        ofPushMatrix();\n        float radius = it-&gt;size\/2;\n        ofTranslate(it-&gt;pt.x - radius, it-&gt;pt.y - radius, 0);\n        ofRotate(it-&gt;angle, 0, 0, 1);\n        ofRect(0, 0, radius, radius);\n        ofPopMatrix();\n        it++;\n    }\n    ofPopMatrix();\n     \n    ofSetColor(255, 255, 255);\n    string draw_string = ofToString(current_detector+1) + string(&quot;\/&quot;) + \n                        ofToString(feature_detectors.size()) + string(&quot;: &quot;) +\n                        feature_detectors&#x5B;current_detector];\n    ofDrawBitmapString(draw_string, 20, 20);\n    draw_string = string(&quot;# of features: &quot;) + ofToString(keypoints.size());\n    ofDrawBitmapString(draw_string, 20, 35);\n    draw_string = string(&quot;fps: &quot;) + ofToString(ofGetFrameRate());\n    ofDrawBitmapString(draw_string, 20, 50);\n}\n \nvoid testApp::keyPressed(int key){\n    if(key == &#039;n&#039;)\n    {\n        current_detector = (current_detector + 1) % feature_detectors.size();\n        feature_detector = FeatureDetector::create(feature_detectors&#x5B;current_detector]);\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Detecting Planar Objects<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n*  Created by Parag K. Mital - http:\/\/pkmital.com \n*  Contact: parag@pkmital.com\n*\n*  Copyright 2011 Parag K. Mital. All rights reserved.\n* \n*   Permission is hereby granted, free of charge, to any person\n*   obtaining a copy of this software and associated documentation\n*   files (the &quot;Software&quot;), to deal in the Software without\n*   restriction, including without limitation the rights to use,\n*   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n*   copies of the Software, and to permit persons to whom the\n*   Software is furnished to do so, subject to the following\n*   conditions:\n*   \n*   The above copyright notice and this permission notice shall be\n*   included in all copies or substantial portions of the Software.\n*\n*   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, \n*   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n*   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n*   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n*   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n*   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n*   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n*   OTHER DEALINGS IN THE SOFTWARE.\n*\/\n#ifndef _TEST_APP\n#define _TEST_APP\n \n#include &quot;ofMain.h&quot;\n \n#include &quot;pkmImageFeatureDetector.h&quot;\n \n#include &quot;ofxOpenCv.h&quot;\n \nconst int CAM_WIDTH = 320;\nconst int CAM_HEIGHT = 240;\nconst int SCREEN_WIDTH = CAM_WIDTH*2;\nconst int SCREEN_HEIGHT = CAM_HEIGHT + 75;\n \nclass testApp : public ofBaseApp {\n \n    public:\n \n    ~testApp();\n    void setup();\n      \n    void update();\n    void draw();\n    void drawKeypoints(vector&amp;lt;KeyPoint&gt; keypts);\n \n    void keyPressed  (int key);\n    void mouseMoved(int x, int y );\n    void mouseDragged(int x, int y, int button);\n    void mousePressed(int x, int y, int button);\n    void mouseReleased(int x, int y, int button);\n    void windowResized(int w, int h);\n     \n    ofVideoGrabber          camera;\n     \n    ofxCvColorImage         color_img, color_roi_img;\n    ofxCvGrayscaleImage     gray_search_img, \n                            gray_template_img;\n     \n    float                   x_start, \n                            x_end, \n                            y_start, \n                            y_end;\n     \n    cv::Point2f             low_pass_bounding_box&#x5B;4],\n                            prev_pass_bounding_box&#x5B;4];\n     \n    float                   alpha;\n     \n    bool                    choosing_img, \n                            chosen_img;\n     \n    pkmImageFeatureDetector detector;\n     \n    vector&amp;lt;cv::KeyPoint&gt;    img_template_keypoints,\n                            img_search_keypoints;\n     \n};\n#endif\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.cpp<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com \n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n * \n *  Permission is hereby granted, free of charge, to any person\n *  obtaining a copy of this software and associated documentation\n *  files (the &quot;Software&quot;), to deal in the Software without\n *  restriction, including without limitation the rights to use,\n *  copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *  copies of the Software, and to permit persons to whom the\n *  Software is furnished to do so, subject to the following\n *  conditions:\n *  \n *  The above copyright notice and this permission notice shall be\n *  included in all copies or substantial portions of the Software.\n *\n *  THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, \n *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *  OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#include &quot;testApp.h&quot;\n\/\/--------------------------------------------------------------\ntestApp::~testApp(){\n}\nvoid testApp::setup(){\n     \n    \/\/ init video input\n    camera.initGrabber(CAM_WIDTH,CAM_HEIGHT);\n    camera.setUseTexture(true);\n     \n    \/\/ window setup\n    ofSetWindowShape(SCREEN_WIDTH, SCREEN_HEIGHT);\n    ofSetVerticalSync(true);\n    ofSetFrameRate(60);\n    ofBackground(0,0,0);\n     \n    \/\/ allocate stuff\n    color_img.allocate(CAM_WIDTH, CAM_HEIGHT);\n    gray_search_img.allocate(CAM_WIDTH, CAM_HEIGHT);\n     \n    alpha = 0.6;\n     \n    choosing_img = false;\n    chosen_img = false;\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n     \n    camera.update();\n    if(camera.isFrameNew())\n    {\n        \/\/ get camera img into iplimage\n        color_img.setFromPixels(camera.getPixels(), CAM_WIDTH, CAM_HEIGHT);\n        color_img.convertRgbToHsv();\n        if (chosen_img) {\n            color_img.convertToGrayscalePlanarImage(gray_search_img, 2);\n            detector.setImageSearch(gray_search_img.getCvImage());\n            detector.update();\n             \n            img_search_keypoints = detector.getImageSearchKeypoints();\n             \n            ofCircle(detector.dst_corners&#x5B;0].x, detector.dst_corners&#x5B;0].y, 10);\n             \n            low_pass_bounding_box&#x5B;0] = detector.dst_corners&#x5B;0] * (1-alpha) + prev_pass_bounding_box&#x5B;0] * alpha;\n            low_pass_bounding_box&#x5B;1] = detector.dst_corners&#x5B;1] * (1-alpha) + prev_pass_bounding_box&#x5B;1] * alpha;\n            low_pass_bounding_box&#x5B;2] = detector.dst_corners&#x5B;2] * (1-alpha) + prev_pass_bounding_box&#x5B;2] * alpha;\n            low_pass_bounding_box&#x5B;3] = detector.dst_corners&#x5B;3] * (1-alpha) + prev_pass_bounding_box&#x5B;3] * alpha;\n             \n            prev_pass_bounding_box&#x5B;0] = low_pass_bounding_box&#x5B;0];\n            prev_pass_bounding_box&#x5B;1] = low_pass_bounding_box&#x5B;1];\n            prev_pass_bounding_box&#x5B;2] = low_pass_bounding_box&#x5B;2];\n            prev_pass_bounding_box&#x5B;3] = low_pass_bounding_box&#x5B;3];\n        }\n    } \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n    ofBackground(0,0,0);\n     \n    ofSetColor(255, 255, 255);\n    \/\/ camera image\n    camera.draw(0, 0);\n     \n    if (chosen_img) {\n        ofSetColor(200, 100, 100);\n        drawKeypoints(img_search_keypoints);\n         \n         \n        ofPushMatrix();\n        ofTranslate(CAM_WIDTH, 0, 0);\n        ofSetColor(255, 255, 255);\n        gray_template_img.draw(0, 0);\n        ofSetColor(200, 100, 100);\n        drawKeypoints(img_template_keypoints);\n        ofPopMatrix();\n         \n        ofSetColor(200, 200, 200);\n         \n        ofLine(low_pass_bounding_box&#x5B;0].x, low_pass_bounding_box&#x5B;0].y,\n               low_pass_bounding_box&#x5B;1].x, low_pass_bounding_box&#x5B;1].y);\n         \n        ofLine(low_pass_bounding_box&#x5B;2].x, low_pass_bounding_box&#x5B;2].y,\n               low_pass_bounding_box&#x5B;1].x, low_pass_bounding_box&#x5B;1].y);\n         \n        ofLine(low_pass_bounding_box&#x5B;2].x, low_pass_bounding_box&#x5B;2].y,\n               low_pass_bounding_box&#x5B;3].x, low_pass_bounding_box&#x5B;3].y);\n         \n        ofLine(low_pass_bounding_box&#x5B;0].x, low_pass_bounding_box&#x5B;0].y,\n               low_pass_bounding_box&#x5B;3].x, low_pass_bounding_box&#x5B;3].y);\n         \n    }\n     \n     \n    \/\/ draw a rectanlge around the current selection\n    if (choosing_img) {\n        int x = mouseX;\n        int y = mouseY;\n         \n        ofNoFill();\n        ofRect(x_start &amp;lt; x ? x_start : x, \n               y_start &amp;lt; y ? y_start : y, \n               abs(x_start - x), \n               abs(y_start - y));\n         \n    }\n     \n     \n}\n \nvoid testApp::drawKeypoints(vector&amp;lt;KeyPoint&gt; keypts)\n{\n    vector&amp;lt;KeyPoint&gt;::iterator it = keypts.begin();\n    while(it != keypts.end())\n    {\n        ofPushMatrix();\n        float radius = it-&gt;size\/2;\n        ofTranslate(it-&gt;pt.x - radius, it-&gt;pt.y - radius, 0);\n        ofRotate(it-&gt;angle, 0, 0, 1);\n        ofRect(0, 0, radius, radius);\n        ofPopMatrix();\n        it++;\n    }\n \n}\n \n \n\/\/--------------------------------------------------------------\nvoid testApp::keyPressed  (int key){\n     \n    switch (key){           \n        case &#039;s&#039;:\n            camera.videoSettings();\n            break;\n        case &#039;n&#039;:\n        {\n            detector.changeDetector();\n            if(chosen_img)\n               img_template_keypoints = detector.getImageTemplateKeypoints();\n            break;\n        }\n        case &#039;1&#039;:\n            break;\n        case &#039;2&#039;:\n            break;\n             \n        case &#039;b&#039;:\n            break;\n             \n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mouseMoved(int x, int y ){\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mouseDragged(int x, int y, int button){\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mousePressed(int x, int y, int button){\n     \n    \/\/ start a rectangle selection\n    if(!choosing_img)\n    {\n        choosing_img = true;\n        x_start = x;\n        y_start = y;\n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mouseReleased(int x, int y, int button){\n     \n    \/\/ end the rectangle selection\n    if (choosing_img) {\n        choosing_img = false;\n        x_end = x;\n        y_end = y;\n         \n        if(x_start &gt; x_end)\n            std::swap(x_start, x_end);\n        if(y_start &gt; y_end)\n            std::swap(y_start, y_end);\n         \n        int w = x_end - x_start;\n        int h = y_end - y_start;\n         \n         \n        cvSetImageROI(color_img.getCvImage(), \n                      cvRect(x_start, \n                             y_start, \n                             w, h));\n         \n        if (color_roi_img.bAllocated) {\n            gray_template_img.clear();\n            color_roi_img.clear();\n        }\n        gray_template_img.allocate(w, h);\n        color_roi_img.allocate(w, h);\n        color_roi_img = color_img;\n        color_roi_img.convertToGrayscalePlanarImage(gray_template_img, 2);\n        cvResetImageROI(color_img.getCvImage());\n \n        detector.setImageTemplate(gray_template_img.getCvImage());\n         \n        img_template_keypoints = detector.getImageTemplateKeypoints();\n         \n        chosen_img = true;\n    }\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::windowResized(int w, int h){\n     \n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 3: Background\/Foreground Modeling, Blob Detection, Blob Tracking<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<figure class=\"wp-block-embed alignwide\"><div style=\"padding:32.5% 0 0 0;position:relative;\"><iframe src=\"https:\/\/player.vimeo.com\/video\/22054133?h=bf65ae1a98&#038;loop=1&#038;title=0&#038;byline=0&#038;portrait=0\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen><\/iframe><\/div><script src=\"https:\/\/player.vimeo.com\/api\/player.js\"><\/script><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This week we will develop a system for blob detection and tracking.<\/p>\n\n\n\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-8.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-8.\"><\/object><a id=\"wp-block-file--media-ce565d8d-5184-4695-8fe4-04ca8fdc4ed3\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-8.pdf\">Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-8<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-8.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-ce565d8d-5184-4695-8fe4-04ca8fdc4ed3\">Download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lab<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">For the second part of the lab, you\u2019ll need this zip file: [<a href=\"http:\/\/archive.pkmital.com\/wp-content\/uploads\/2013\/01\/pkmBlobTracker.zip\">pkmBlobTracker.zip<\/a>]. Extract the contents of this zip file into the \u201csrc\u201d directory of a new openframeworks project that references the ofxOpenCv addon. Be sure that these files are added to your project by simply dragging them to your project navigator\/solution explorer (where you see the list of files).<\/p>\n\n\n\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-9.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-9.\"><\/object><a id=\"wp-block-file--media-f26cc076-e4d3-45dc-94e8-96977032fae9\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-9.pdf\">Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-9<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Workshops-in-Creative-Coding-\u2013-Mobile-and-Computer-Vision-9.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-f26cc076-e4d3-45dc-94e8-96977032fae9\">Download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 4: Face Detection, Face Shape Models, Face Expressions, and Face Motion Capture<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">There are no slides for this or next week. Instead, we will look at code together. This week, we focus on faces.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are few specific tasks you may want to achieve when looking at faces:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Detection<\/strong>: Think of this as a binary exercise. Is this is a face or not?<br><strong>Recognition<\/strong>: Think of this as a classification of a possible set of faces. Is this John or Jill?<br><strong>Tracking<\/strong>: This involves either of the previous stages, as well as understanding the same face has persisted over time. From frame&nbsp;<code>t<\/code>&nbsp;to frame&nbsp;<code>t+1<\/code>, is this the same face I just saw?<br><strong>2D\/3D<\/strong>: If you just want the bounding box of the face in an image, this is 2D detection. However, if you\u2019d also like to know the face\u2019s orientation, this is knowing the object\u2019s pose, and is a 3D detection problem.<br><strong>Expression<\/strong>: This is classifying the information in the face to a set of possible emotions. These emotions can be discrete states meaning only one of a possible set of emotions are possible. Or, more likely, these are \u201cvalences\u201d, and are likelihoods of being any possible emotion.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you have already had a look at the OpenCV examples that come with openFrameworks, you\u2019ll have seen the \u201copencvHaarFinderExample\u201d. This is an example of using Haar-like features for detecting a face. It\u2019s not very good, but it is one of the most commonly used face detectors since it is easily accessible. Many better face detectors will use this one as a \u201cfirst-pass\u201d, and then prune out the false-positives with a better detection algorithm (e.g. ASM\/AAM models).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you\u2019d like to know more about the face though, such as its pose or expression, you\u2019ll have to start looking at other models.&nbsp;<a href=\"http:\/\/www.ics.uci.edu\/~dramanan\/papers\/face_2012.pdf\">This paper<\/a>&nbsp;is in my opinion the current state-of-the-art for face detection, pose estimation, and facial shape modeling. There is a&nbsp;<a href=\"https:\/\/github.com\/wg-perception\/PartsBasedDetector\">C++ library<\/a>&nbsp;here.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is also the work of&nbsp;<a href=\"http:\/\/jsaragih.org\/\">Jason Saragih<\/a>. He has built a very nice model called&nbsp;<a href=\"http:\/\/web.mac.com\/jsaragih\/FaceTracker\/FaceTracker.html\">FaceTracker<\/a>&nbsp;for discovering landmarks of faces which you could use to train a facial expression library. Check out Jason\u2019s vimeo page to see some examples of how this technology can be extended. Kyle McDonald has also written a very extensive openFrameworks library for using this library called&nbsp;<a href=\"https:\/\/github.com\/kylemcdonald\/ofxFaceTracker\">ofxFaceTracker<\/a>. He has also demonstrated its use with Arturo Castro on Face Substitution. Have a look at Kyle\u2019s course on&nbsp;<a href=\"https:\/\/github.com\/kylemcdonald\/AppropriatingNewTechnologies\/wiki\/Week-2\">Appropriating New Technologies<\/a>&nbsp;to see other information on facial detection and also many cultural references.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To get started with FaceTracker, you have a lot of options. You can go straight to Jason\u2019s course and start detecting faces without openFrameworks. Or you can get into ofxFaceTracker and see the examples Kyle has created. Just a note, ofxFaceTracker requires&nbsp;<a href=\"https:\/\/github.com\/kylemcdonald\/ofxCv\">ofxCv<\/a>. Some examples in ofxFaceTracker also require&nbsp;<a href=\"https:\/\/github.com\/ofTheo\/ofxControlPanel\/\">ofxControlPanel<\/a>. Be sure to have both of these addons copied to your addons folder of openFrameworks. You can also use&nbsp;<a href=\"https:\/\/github.com\/kylemcdonald\/ofxFaceTracker\/downloads\">FaceOsc<\/a>, a program written by Kyle to stream information via OSC from FaceTracker. This is a binary application (no source required, though it is in ofxFaceTracker\u2019s branch), so you can get started with face tracking right away if you\u2019d like.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside of ofxFaceTracker, Kyle has also started to write an \u201cExpression\u201d engine. There is an example that tries to classify different expressions that you train. Like any classification algorithm, this requires examples. In classification, there are two phases: training and testing. Training requires you to have a set of examples for every class (i.e. facial expression). Testing is then when you try and of the classes (i.e. facial expressions) and see if it correctly guesses the correct class (i.e. facial expression). There is a huge amount of literature on ways of doing classification.&nbsp;<a href=\"http:\/\/www.amazon.com\/Pattern-Recognition-Learning-Information-Statistics\/dp\/0387310738\">Pattern Recognition and Machine Learning<\/a>&nbsp;by Christopher Bishop is a great book for learning these.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Kyle\u2019s approach to classification of facial expressions is based on the nearest neighbor of a set of training examples. Given a set of classified examples (the training data), any new face can be classified by finding the nearest example (computed using the euclidean distance or L2-norm). Have a look at the \u201cexample-expression\u201d app to see how this works in practice.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In practice, you will find that face detection algorithms are noisy, pick out a lot of false positives, and work better for lighter skin types than darker ones. As well, the more beardy\/hairy you are, the more likely the algorithm will fail. Babies as well have very different facial profiles and will perhaps fail on any classifiers built for adults. Lighting, as with pretty much every camera-based computer vision algorithm is very important. Infrared lighting can help you achieve much more control of your environment. Keep this in mind if you are having poor detection results.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your detection algorithm has found the eye, does this mean I can start to control the mouse pointer? No. There is a huge giant leap to go from detecting the eye in a camera image, to understanding where the eye is looking in reference to a monitor. For an open-source project of eye-tracking, have a look at these two projects:&nbsp;<a href=\"https:\/\/github.com\/eyewriter\/eyewriter\">EyeWriter<\/a>&nbsp;(cross-platform C\/C++) and ITU GazeGroup\u2019s&nbsp;<a href=\"http:\/\/www.gazegroup.org\/downloads\/23-gazetracker\">GazeTracker<\/a>&nbsp;(Windows only, written in C-Sharp). The latter is much more advanced though is written in C# (Windows only).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/faceshift.com\/\">FaceShift<\/a>&nbsp;is another technology that you should check out. It\u2019s still in beta but you can get a 30-day license for free. They describe their work:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Our software analyzes the face motions of an actor, and describes them as a mixture of basic expressions, plus head orientation and gaze. This description is then used to animate virtual characters for use in movie or game prodcution. We have astonishing real time tracking and a high quality offline postprocessing in a single, convenient application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Kyle McDonald has written a nice openFrameworks wrapper,&nbsp;<a href=\"http:\/\/github.com\/kylemcdonald\/ofxFaceShift\">ofxFaceShift<\/a>, for interfacing with this library. He also wrote a binary similar to FaceOsc,&nbsp;<a href=\"http:\/\/github.com\/kylemcdonald\/ofxFaceShift\/downloads\">FaceShiftOsc<\/a>, which just outputs some essential information. Check out his&nbsp;<a href=\"http:\/\/vimeo.com\/46916078\">video tutorial<\/a>&nbsp;with associated links and guide here.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This technology requires the Kinect or similar depth sensing device. Note, if you are interested in facial capture, the&nbsp;<a href=\"http:\/\/www.primesense.com\/developers\/get-your-sensor\/\">Carmine 1.09<\/a>&nbsp;is a better device to use. Next week, we\u2019ll look in more depth at depth sensors and the capabilities of using OpenNI with the Kinect.<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lab<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Please make sure you have a group by now and an idea ready to discuss. Next week I will need 300 words from every group. This week, I will be coming to every lab to get a better sense of what you are planning to do and to give you feedback on your ideas. Please work towards your group projects.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 5: (ofx)OpenNI, RGBDToolkit, RGBDemo, (ofx)PTAMM<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>OpenNI<\/strong><br>This is an open-source SDK for developing middleware libraries for Natural Interaction. Middleware acts as a bridge between hardware specific routines, and more general routines. This means that you may have a number of different hardware, such as the Asus Xtion or the Kinect XBox sensor, and you can use the same application so long as there is a middleware that talks to either device. The middleware has to be written with the general framework in mind, however. Also, the middleware itself may not necessarily be open-source.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Primesense, the makers of the sensor on board the Kinect XBox, have developed a middleware called NITE. This allows you to do skeleton tracking and hand tracking. This is perhaps the most popular middleware. There are others&nbsp;<a href=\"http:\/\/www.openni.org\/software\/?cat_slug=file-cat1#.UUiN2Fv7Ji4\">listed here<\/a>&nbsp;which I have not tried, though which look promising.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because the Kinect uses a Primesense sensor, you can use the NITE middleware to do skeletal tracking and hand tracking. However, this middleware expects you to have a driver which provides an interface to the hardware. Luckily the community has worked on doing all the USB sniffing etc\u2026 required for figuring out how to do this.&nbsp;<a href=\"https:\/\/github.com\/avin2\/SensorKinect\">Here<\/a>&nbsp;are the sensor drivers for the Kinect. Before you download this, note if you are going to use ofxOpenNI, you won\u2019t need to download this, or NITE, or OpenNI.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/gameoverhack\/ofxOpenNI\" target=\"_blank\" rel=\"noreferrer noopener\">ofxOpenNI<\/a><br>Be sure to read the included README file for instructions on how to get it running. There are included compiled libraries for OSX. ofxOpenNI includes the SensorKinect, NITE, and OpenNI libraries required for working with the Kinect sensor. It also provides a simple to use openFrameworks library which communicates with the OpenNI library.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/www.rgbdtoolkit.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">RGBDToolkit<\/a><br>Using a DSLR and a Kinect, you can create very vivid point clouds.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/labs.manctl.com\/rgbdemo\/\" target=\"_blank\" rel=\"noreferrer noopener\">RGBDemo \u2013 Object\/Scene Reconstruction<\/a><br>From the surface reconstruction or object model acquisition example, you can import the \u201cply\u201d or \u201cmodel\u201d file into&nbsp;<a href=\"http:\/\/meshlab.sourceforge.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">MeshLab<\/a>. Here is a&nbsp;<a href=\"https:\/\/vimeo.com\/20933872\">video<\/a>&nbsp;by Kyle McDonald describing how you can transform these points into a set of faces describing a surface. Here is a&nbsp;<a href=\"https:\/\/www.youtube.com\/watch?feature=player_embedded&amp;v=iK_r2Ru3wP4#!\" target=\"_blank\" rel=\"noreferrer noopener\">video<\/a>&nbsp;by Nicolas Burrus demo-ing the object acquisition process.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Going from point clouds (what the Kinect gives you, a bunch of 3D points, or a Depth Image) to a 3D model with \u201cfaces\u201d (vertices describing triangles with associated normals) involves a processes called surface reconstruction. You could, for instance, model an arbitrary object in 3D, such as a car, face, or an entire room, and use this technique to build a digital 3D model of it. You could then import that model into a game engine for instance. Or maybe use our 3D printer and see what it looks like as a scale model.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Generally, there are a number of stages involved, all of which you can do in&nbsp;<a href=\"http:\/\/meshlab.sourceforge.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">MeshLab<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here are the parameters he uses in the video:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Render-&gt;Show Vertex Normals<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Filters-&gt;Point Set -&gt; Compute Normals<br>Neighbors 16<br>Flip Normals checked<br>-1000 Z<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Filters-&gt;SamplingFilters-&gt; Poisson-disk<br>Samples:5000<br>Base Mesh Sampling Checked<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Filters-&gt;Point Set-&gt;Surface Reconstruction: Poisson<br>Octree: 12<br>Solver: 7<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Filters-&gt;Remeshing-&gt;LS3, 3 Iterations (default)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Filters-&gt;Sampling-&gt;Vertex Attrib Transfer<br>Source: *.ply<br>Target: Poisson Mesh<br>Transfer Geometry<br>Transfer Normal<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Filters-&gt;Cleaning-&gt;Remove Duplicate Vertex<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These parameters are highly dependent on your data set. You will likely have to read more about these to understand how they effect the output in order to obtain better results. For surface reconstruction, also have a look at the \u2018Marching Cubes\u2019 and \u2018Ball Pivoting\u2019 algorithms instead of \u2018Poisson\u2019 to see how these compare.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Generally, you want to scan your object in very controlled light situations, with low IR as the Kinect is highly dependent on IR for its depth image construction. As well, you will want to move the Kinect at a very controlled speed and with similar rotation\/translation around an object or scene. Ideally, nothing in the scene is changing, unless this is part of your process.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/labs.manctl.com\/rgbdemo\/\" target=\"_blank\" rel=\"noreferrer noopener\">RGBDemo \u2013 3D Projector\/Camera Calibration<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also included in RGBDemo are routines for doing intrinsic and extrinsic calibration of a projector and camera. \u2018Intrinsic\u2019 parameters of a lens describe the transformation from camera\/projector space to world space. In other words, it describes how the camera\/projector\u2019s lens warps what it sees. Think of a fish-eye lens image. This image is incredibly warped because of the shape of the lens. However, knowing the intrinsic parameters of this lens, you can un-warp the image back to what we\u2019d see in the real-world (though we also have a warped perspective closer towards our periphery). What this means is any parallel lines in the world space (i.e. what we see), will also be parallel in the image space (i.e. what the camera sees).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once you calculate the intrinsics of the camera, you can un-warp the image received by the camera device. This image will have all parallel lines mapped to parallel lines. You can also do this for a projector.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can also do one more really cool thing: extrinsic calibration of a camera and projector. This means you can capture something with the camera, then project it back into the real world with the camera image aligned to the projector\u2019s point of view. You would ideally do some processing on the image, or tracking, or augmented reality of this image before projecting it back into the world.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>PTAM\/PTAMM<\/strong><br><a href=\"http:\/\/www.robots.ox.ac.uk\/~gk\/PTAM\/\" target=\"_blank\" rel=\"noreferrer noopener\">PTAM<\/a>&nbsp;and associated&nbsp;<a href=\"https:\/\/ewokrampage.wordpress.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">blob<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ofxPTAMM<\/strong><br><a href=\"http:\/\/www.patriciogonzalezvivo.com\/blog\/?p=563\" target=\"_blank\" rel=\"noreferrer noopener\">ofxPTAMM<\/a>. Follow the steps of the included README as there a few things to do before getting the example project running. It comes with compiled sources for OSX 10.6 and 10.7, and iOS 5.0. There are instructions for getting it up and running for Linux and Windows. For OSX 10.7, I also had to add the frameworks \u201cQTKit\u201d and \u201cCoreVideo\u201d to my project.<\/p>\n<\/div>\n<\/div>\n","protected":false},"featured_media":2975,"template":"","categories":[15],"teaching-type":[395,396],"class_list":["post-2961","pkm_teaching","type-pkm_teaching","status-publish","has-post-thumbnail","hentry","category-teaching","teaching-type-computer-vision","teaching-type-creative-coding"],"acf":[],"_links":{"self":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/pkm_teaching\/2961","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/pkm_teaching"}],"about":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/types\/pkm_teaching"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/media\/2975"}],"wp:attachment":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/media?parent=2961"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/categories?post=2961"},{"taxonomy":"teaching-type","embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/teaching-type?post=2961"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}