Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to store data in MySQL db? #245

Closed
gurtner-it opened this issue Nov 7, 2021 · 8 comments
Closed

How to store data in MySQL db? #245

gurtner-it opened this issue Nov 7, 2021 · 8 comments

Comments

@gurtner-it
Copy link

gurtner-it commented Nov 7, 2021

Hi,
I just wonder how you would have to do this?

Any one already did that?

So far I managed to store the result from the calibration as json in a table:



var past50 = webgazer.getStoredPoints(); // retrieve the stored points

// The data looks like this

[[829.0460192196398,829.0841480125482,821.5858308217357,822.6017446941858,821.18999527341,824.1292974494039,831.6154633179035,830.4035159516427,840.3226424103923,848.4371447759482,862.0159477908937,879.7087855561188,902.1283752023533,912.614633116113,933.2119358759655,946.002110166998,950.1148044685013,957.9294047882618,882.3399980767003,878.8880138181403,886.4047057361611,894.6499106398966,902.8403363500439,907.4416125387759,891.4690591320496,901.6762598449178,889.8286346099424,906.036763043852,907.8445010510384,921.5974591115738,905.0700249000388,917.4333483289645,892.1457408276463,906.4976500277846,888.4055590749513,903.4429595236643,902.9902355207382,914.2041324767447,924.6196389503164,916.5050951212232,918.0137122779176,906.9566607961306,904.3240204349245,892.9693442742789,884.4456104558694,875.8909782427662,867.0221932657232,868.0521955320717,849.1806986993706,851.5048756768731],[454.4838061598537,452.07091203844163,458.01961955560125,462.85032399521157,474.7182500299998,480.4409701263402,483.49421632943705,483.5635348395362,482.6606272312582,491.57657425866455,505.09918395104455,531.7094964097319,543.354903238816,544.1299155080272,535.993028991662,523.8126609632172,502.8289610274609,511.5551962273284,512.7158285042863,514.006485201347,493.29487252875106,488.45054715936544,457.59295836813385,472.90256514638486,466.23562892552263,464.4053517525057,471.2742038428506,451.69962626268943,450.9185027076684,426.99157802624427,445.8512026132687,440.80776688234937,455.6864922998949,473.12235255453993,468.461015994367,466.8140389778065,478.8267859410978,470.1659368691937,498.0402215493374,481.775767162119,484.7126219165725,463.62622910992,448.26529982855993,442.99822098175446,444.709195513433,461.53642826215673,465.9900323406249,475.02816685638294,464.46087558352656,454.7502578423936]]

My problem is, that I want to restore a calibration from the DB if a users deletes the local storage...

So how can I now import this data again?

And is it correct, that by default only the last 50 predictions are stored?

Would it even be possible to store all the data in a db? Or would it be too much? (Talking about data from real usage, not calibration)

Thanks for the help

PS Love your webgazer, i'm trying to use in in a visual training for people after a stroke!

@jeffhuang
Copy link
Contributor

Since you have the data on the client side with JavaScript, you can send it to the server via the regular methods and store it that way. For example, with websockets or AJAX or even simple HTTP GET requests.

Good luck

@gurtner-it
Copy link
Author

Hey Jeff,
thanks for you answer!
And if I want to import it again into an empty local forage? Is there no script for such thing already existing?
Is the above data, all the model needs?

@gurtner-it
Copy link
Author

Update: I managed to store the calibration data in Mysql as LONGBLOG type (it is a lot of data).

Now, If localforage is empty, I try to import the calibration stored in the db:

$.ajax({
       url: "inc/run.php",
       data: {
           typ: "get_eyetracking_calibration",
       },
       type: "GET",
       context: document.body,
       success: function(data, textStatus, jqXHR) {

           data = $.parseJSON(data);

           var finalData = data['mydata'];

           localforage.setItem('webgazerGlobalData', finalData).then(function (value) {
               // Do other things once the value has been saved.
               console.log('ok');
           }).catch(function(err) {
               // This code runs if there were any errors
               console.log(err);
           });

           console.log(data);
       },
       error: function(jqXHR, textStatus, errorThrown) {
           //if fails
           console.log('Error: ' + jqXHR.responseText);
           alert('Error (save_train_sound)');
       }
   });

This script works, so if I check the localforage database in the browser dev tools, it looks exactly the same as before, but the eyetracking does not work anymore...

This is how localforage looks like after I run my script...
Bildschirmfoto 2021-11-08 um 15 52 51

Any ideas?

@jeffhuang
Copy link
Contributor

