1515// You should have received a copy of the GNU General Public License
1616// along with RunwayML. If not, see <http://www.gnu.org/licenses/>.
1717//
18+ // ===============================================================
19+ //
20+ // Runway: OpenPose Send Webcam Demo
21+ // This example sends one image to Runway and draw all humans detected in the image
22+ // p5.js is used to draw the human data sent from Runway
23+ // You should select HTTP from the Input Panel
24+ //
25+ // Cristóbal Valenzuela, George Profenza (merging sendImage and receviesOnly examples)
26+ // cris@runwayml .com
27+ //
28+ // ===============================================================
29+
30+ var capture ;
31+ var w = 400 ;
32+ var h = 225 ;
33+ var colors ;
34+
35+ // This are all the body connections we want to draw
36+ var bodyConnections = [
37+ [ 'Nose' , 'Left_Eye' ] ,
38+ [ 'Left_Eye' , 'Left_Ear' ] ,
39+ [ 'Nose' , 'Right_Eye' ] ,
40+ [ 'Right_Eye' , 'Right_Ear' ] ,
41+ [ 'Nose' , 'Neck' ] ,
42+ [ 'Neck' , 'Right_Shoulder' ] ,
43+ [ 'Right_Shoulder' , 'Right_Elbow' ] ,
44+ [ 'Right_Elbow' , 'Right_Wrist' ] ,
45+ [ 'Neck' , 'Left_Shoulder' ] ,
46+ [ 'Left_Shoulder' , 'Left_Elbow' ] ,
47+ [ 'Left_Elbow' , 'Left_Wrist' ] ,
48+ [ 'Neck' , 'Right_Hip' ] ,
49+ [ 'Right_Hip' , 'Right_Knee' ] ,
50+ [ 'Right_Knee' , 'Right_Ankle' ] ,
51+ [ 'Neck' , 'Left_Hip' ] ,
52+ [ 'Left_Hip' , 'Left_Knee' ] ,
53+ [ 'Left_Knee' , 'Left_Ankle' ] ,
54+ ]
55+
56+ // This array will get updated with all the humans detected in the image
57+ var humans = [ ] ;
58+
59+ // This connection (to be later initialized)
60+ var socket ;
61+
62+ // Wait until the page is loaded
63+ document . addEventListener ( "DOMContentLoaded" , function ( event ) {
64+ // A variable to hold the status of the connection
65+ var status = document . getElementById ( 'status' ) ;
66+
67+ // Create a connection with Runway
68+ // *You should update this address to match the URL provided by the app
69+ socket = io . connect ( 'http://127.0.0.1:33200/query' ) ;
70+
71+ // When a connection is established
72+ socket . on ( 'connect' , function ( ) {
73+ status . innerHTML = 'Connected' ;
74+ setInterval ( sendImgToRunway , 500 , capture ) ;
75+ } ) ;
76+
77+ // When there is a data event, update the humans array
78+ socket . on ( 'update_response' , function ( data ) {
79+ humans = data . results . humans ;
80+ } ) ;
81+ } ) ;
82+
83+ // p5 setup function
84+ function setup ( ) {
85+ // Create a canvas
86+ createCanvas ( w , h ) ;
87+ // Create a video element.
88+ // Although we are getting the images from Runway, this is just to show the video behind
89+ capture = createCapture ( VIDEO ) ;
90+ capture . size ( w , h ) ;
91+ // Set some style and colors
92+ strokeWeight ( 2 ) ;
93+ colors = [ color ( '#00ff00' ) , color ( '#ffff00' ) , color ( '#ff0000' ) , color ( '#00ffff' ) , color ( '#ffffff' ) , color ( '#f4f' ) , color ( '#00ff' ) , color ( '#ffaf00' ) , color ( '#aff' ) , color ( '#aaf' ) , color ( '#33a' ) , color ( '#55f' ) , color ( '#771' ) , color ( '#15f' ) , color ( '#ff0000' ) , color ( '#00ff00' ) , color ( '#ffff00' ) , color ( '#ff0000' ) ] ;
94+
95+ }
96+
97+ function sendImgToRunway ( img ) {
98+ if ( img ) {
99+ // update camera pixels
100+ img . loadPixels ( ) ;
101+ // send data
102+ socket . emit ( 'update_request' , {
103+ data : img . canvas . toDataURL ( 'image/jpeg' ) ,
104+ model : "mobilenet_thin"
105+ } ) ;
106+ } else {
107+ console . warn ( "invalid pixels, skipping request to Runway" ) ;
108+ }
109+ }
110+
111+ // p5 draw function
112+ function draw ( ) {
113+ // Every frame, draw the current video frame
114+ image ( capture , 0 , 0 , w , h ) ;
115+ // If there are humans detected, draw them in top of video frames
116+ if ( humans . length > 0 ) {
117+ humans . forEach ( human => drawHuman ( human ) ) ;
118+ }
119+ }
18120
121+ // A function that connects joints based on data coming from OpenPose
122+ function drawHuman ( human ) {
123+ bodyConnections . forEach ( ( connection , i ) => {
124+ let start = null ;
125+ let endA = null ;
126+ let endB = null ;
127+ human . forEach ( bodyPart => {
128+ const name = bodyPart [ 0 ] ;
129+ if ( name === connection [ 0 ] ) {
130+ start = bodyPart ;
131+ } else if ( name === connection [ 1 ] ) {
132+ endA = bodyPart ;
133+ } else if ( connection [ 2 ] && name === connection [ 2 ] ) {
134+ endB = bodyPart ;
135+ }
136+ } ) ;
137+ stroke ( colors [ i ] ) ;
138+ if ( start && endA && ! endB ) {
139+ line ( start [ 1 ] * w , start [ 2 ] * h , endA [ 1 ] * w , endA [ 2 ] * h ) ;
140+ } else if ( start && endA && endB ) {
141+ line ( start [ 1 ] * w , start [ 2 ] * h , ( endA [ 1 ] + endB [ 1 ] ) / 2 * w , ( endB [ 2 ] + endB [ 2 ] ) / 2 * h ) ;
142+ }
143+ } ) ;
144+ }
0 commit comments