How can I get continuous landmarks from video for Mediapipe Handpose - mediapipe

I am new to Javascript. I am trying to get output from MediaPipe Handpose. When I give an image into this model, I easily get an output. But when I try for a video, it doesn't work.
This is the head
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/#tensorflow/tfjs-core"></script>
<script src="https://cdn.jsdelivr.net/npm/#tensorflow/tfjs-converter"></script>
<script src="https://cdn.jsdelivr.net/npm/#tensorflow/tfjs-backend-webgl"></script>
<script src="https://cdn.jsdelivr.net/npm/#tensorflow-models/handpose"></script>
My video ID details
Source<br>
<video id="video" src="o_new.mp4" width="640" height="480" controls>
</video>
<canvas id="canvas" style="overflow:auto"></canvas>
Inside the script
<script>
const video = document.getElementById("video");
async function main() {
// Load the MediaPipe handpose model.
const model = await handpose.load(maxContinuousChecks = 60);
console.log('Model Loaded')
// Pass in a video stream (or an image, canvas, or 3D tensor) to obtain a
// hand prediction from the MediaPipe graph.
const predictions = await model.estimateHands(video);
console.log('Estimated Hand')
console.log(predictions)
if (predictions.length > 0) {
/*
`predictions` is an array of objects describing each detected hand, for example:
[
{
handInViewConfidence: 1, // The probability of a hand being present.
boundingBox: { // The bounding box surrounding the hand.
topLeft: [162.91, -17.42],
bottomRight: [548.56, 368.23],
},
landmarks: [ // The 3D coordinates of each hand landmark.
[472.52, 298.59, 0.00],
[412.80, 315.64, -6.18],
...
],
annotations: { // Semantic groupings of the `landmarks` coordinates.
thumb: [
[412.80, 315.64, -6.18]
[350.02, 298.38, -7.14],
...
],
...
}
}
]
*/
for (let i = 0; i < predictions.length; i++) {
const keypoints = predictions[i].landmarks;
console.log('keypoints Loop')
// Log hand keypoints.
for (let i = 0; i < keypoints.length; i++) {
const [x, y, z] = keypoints[i];
console.log(`Keypoint ${i}: [${x}, ${y}, ${z}]`);
}
}
}
}
main();
</script>
How can I get continuous landmarks in an output object for video?
Here is the error.

I am updating my previous answer. You don't want to use set interval like I put in my former solution. When I used it for more than a few minutes it filled up my gpu memory and crashed webgl. I was able to comb through the developers demo.js file, and found a solution. In your js file replace your main() function with the below code:
const state = {
backend: 'webgl'
};
let model;
async function main() {
await tf.setBackend(state.backend);
model = await handpose.load();
landmarksRealTime(video);
}
const landmarksRealTime = async (video) => {
async function frameLandmarks() {
const predictions = await model.estimateHands(video);
if (predictions.length > 0) {
const result = predictions[0].landmarks;
console.log(result, predictions[0].annotations);
}
rafID = requestAnimationFrame(frameLandmarks);
};
frameLandmarks();
};
video.addEventListener("loadeddata", main);
This console logs continuous landmarks. It doesn't log anything if a hand is not detected. Also, it looks like the developers updated the recommended script tags a few days ago, so I would recommend updating your index.html file. They should be:
<!-- Require the peer dependencies of handpose. -->
<script src="https://unpkg.com/#tensorflow/tfjs-core#2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/#tensorflow/tfjs-converter#2.1.0/dist/tf-converter.js"></script>
<!-- You must explicitly require a TF.js backend if you're not using the tfs union bundle. -->
<script src="https://unpkg.com/#tensorflow/tfjs-backend-webgl#2.1.0/dist/tf-backend-webgl.js"></script>
<!-- Alternatively you can use the WASM backend: <script src="https://unpkg.com/#tensorflow/tfjs-backend-wasm#2.1.0/dist/tf-backend-wasm.js"></script> -->
<script src="https://unpkg.com/#tensorflow-models/handpose#0.0.6/dist/handpose.js"></script></head>

Related

Unable to use Lazy load + Dynamic image manipulation Cloudinary

I am unable to use the feature Cloudinary Lazyload + Dynamic image manipulation both at the same time.
Is there any trick to use both the function at the same time?
I am using an HTML website.
My code is
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://unpkg.com/cloudinary-core#latest/cloudinary-core-shrinkwrap.js"></script>
<script type="text/javascript">
var cl = cloudinary.Cloudinary.new({cloud_name: "syg"});
// replace 'demo' with your cloud name in the line above
cl.responsive();
</script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const imageObserver = new IntersectionObserver((entries, imgObserver) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const lazyImage = entry.target
console.log("lazy loading ", lazyImage)
lazyImage.src = lazyImage.dataset.src
}
})
});
const arr = document.querySelectorAll('img.lzy_img')
arr.forEach((v) => {
imageObserver.observe(v);
})
})
</script>
<img class="cld-responsive lzy_img" data-src="https://res.cloudinary.com/syg/image/upload/w_auto,c_scale/sample.jpg" />
The responsive script will apply the relevant width value and replace w_auto in the URL based on the container size.
Since your code does not limit the <img> container, it applies the max width size of the screen.
For testing purposes, you can wrap your <img> element with <div style="width:50%;"></div> and you will see that the image URL adjusts the width transformation accordingly:
<div style="width:50%;">
<img class="cld-responsive lzy_img" data-src="https://res.cloudinary.com/syg/image/upload/w_auto,c_scale/v346346/sample.jpg"/>
</div>
In addition, you can take a look at the following broader implementation of LQIP+Lazy Loading+Responsive with Cloudinary for reference and ideas on how to implement these features within your site's pages.

wijmo 5 scripts concatenation fails, anyone else found the same issue.?

Did anyone ever tried minified wijmo 5 angular js files?
I fails after concatenation, I tried putting all js files inside IIFE still it fails to execute.
Please let me know if any one has ever tried the same.
FYI: I do not have unminified files as wijmo provides it after buying licences.
Link to wijmo : http://wijmo.com/5/docs/static/references.html
You can also use CDN link for the same. Please refer to 'Deploying Wijmo from CDN' at the same link mentioned above. Here is the code snippet for using Wijmo 5 FlexGrid with AngularJS.
<html>
<head>
<link href="http://cdn.wijmo.com/5.20163.254/styles/wijmo.min.css" rel="stylesheet"/>
<script src="http://cdn.wijmo.com/5.20163.254/controls/wijmo.min.js"></script>
<script src="http://cdn.wijmo.com/5.20163.254/controls/wijmo.input.min.js"></script>
<script src="http://cdn.wijmo.com/5.20163.254/controls/wijmo.grid.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://cdn.wijmo.com/5.20163.254/interop/angular/wijmo.angular.min.js"></script>
<script>
var app = angular.module('app', ['wj']);
// app controller provides data
app.controller('appCtrl', function($scope){
// generate some random data
var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','),
data = [];
for (var i = 0; i < 50; i++) {
data.push({
id: i,
country: countries[i % countries.length],
date: new Date(2014, i % 12, i % 28),
amount: Math.random() * 10000,
active: i % 4 == 0
});
}
// add data array to scope
$scope.data = data;
});
</script>
</head>
<body>
<div ng-app="app" ng-controller="appCtrl" >
<wj-flex-grid items-source="data" style="height:200px;">
</wj-flex-grid>
</div>
</body>
</html>
Thanks,
Manish Kumar Gupta

Passing image from Processing to Javascript and then saving said image back to server using AJAX / PHP?