So getStoredPoints() gets the 50 recent prediction accuracies, rather than what's used in the model. So those 50 points are not stored in localForage.

I would suggest taking a look at the localForage data after calibration, and storing that in your MySQL, then loading that instead of the getStoredPoints() data.

@gurtner-it
Copy link
Author

gurtner-it commented Nov 8, 2021

Hey Jeff, yup I'm doing that with the code above: get_eyetracking_calibration

To store the data I run:

localforage.getItem('webgazerGlobalData').then(function(value) {

    //create data in the form of “simpleheat” input
    $('#calibData').val(JSON.stringify(value));

}).catch(function(err) {
    // This code runs if there were any errors
    console.log(err);
});

After this I send the form and store it in the database. This part works ;)

Still the problem is that I get the error above about the missing "ImageData"...

Uncaught (in promise) DOMException: Failed to construct 'ImageData': The input data has zero elements.
    at ridgeReg_reg.RidgeReg.util_regression.setData (http://localhost/sakkadentrainer/node_modules/webgazer/dist/webgazer.js:138027:31)
    at loadGlobalData (http://localhost/sakkadentrainer/node_modules/webgazer/dist/webgazer.js:138923:15)

So it's a bit tricky to store the localforage db and restore it from mysql... I will look for some help from a fiverr javascript developer... Keep you posted

@gurtner-it
Copy link
Author

@jeffhuang Hurrayy :)

Finally it works!

This gave me the hint I needed:
#106 (comment)

Now I have this function:


function addBestCalibrationFromMySQL() {

    webgazer.clearData();

    $.ajax({
        url: "inc/run.php",
        data: {
            typ: "getBestCalibrationData",
        },
        type: "GET",
        context: document.body,
        success: function(data, textStatus, jqXHR) {

            if(data == "false") {
                return;
            }

            loadData = $.parseJSON(data);
            // add data
            var finalData = loadData['myData'];
            webgazer.setDataFromLF(finalData);

            // add settings
            var settings = loadData['mySettings'];
            localforage.setItem("webgazerGlobalSettings", settings);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            //if fails
            console.log('Error: ' + jqXHR.responseText);
            alert('Error (save_train_sound)');
        }
    });
}

PHP Looks like that:


public function getBestCalibrationData() {
       $sql = "SELECT cal_data, cal_globalSettings FROM ".$this->db->mainDBName.".tbl_eyetracking_calibrations WHERE cal_user = ? and cal_appType = ? ORDER BY cal_precision_measurement DESC LIMIT 1";
       $result = $this->db->fetch_all($sql, array($this->usr->ID, $this->App->appType));
       if(!$result) {
           return "false";
       }

       if(is_array($result) && count($result) == 0) {
           return "false";
       }

       $data = $result['cal_data'];
       $data = json_decode($data);

       $settings = $result['cal_globalSettings'];
       $settings = json_decode($settings);

       
       $data = '{"myData":'.$data.',"mySettings":'.$settings.'}';

       return $data;
   }

And finally I added this to webgazer:

/**
 * Set data from localforage and from regs
 */
src_webgazer.setDataFromLF = async function(loadedData) {

    // Load data into regression model(s)
  for (var reg in regs) {
    regs[reg].setData(loadData);
  }
}

And this:

if(data[i].eyes.left.patch.data.length > 0) {
      // Duplicate ImageData object
      data[i].eyes.left.patch = new ImageData(leftData, data[i].eyes.left.width, data[i].eyes.left.height);
      data[i].eyes.right.patch = new ImageData(rightData, data[i].eyes.right.width, data[i].eyes.right.height);
  } else {
      // if import from mysql data
      data[i].eyes.left.patch = new ImageData(new Uint8ClampedArray(Object.values(data[i].eyes.left.patch.data)), data[i].eyes.left.width, data[i].eyes.left.height);
      data[i].eyes.right.patch = new ImageData(new Uint8ClampedArray(Object.values(data[i].eyes.right.patch.data)), data[i].eyes.right.width, data[i].eyes.right.height);
  }

So if anyone else is trying to do it...

@gurtner-it
Copy link
Author

@jeffhuang Still a question: My idea is to restore a lost calibration file, if the browser is reset or the users changes the computer.
Does it make sense to restore the calibration stored in the mysql db (from PC A), and restore it on PC B (with another Webcam)? Or would you have to do a new calibration?

Thanks for your help!

@gurtner-it gurtner-it reopened this Nov 12, 2021
@jeffhuang
Copy link
Contributor

I would suggest a new calibration. Any change in environment should be recalibrated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants