Placeholder Image

Subtitles section Play video

  • [TRAIN WHISTLE]

  • Hello and welcome to another video tutorial

  • about working with Runway and running machine learning models

  • in Runway itself.

  • Now, before you watch this video tutorial,

  • if you've never used Runway before,

  • you might want to go back and look at my Introduction

  • to Runway, how to download and install it.

  • But to be honest, you probably can figure that out

  • if you just go to runwayml.com and click on Download Beta.

  • You're going to want to download and open the runway software.

  • You'll go then to Browse Models.

  • I might go here under Motion, and I'm going to click PoseNet.

  • And you'll find yourself right here.

  • So this is where I am.

  • I've installed Runway.

  • I've downloaded it.

  • And I'm on the page in the Runway software for the PoseNet

  • machine learning model.

  • Now, what is PoseNet?

  • PoseNet is a machine learning model

  • that performs real-time skeletal tracking of one or more people.

  • And guess what?

  • I'm a person, and I've got Runway running here

  • with PoseNet.

  • So I'm going to run it.

  • So let's actually first click Add To Workspace.

  • So I already have a workspace that I've

  • made in the previous video called Coding Train Live

  • Stream.

  • I want to choose an input source, which

  • I want it to be my webcam.

  • So, yep, Runway go right ahead, and there I am.

  • And then I want to choose an output source, which eventually

  • I want to be processing, because I want

  • to get the results of running this machine learning model

  • PoseNet into processing itself.

  • But for right now, I'm just going to click on Preview.

  • So I click on Preview.

  • Oh, and I have to run.

  • But guess what?

  • So this is different than what I've showed in previous videos.

  • I've got an option for Run Locally.

  • And, in fact, this model can only be run locally.

  • It would be silly to run this one in the cloud,

  • because I'd have to spend all this time sending

  • the data over the network.

  • And it's very easy for it to run.

  • This is a very small, fast model.

  • It can be run on most modern computers.

  • So I'm going to click Run Locally.

  • So it requires no GPU credits.

  • Absolutely, can be used for free.

  • And we can see there it goes.

  • It's running right now.

  • It is making guesses as to where the various key points

  • of my skeleton are on my body in the output That's. viewable

  • below.

  • So one of the nice things about working

  • with Runway and its models is a lot

  • of times models have different parameters and values

  • and things that you can tweak and change to try running it

  • in different ways.

  • And these are sort of known as hyper parameters

  • to a machine learning model.

  • And so some of them I would actually

  • have to stop running the model and then

  • I can start to play with it.

  • So, for example, this Architecture one

  • is something I can actually make the models smaller.

  • It might be less accurate, but it will run faster.

  • But so, for example, I'm just going

  • to change this to 0.75 instead.

  • I'm going to run it again.

  • But some of these parameters can actually

  • be tweaked in real time.

  • So, for example, I can change the width and height

  • of the image, which is actually changing

  • the resolution of the image from the webcam itself.

  • And I can make it more grayscale if I want.

  • I could do various things to actually tweak

  • the image before it goes in.

  • But this is not the important piece

  • of what I want to do in this video.

  • What I want to do in this video is

  • we have a moment here where I've got a model running in Runway.

  • And I'm able to play with it, tweak it, get it exactly

  • the way I want it to work.

  • And I want to take that next step

  • from having it run here to be able to see the result of it

  • in my own piece of software.

  • So let's make that happen.

  • This software that I'm going to use to attempt this

  • is something called Processing.

  • So since this size here in Runway of the output

  • is 640 by 362, what I'm going to do in my Processing code

  • is set the size of the canvas to 640 by 362.

  • void draw.

  • background 0.

  • So now, I have a Processing sketch,

  • which I am running right here.

  • How do I see the results, the output of the model

  • in my Processing sketch?

  • So there are a variety of different network protocols

  • that Runway supports.

  • And I can find out about them up here

  • by clicking this Network tab.

  • And the one that I want to use for working with Processing

  • is OSC.

  • So there's a variety of reasons why you might

  • pick one protocol over another.

  • It really depends on what you're doing.

  • In the case of where I just want to get a single image,

  • an HTTP request would make the most sense.

  • And I'll do that in another video

  • when I show you how to work with style again in Runway.

  • But right now, I'm going to click

  • on OSC, which works pretty well with Processing.

  • And it's telling me a lot of information here.

  • So it's saying, hey, this is the server address.

  • So this is the most important thing that I need from Runway.

  • It's what I'm going to tell Processing is the unique IP

  • address, which happens to be the local IP

  • address of this computer and the port number

  • from which it can get the OSC messages.

  • I'm going to click here.

  • And I'm going to create a string called like ip.

  • I'm pretty sure I'm probably going

  • to want the port number in a separate variable.

  • And I'm going to create a port number like this.

  • Now, I could sit here and write all the code

  • for this, which is what I usually

  • do in Coding Train videos.

  • But this is a fairly different circumstance.

  • I really just want to get the example up

  • and running and show you how to do this.

  • And one of the nice things about working with Runway

  • is there are a whole bunch of premade examples

  • for you with different platforms and pieces of software,

  • one of which is Processing.

  • So let me show you how you would actually

  • do this in the real world, how I would be doing this, which

  • is the way to do it right now.

  • So if I go to the Runway ML GitHub--

  • and I actually should go back one level

  • and go here under Runway ML.

  • You can see here's the GitHub page for the Runway software.

  • And there's a lot of information.

  • There's some sort of like high-level stuff

  • here about how to port your own machine learning model

  • to Runway itself.

  • So if you've trained your own model or you

  • find a model that's not supported by Runway,

  • how you could add it.

  • But that's not what we're really doing here.

  • What I want to look for is here Processing, Runway

  • and Processing.

  • If I click here, this repository has

  • a whole bunch of examples of using Runway with Processing.

  • So you can see there's a StreetView one, attnGAN,

  • face landmarks, im2txt, and, voila, PoseNet.

  • This is the one that I'm working with.

  • So I'm going to look at this example.

  • I should say that this is an open source project.

  • Processing is an open source project

  • that I'm involved with that I've talked

  • about in a lot of other videos.

  • So maybe this is a place where if you find another model

  • in Runway that you've made work and you want to contribute

  • your Processing example here, I would encourage you to do that.

  • And Chris, one of the founders and creators of Runway,

  • and I have been talking about making a Processing

  • library for Runway.

  • And it just so happens that I made two recent video tutorials

  • about how to make a Processing Java library.

  • So I see a project in the future, which is a Processing

  • library for Runway.

  • So if you want to get involved with that, with making that,

  • write in the comments and let me know.

  • And maybe we'll create a GitHub repo for that.

  • OK, so I mean to go here under PoseNet.

  • And I'm just going to click here under posenet.pde.

  • So I could just copy paste the whole thing,

  • but I'm going to kind of go piece by piece.

  • And you can see here already Runway host and Runway port.

  • So I made a mistake in my code.

  • So I got a-- oh, I'm missing the 0.1 here,

  • which I'm sure the Chat is already talking about.

  • And there's an extra 1 here.

  • And this should be an integer.

  • And this would really be Host.

  • So actually let me use the same variable

  • names, runwayHost and runwayPort.

  • OK, so I think I've gotten this right now.

  • Now, in order for the example to work,

  • I need to make sure also I have the Processing OSC

  • library installed.

  • So if I come over here, I can copy

  • paste these import statements.

  • I can copy paste this OSC object that I definitely need.

  • And we'll see very quickly that I

  • have an error, which is the class OscP5 does not exist.

  • This is because I haven't installed the Processing OSC

  • library.

  • You might have already have it installed because you use it

  • with a different project.

  • But I could go here.

  • And I could do Sketch, Import Library,

  • Add Library, OSC to search for it.

  • This is the library I'm looking for oscP5.

  • I'm going to click Install.

  • And now, you'll see that error message goes away.

  • The next thing that I want to do is create an object

  • to receive OSC messages.

  • And I think I can just make this a new OscP5 object.

  • I need to give it a reference to this particular sketch,

  • because it's going to need to trigger events in the sketch

  • when there's data available.

  • And then just give it the port number.

  • This is called runwayPort.

  • So if you look at the runway example,

  • it's actually using this object called OscProperties, which

  • is a bit more sophisticated.

  • It says a remote address, a listening port, a datagram

  • size, and some other stuff.

  • I should probably just copy paste this into my example,

  • but I'm curious if it will work with just the sort of more

  • simplified default OscP5 object, where I just say

  • this and the particular port.

  • But I do need this.

  • I do need a broadcast location, because I'm

  • going to have to send messages to Runway as well, saying I'm

  • connected or I'm disconnected.

  • So there's two things at play here.

  • There's the Processing software.

  • And there's the Runway software.

  • They're both running locally on my computer.

  • Now, it's possible that in other scenarios

  • there could also be a cloud GPU involved

  • that runway sends messages back and forth between.

  • And this is something that I'm going

  • to do in the next example, where I work

  • with something called StyleGAN.

  • I'm going to have Runway also talk to a cloud GPU.

  • But that's not happening here.

  • PoseNet is actually running inside of--

  • basically wrapped into Runway itself locally.

  • So PoseNets running here in Runway locally.

  • Processing is sending a message like connect.

  • Like, hey, I want to hear information.

  • That's a one-time message.

  • And then Runway will just continuously send data via OSC

  • to Processing about what pose it's detecting with the PoseNet

  • model from the webcam input.

  • So if I wanted, I probably could figure out a way

  • to get the camera input into Processing,

  • send the image to Runway, and then have

  • Runway send the results back.

  • But Runway can connect to the camera directly,

  • so I might as well just do that, because that's pretty easy.

  • So I should also put here that like

  • if I make a little note here, like webcam--

  • that webcam is talking to Runway.

  • I might also have it talk to Processing

  • if I want to show the results in Processing as well.

  • So this is what's going on in this particular example.

  • So I want to create this broadcast location, which

  • is a net address object.

  • So I need to put that in here.

  • And then the first thing that I want to do

  • is just send the connect message.

  • So I'm going to copy this in and paste it here and say Connect.

  • So what I'm doing when Processing starts up

  • is it calls the function connect, which

  • creates an OSC message.

  • Every single OSC message is comprised of two parts.

  • Those two parts are an address, which

  • is usually denoted as a string, kind of like a path--

  • and you can see this is server/connect.

  • That's the address.

  • Or you might also think of that almost as like the message

  • name as the way I sometimes think about it--

  • and then the data.

  • Now, in this case, there actually

  • is no data, because the address itself is the message.

  • So this is a very simplified thing,

  • where this connect message is just, hey, I'm connecting.

  • So the name of the message, the address,

  • is the only thing needs to be there.

  • There's no data.

  • But when Runway sends data back, it's

  • going to have a message name, like a data or key points

  • or poses, something like that.

  • And then that's going to have packaged with it lots of data,

  • like all the xy's of all the positions of everything.

  • All right, so let's run this and see what happens.

  • Yeah, that's pretty good.

  • No errors.

  • Now that I've connected, I want to listen for messages.

  • And the way that that is done is with an event called OSC Event.

  • So this is much like mouse pressed

  • or key pressed or serial event or capture event.

  • This is a function in Processing that has a very special name,

  • called OSC Event.

  • And the oscP5 library knows to call that function

  • when there's data coming in.

  • So I'm going to just copy paste this.

  • And I'm going to put it in here.

  • And what I'm going to-- so let's take a look at this.

  • So there's an OSC Event that has passed through it

  • an OSC message.

  • I'll just change this to message.

  • And if the message has that data--

  • so this is like its address.

  • Remember that?

  • Its address has data, that's the address we're looking for.

  • Or if it doesn't, get out of here.

  • So I want to ignore any other messages coming in.

  • Then what I want to do is get the data itself.

  • So the data of the message actually comes in as a string.

  • But the string is formatted as JSON, which

  • is JavaScript Object Notation.

  • If you don't know what JSON is I might refer you

  • to a different video of mine that explains what JSON is.

  • JSON works really nicely in JavaScript.

  • It's a little bit awkward to work with it

  • in Processing, because Processing is Java.

  • It doesn't speak JavaScript natively.

  • But we're going to make it work.

  • So the first thing in the message

  • itself is a big string of JSON data, which then is a JSON

  • object that can be parsed with Processing's parseJSONObject

  • function.

  • And then I can just look at it in the console.

  • So let's see if we actually get the data in.

  • I'm not getting anything.

  • And I'm wondering why.

  • And actually I know why, because I had to figure it out.

  • So first of all, there's a clue to me here.

  • It says, could not create datagram socket

  • port 5100, because it's already in use.

  • And I forgot there's a weird thing going on here.

  • If I were using OSC to communicate between two

  • separate computers, I could use the same port number

  • on each separate computer because it's just

  • one port number.

  • But, here, I need to be able to send data to runway

  • at a particular port, as well as receive data into processing

  • at a different port that cannot be the same port,

  • otherwise it will be in conflict.

  • So the port that I am broadcasting to is 57100.

  • That's what's listed in Runway.

  • But the actual port that I want to receive messages at

  • is 57200.

  • And maybe Runway knows just to add 100 to it automatically

  • behind the scenes.

  • But this is the default setup that's in Runway.

  • So I need to have a different port for receiving the data,

  • as the port that I'm sending to.

  • And let me show you what I mean by that in the code.

  • So this is the Runway port right there, 57100.

  • That's the port that I want to broadcast to.

  • And it's part of my broadcast location.

  • That's where I'm broadcasting to.

  • But where I want to receive messages is actually 57200.

  • So now, if I run this, I'm actually receiving messages.

  • But I've got a new error--

  • ArrayIndexOutOfBoundsException.

  • So this is a rare case, where the data that Runway

  • is sending for all of these poses is actually quite large.

  • And so what it needs is more space.

  • It needs a bigger packet size.

  • And so that's why in the Runway example

  • there was this extra OSC properties

  • object, which allowed setting a larger datagram size.

  • And the listening port is 57200.

  • So just before using OscP5 by default--

  • you don't need to do this, but I'm

  • going to copy paste this in.

  • I'm going to put this back here and then

  • I am going to change this to properties.

  • And I think I now have all of the pieces,

  • and what I should see is-- there we go, a lot of stuff.

  • And look at this.

  • Now, I've got exactly coming into processing a confidence

  • score--

  • it clearly cannot see my left ankle,

  • because my left ankle is not viewable to the camera.

  • So that's why that confidence score is so low.

  • Let's scroll up and do like right ear.

  • It's got a very high confidence score and an x and a y

  • for my right ear.

  • So now, I'm at the point, where I can actually use this data.

  • Going back to the Runway example,

  • you can see here that there's a very elaborate loop

  • to parse through the JSON and look

  • at all the different key points and get

  • all the different positions of everything that it detects.

  • I'm going to try to do something much simpler right now.

  • I'm just going to get the right eye and left eye.

  • So let's see if we can figure that out.

  • One way we can approach this is we

  • can make this data variable a global variable.

  • So I'm going to take this JSON object.

  • And I'm going to make this a global variable.

  • I'm going to call it data.

  • And then, in the draw loop, I'm just

  • going to say as long as data is not equal to null--

  • I forget that I'm in Java.

  • I can just do that--

  • data will be null until it's received something from Runway.

  • So as soon as it's received something from Runway,

  • all I need to do now is parse this JSON.

  • Something I've done to make this a little bit easier

  • is I've just taken that JSON that prints it

  • to the processing console and I've

  • pasted it into a into a JSON file

  • that I can look at in Visual Studio Code

  • just so I have something to reference to for.

  • So I know that I need to get something called poses.

  • So the first thing that I want is the poses array.

  • So one of the thing that's really weird in Processing

  • with JSON is you have to specify whether the data you're

  • looking at is a JSON object or JSON array.

  • And this poses data is an array, as indicated

  • by this square bracket.

  • So I'm going to say JSONArray poses equals

  • data.getJSONArray string poses.

  • Then, I want to get the key points array.

  • Oh, because there could be more than one pose.

  • But I'm going to assume there's just one pose.

  • So then that's the poses.

  • So then I'm going to say the key points are also

  • an array equal poses.get 0.

  • So that would be the first element of the array.

  • Now, get a new array called key points.

  • Get a JSON array key points.

  • The good news is the Runway example

  • has all of this in there, so if I get it wrong--

  • key points.

  • I have an error here, because I can't just say get element 0.

  • What is element 0?

  • It's a JSON object.

  • There we go.

  • So now, I have the key points, which

  • are the JSON array called key points in the first JSON object

  • index 0.

  • Then, what do I want to look for?

  • So now, I'm in the key points array.

  • This is element 0.

  • If I knew like left--

  • oh, this is easy, let's do nose, left eye, and right eye,

  • 0, 1, and 2, perfect.

  • So I want to get JSONObject nose equals

  • keypoints.getJSONObject 0.

  • And we'll do three of these.

  • Left eye-- I'm doing this a little bit

  • different than the Runway example.

  • And then I'll point you runway example after right eye.

  • Certainly, I could use a loop here--

  • so nose, left eye, right eye.

  • And then I need to get the position--

  • nosePos equals nos.getJSONObject.

  • I should just do the nose.

  • I'm just going to do the nose just

  • to keep things simpler here.

  • You can extrapolate to figure out

  • how to do the left eye and the right eye--

  • nose.getJSONObject position.

  • And then x equals--

  • I'm going to call this nose position.

  • Nose position gets x.

  • Pretty sure this is right.

  • And y equals nosePosition.get y.

  • All right, let's see, what have I gotten wrong here?

  • getFloat.

  • Again, I'm in Java.

  • I've got to specify the type.

  • So if I've done everything correctly,

  • I've gotten all the key points of the first pose.

  • I've gotten the object with all the data for the nose.

  • Then I can get the nose position out of that object, then the x

  • and y out of that object.

  • Phew.

  • Now, I'm gong to say ellipse x,y 2020.

  • And let's make it a red nose.

  • fill 255.0.0.

  • Let's give this a run.

  • And there we go.

  • I am now controlling my nose.

  • From Runway into Processing with OSC messages.

  • Amazing.

  • OK, so this really concludes this particular video tutorial.

  • Certainly, what you might want to do

  • is see the entire skeleton.

  • To use PoseNet effectively, you really

  • want to have the camera probably around 6 feet from you.

  • You want to back up and allow it to see your full form.

  • You can also pass it images and get the pose, the skeleton off

  • from an image.

  • There's lots of different things you can do.

  • And, certainly, I would recommend

  • that you check the example in the Runway GitHub repo itself,

  • which has a nice loop to go through all

  • of the different positions.

  • And actually it also has this little mapping to map

  • what all the connections are between them

  • for the actual skeleton itself.

  • So as a little exercise, see if you

  • can expand what I did to have the right eye and the left eye.

  • But even so, you could just go get the Runway example itself.

  • But this is a guiding principle for how

  • any particular model that you might find in Runway itself--

  • someone in the chat was just asking about dense

  • pose, for example, that you can communicate from runway via OSC

  • to Processing.

  • But in a lot of other cases, you might

  • want to use web sockets or an HTTP connection

  • to communicate, particularly if you're working

  • in the browser with JavaScript.

  • So what I'm going to do in the next video,

  • if you want to watch, is run StyleGAN to generate a rainbow

  • image and then pass that image into P5

  • and render it in the browser itself.

  • And breaking news from the chat, Damien

  • writes SRSP stand for Send and Receive on the Same Port.

  • By default, OSC packets are not received and sent

  • by the same port, if you need to send or receive

  • in the same port.

  • Oh, so maybe I could have actually done something

  • with the port numbers.

  • I have no idea.

  • I'm sure people will write about it in the comments.

  • But this code works.

  • The code in the Runway GitHub repository works.

  • So how fun.

  • Use it.

  • Make something with it.

  • Please share it with me.

  • And hope you enjoyed this tutorial about Processing,

  • Runway, and the PoseNet model running locally

  • on your computer.

  • Goodbye.

  • [TRAIN WHISTLE]

  • [MUSIC PLAYING]

[TRAIN WHISTLE]

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it