I'm working on a project where I want to load a processing sketch into a canvas, have some things happen to the image when a user mouses over (got that part), and then when they leave the canvas save the image back to the server.
I've looked at these other questions, and can't quite figure this out:
HTML5 CANVAS: How to save and reopen image from server
That's not really working for me.
Uploading 'canvas' image data to the server
I don't exactly understand where to put everything in this.
http://j-query.blogspot.in/2011/02/save-base64-encoded-canvas-image-to-png.html
From outside of Stackoverflow, but I got there from here.
Version 1
This isn't working all the way, I feel like I'm close, the processing sketch is working, and it's kicking out an image, I just can't grab it with JS, and then I don't know what to do with it to get it back to the server.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Processing Page</title>
<script type="text/javascript" src="../../processingjs/processing.js"></script>
<script type="text/javascript"> //This is for communicating between Processing and Javascript
function showXYCoordinates(x, y) {
document.getElementById('xcoord').value = x;
document.getElementById('ycoord').value = y;
}
var bound = false;
function bindJavascript(instance) {
var pjs = Processing.getInstanceById(instance);
if(pjs != null) {
pjs.bindJavascript(this);
bound = true;
}
if(!bound) {
setTimeout(bindJavascript, 250);
}
}
bindJavascript('B_103');
var processingOutput = Processing.getInstanceByID('B_103');
var img = processingOutput.mouseOut();
</script>
</head>
<body>
<canvas id="B_103" data-processing-sources="B_103/B_103.pde" width="300px" height="300px"></canvas>
<?php
// requires php5
echo $_GET['img'];
define('UPLOAD_DIR', 'B_103/data/');
$img = $_POST['img'];
// $img = str_replace('data:image/png;base64,', '', $img);
// $img = str_replace(' ', '+', $img);
// $data = base64_decode($img);
$file = UPLOAD_DIR . 'image.jpg';
$success = file_put_contents($file, $data);
print $success ? $file : 'Not able to save the file.';
?></body>
</html>
And then there is this:
Version 2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Processing Page</title>
<script type="text/javascript" src="../../processingjs/processing.js"></script>
<script type="text/javascript"> //This is for communicating between Processing and Javascript
function showXYCoordinates(x, y) {
document.getElementById('xcoord').value = x;
document.getElementById('ycoord').value = y;
}
var bound = false;
function bindJavascript(instance) {
var pjs = Processing.getInstanceById(instance);
if(pjs != null) {
pjs.bindJavascript(this);
bound = true;
}
if(!bound) {
setTimeout(bindJavascript, 250);
}
}
bindJavascript('B_103');
//var processingOutput = Processing.getInstanceByID('B_103');
//var img = processingOutput.mouseOut();
function save(){ //saves the canvas into a string as a base64 png image. jsvalue is sent to the server by an html form
var b_canvas = document.getElementById("B_103");
var b_context = b_canvas.getContext("2d");
var img = b_canvas.file_put_contents('backpicture.png',base64_decode(substr($str,22)));
}
</script>
</head>
<body>
<canvas id="B_103" data-processing-sources="B_103/B_103.pde" width="300px" height="300px"></canvas>
<?php
echo $_GET['img'];
$str=$_POST['img'];
$file=fopen("B_103/data/image.txt","w");
if(isset($_POST['submit']))
fwrite($file,$str);
fclose($file)
?>
</body>
</html>
So this one is saving a file backwards, but the file has nothing in it. I can deal with Base64 (with the answer to one question about using it in processing) but this file doesn't have it in there.
Any thoughts appreciated, thank you!
Way too much code there =)
Canvas can give you a base64 encoded image with a single function call, so just use canvas.toDataURL("image/png") or canvas.toDataURL("image/jpg") to get that string, and then save it to your server with a normal POST operation.
When it's required again, ask your server for the data using whatever format your GET request takes, and then unpack it as an Image, then draw that image onto your sketch:
var dataURI = /* get the string from your server */
var img = new Image();
img.src = dataURI;
sketch.image(img,0,0);
And we should be good to go.
Thanks Mike, it's working. Here's what I did.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Processing Page</title>
<script type="text/javascript" src="../../processingjs/processing.js"></script>
<script type="text/javascript"> //This is for communicating between Processing and Javascript
function showXYCoordinates(x, y) {
document.getElementById('xcoord').value = x;
document.getElementById('ycoord').value = y;
}
var bound = false;
function bindJavascript(instance) {
var pjs = Processing.getInstanceById(instance);
if(pjs != null) {
pjs.bindJavascript(this);
bound = true;
}
if(!bound) {
setTimeout(bindJavascript, 250);
}
}
bindJavascript('B104');
//var processingOutput = Processing.getInstanceByID('B_104');
//var img = processingOutput.mouseOut();
function postAjax(){
var canvasB104 = document.getElementById('B104');
var canvasData = canvasB104.toDataURL('image/png');
var ajax = new XMLHttpRequest();
ajax.open("POST",'testSave.php',false);
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(canvasData);
}
</script>
</head>
<body>
<canvas id="B104" data-processing-sources="B_104/B_104.pde" width="300px" height="300px" onmouseout="postAjax()"></canvas>
Plus, I have a PHP file, that I got from this tutorial: http://permadi.com/blog/2010/10/html5-saving-canvas-image-data-using-php-and-ajax/
One of the things I goofed up, which is probably a rookie thing to do, was I had the variable canvasData in quotes, which I see now is incorrect of course (because I wanted the string not the actual word 'canvasData')
In case anyone wants to see it working: http://graphic-interaction.com/mfa-thesis/testing-group02/pro-ex-07.php

