From feebc41d3372b41b1c48588e1a1e16fb3d2d1db8 Mon Sep 17 00:00:00 2001
From: Jake Read <jake.read@cba.mit.edu>
Date: Sat, 16 Nov 2019 16:37:43 -0500
Subject: [PATCH] ...

---
 hunks/adhoc/correlate.js                  | 102 ++++++++++++++++------
 save/contexts/cuttlefish/correlation.json |  98 +++++++++++++++++++++
 2 files changed, 175 insertions(+), 25 deletions(-)
 create mode 100644 save/contexts/cuttlefish/correlation.json

diff --git a/hunks/adhoc/correlate.js b/hunks/adhoc/correlate.js
index 03d1871..e5a734a 100644
--- a/hunks/adhoc/correlate.js
+++ b/hunks/adhoc/correlate.js
@@ -11,13 +11,28 @@ import {
   State
 } from '../hunks.js'
 
+let computedResult = null
 let running = false
 
-let correlate = (a, b) => {
+let correlate = (a, b, x, y) => {
   // score a against b,
+  let sumA = 0
+  let sumB = 0
+  let sumDot = 0
+  let bi = 0
+  for(let i = 0; i < a.data.length; i ++){
+    sumA += a.data[i]
+
+    bi = y * b.width + x
+    bi += Math.floor(i / a.width) * b.width + i
+    sumB += b.data[bi]
+
+    sumDot += a.data[i] * b.data[bi]
+  }
+  return (sumDot / Math.sqrt(sumA*sumA + sumB*sumB))
   // a, b are str8 up matricies
-  console.log(b.width)
-  // ok, now we can do the maths on a and b, thx 
+  //console.log(b.width)
+  // ok, now we can do the maths on a and b, thx
 }
 
 let delay = (time) => {
@@ -28,24 +43,52 @@ let delay = (time) => {
   })
 }
 
-async function run(ca, cb){
+async function run(a, b){
   running = true
-  let a = ca.getImageData(0,0, ca.height, ca.width)
-  for(let x = 0; x < cb.width - a.width; x ++){
-    for(let y = 0; y < cb.height - a.height; y ++){
-      // make some b,
-      let b = cb.getImageData(x, y, a.width, a.height)
-      correlate(a, b)
-      await delay(100)
+  // a is img to search for, b is img to search within. both are ImageData types
+  let resX = b.width - a.width
+  let resY = b.height - a.height
+  let numruns = resX * resY
+  console.log('numruns', numruns)
+  let result = []
+  // so, let's see about this ... we
+  for(let x = 0; x < b.width - a.width; x ++){
+    for(let y = 0; y < b.height - a.height; y ++){
+      // best to use b in-place,
+      let corr = correlate(a, b, x, y)
+      // four channels ...
+      result.push(corr, corr, corr, corr)
     }
+    // not blocking ...
+    await delay(0)
+  }
+  console.log('complete')
+  // make image from the result,
+  let max = -Infinity
+  let min = Infinity
+  for(let i = 0; i < result.length; i ++){
+    if(result[i] > max) max = result[i];
+    if(result[i] < min) min = result[i];
   }
+  for(let i = 0; i < result.length; i ++){
+    result[i] = (result[i] - min) * (255 / (max-min))
+  }
+  console.log('max, min', max, min)
+  console.log('result', result)
+  let u8 = Uint8ClampedArray.from(result)
+  console.log('u8', u8)
+  console.log('resX, resY', resX, resY)
+  let imgRes = new ImageData(u8, resX, resY)
+  console.log('imgRes', imgRes)
+  running = false
+  computedResult = imgRes
 }
 
 export default function Correlate(){
   Hunkify(this)
 
   let imgIn = this.input('ImageData', 'frame')
-  let imgOut = this.output('ImageData', 'correlation')
+  let resOut = this.output('ImageData', 'correlation')
 
   let canvasA = $('<canvas>').get(0)
   let ctxA = canvasA.getContext('2d')
@@ -66,20 +109,29 @@ export default function Correlate(){
   }
 
   this.loop = () => {
-    if(imgIn.io() && !imgOut.io() && !running){
+    if(imgIn.io() && !running){
+      // ok, the image data:
       let img = imgIn.get()
-      // put that into a context, where it's easy to snip from:
-      canvasB.width = img.width
-      canvasB.height = img.height
-      ctxB.width = img.width
-      ctxB.height = img.height
-      ctxB.putImageData(img, 0, 0, 0, 0, img.width, img.height)
-      // we want to set up a loop for this ... first we need some A: a slice of our img,
-      // since we're just checking against ourselves for now... let's take the middle
-      // to clip, I'll use this canvas context ...
-      // this is kind of surprising positioning inputs, but OK
-      ctxA.putImageData(img, -img.width / 2, -img.height / 2, img.width / 2, img.height / 2, ctxA.height, ctxA.width)
-      run(ctxA, ctxB)
+      // to scale this thing, we draw it into a canvas (virtual ... not attached to page)
+      let vc = $('<canvas>').get(0)
+      let scale = 256 / img.height
+      vc.width = img.width
+      vc.height = img.height
+      vc.getContext('2d').putImageData(img, 0, 0)
+      // we draw this into a second canvas, scaling it with the drawImage call,
+      canvasB.width = img.width * scale
+      canvasB.height = img.height * scale
+      ctxB.drawImage(vc, 0, 0, img.width * scale, img.height * scale)
+      // now we can pull the imagedata (scaled) from here,
+      let b = ctxB.getImageData(0, 0, canvasB.width, canvasB.height)
+      // and the thing we want to find, to test, just pick the middle:
+      let a = ctxB.getImageData(b.width / 2, b.height / 2, 50, 50)
+      // and write that out, to debug ...
+      ctxA.putImageData(a, 0, 0)
+      run(a, b)
+    }
+    if(!resOut.io() && computedResult !== null){
+      resOut.put(computedResult)
     }
   }
 }
diff --git a/save/contexts/cuttlefish/correlation.json b/save/contexts/cuttlefish/correlation.json
new file mode 100644
index 0000000..e68e608
--- /dev/null
+++ b/save/contexts/cuttlefish/correlation.json
@@ -0,0 +1,98 @@
+{
+  "interpreterName": "cuttlefish",
+  "interpreterVersion": "v0.1",
+  "hunks": [
+    {
+      "type": "manager",
+      "name": "nrol",
+      "inputs": [
+        {
+          "name": "msgs",
+          "type": "byteArray"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "msgs",
+          "type": "byteArray",
+          "connections": [
+            {
+              "inHunkIndex": "1",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "view",
+      "name": "tlview",
+      "inputs": [
+        {
+          "name": "msgs",
+          "type": "byteArray"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "msgs",
+          "type": "byteArray",
+          "connections": [
+            {
+              "inHunkIndex": "0",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "adhoc/webcam",
+      "name": "adhoc/webcam_2",
+      "outputs": [
+        {
+          "name": "frame",
+          "type": "ImageData",
+          "connections": [
+            {
+              "inHunkIndex": "4",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "image/displayimagedata",
+      "name": "image/displayimagedata_4",
+      "inputs": [
+        {
+          "name": "image",
+          "type": "ImageData"
+        }
+      ]
+    },
+    {
+      "type": "adhoc/correlate",
+      "name": "adhoc/correlate_5",
+      "inputs": [
+        {
+          "name": "frame",
+          "type": "ImageData"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "correlation",
+          "type": "ImageData",
+          "connections": [
+            {
+              "inHunkIndex": "3",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
-- 
GitLab