trouble with loading javascript in visual studio 2012

Hey How would I load this code
http://jsfiddle.net/xw89p/
in a simple web form in visual studio.
For example can I insert this into the
var rotation = function (){
$("#image").rotate({
angle:0,
animateTo:360,
callback:enter code here rotation,
easing: function (x,t,b,c,d){ // t: current time, b: begInnIng value,
c: change In value, d: duration
return c*(t/d)+b;
}
});
}
rotation();​
Put that code in a JavaScript file (.js), then in your web form file, add a tag that references the .js file:
<script language="JavaScript" src="scripts.js"></script>
A second possibility is to put that code inside the script tag in your web form file:
<script>
var rotation = function (){
$("#image").rotate({
angle:0,
animateTo:360,
callback: rotation,
easing: function (x,t,b,c,d){ // t: current time, b: begInnIng value, c: change In value, d: duration
return c*(t/d)+b;
}
});
}
$(document).ready(function(){
rotation();​
});
</script>
Of course, you'll need to make sure to first reference jQuery and whatever other javascript libraries you need BEFORE inclusing your js file, or BEFORE the inline script tag.
Hope this helps
EDIT: Here's a working verison on my side:
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<img src="https://www.google.com/images/srpr/logo3w.png" id="image">​
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
</script>
<script type="text/javascript" src="http://jqueryrotate.googlecode.com/svn/trunk/jQueryRotate.js"></script>
<script type="text/javascript">
function rotation() {
$("#image").rotate({
angle: 0,
animateTo: 360,
callback: rotation,
easing: function(x, t, b, c, d) { // t: current time, b: begInnIng value, c: change In value, d: duration
return c * (t / d) + b;
}
});
};
$(document).ready(function () {
rotation();
})
</script>
</html>

How to show next/previous links in Google Custom Search Engine paging links

The Google Custom Search integration only includes numbered page links and I cannot find a way to include Next/Previous links like on a normal Google search. CSE used to include these links with their previous iframe integration method.
I stepped through the javascript and found the undocumented properties I was looking for.
<div id="cse" style="width: 100%;">Loading</div>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load('search', '1', {language : 'en'});
google.setOnLoadCallback(function() {
var customSearchControl = new google.search.CustomSearchControl('GOOGLEIDGOESHERE');
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
customSearchControl.setSearchCompleteCallback(null,
function() { searchCompleteCallback(customSearchControl) });
customSearchControl.draw('cse');
}, true);
function searchCompleteCallback(customSearchControl) {
var currentPageIndex = customSearchControl.e[0].g.cursor.currentPageIndex;
if (currentPageIndex < customSearchControl.e[0].g.cursor.pages.length - 1) {
$('#cse .gsc-cursor').append('<div class="gsc-cursor-page">Next</div>').click(function() {
customSearchControl.e[0].g.gotoPage(currentPageIndex + 1);
});
}
if (currentPageIndex > 0) {
$($('#cse .gsc-cursor').prepend('<div class="gsc-cursor-page">Previous</div>').children()[0]).click(function() {
customSearchControl.e[0].g.gotoPage(currentPageIndex - 1);
});
}
window.scrollTo(0, 0);
}
</script>
<link rel="stylesheet" href="http://www.google.com/cse/style/look/default.css" type="text/css" />
I've been using this to find the current page:
ctrl.setSearchCompleteCallback(null, function(gControl, gResults)
{
currentpage = 1+gResults.cursor.currentPageIndex;
// or, here is an alternate way
currentpage = $('.gsc-cursor-current-page').text();
});
And now it's customSearchControl.k[0].g.cursor ... (as of this weekend, it seems)
Next time it stops working just go to script debugging in IE, add customSearchControl as a watch, open the properties (+), under the Type column look for Object, (Array) and make sure there is a (+) there as well (i.e. contains elements), open[0], and look for Type Object, again with child elements. Open that and once you see "cursor" in the list, you've got it.