According to the library's readme:
ndarrays can be transposed, flipped, sheared and sliced in constant time per operation.
However I cannot find any examples for doing so. How does one apply a shear to a given ndarray?
According to the library's readme:
ndarrays can be transposed, flipped, sheared and sliced in constant time per operation.
However I cannot find any examples for doing so. How does one apply a shear to a given ndarray?
As clarified in comments, the desired shearing is a sheared mapping.
I found that the easiest to shear an ndarray is to use ndarray-warp.
See here page 5 for details about how shearing is a particular case of warping.
(most interesting things you can do with ndarrays are implemented in the scijs ecosystem of libraries, which revolve around ndarray)
var ndarray = require("ndarray")
var lena = require("lena")
var warp = require("ndarray-warp")
var zeros = require("zeros")
var luminance = require("luminance")
var input = luminance(lena) // Input is famous Lena image
var output = require("zeros")([width, height]) // Allocate buffer for output
var shearFunction = function(out, inp) { // Custom shear function
out[0] = inp[0]
out[1] = inp[1] + inp[0]*0.2
}
warp(result, input, shearFunction)
For a complete example, below I transformed Lena 3 times with ndwarp
, the bottom 2 are sheared.
See it live here (you can even change the code and play with it).
var ndarray = require("ndarray")
var ops = require("ndarray-ops")
var lena = require("lena")
var pool = require("typedarray-pool")
var warp = require("ndarray-warp")
var zeros = require("zeros")
var luminance = require("luminance")
var totalWidth = lena.shape[1]
var totalHeight = lena.shape[0]
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = totalWidth
canvas.height = totalHeight
// lena is 512x512 RGB image, let's get a 256x256 monochrome image
var input = luminance(lena.step(2,2))
var width = totalWidth/2
var height = totalHeight/2
var context = canvas.getContext("2d")
context.fillStyle = "#000"
context.fillRect(0, 0, totalWidth, totalHeight)
drawImage(context, input, 0, 0)
var result = require("zeros")([width, height])
var warpFunction = function(out, inp) {
var dx = inp[0] - 128
var dy = inp[1] - 128
var r = Math.sqrt(dx * dx + dy * dy)
var theta = Math.atan2(dy, dx)
out[0] = 0.9 * r * Math.cos(theta + 0.01 * r) + 128
out[1] = 0.7 * r * Math.sin(theta + 0.01 * r) + 128
}
warp(result, input, warpFunction)
drawImage(context, result, 256, 0)
var shearFunction1 = function(out, inp) {
out[0] = inp[0]
out[1] = inp[1] + inp[0]*0.2
}
warp(result, input, shearFunction1)
drawImage(context, result, 0, 256)
var shearFunction2 = function(out, inp) {
out[0] = inp[0] - inp[1]*0.25
out[1] = inp[1]
}
warp(result, input, shearFunction2)
drawImage(context, result, 256, 256)
function drawImage(context, array, x, y) {
var pixels = context.getImageData(x, y, width, height)
var pixelArray = ndarray(pixels.data, [array.shape[0], array.shape[1], 3], [4*width, 4, 1], 0)
if(array.dimension === 3) {
ops.assign(
pixelArray.hi(array.shape[0], array.shape[1], array.shape[2]), array)
} else {
ops.assign(pixelArray.pick(-1,-1,0), array)
ops.assign(pixelArray.pick(-1,-1,1), array)
ops.assign(pixelArray.pick(-1,-1,2), array)
}
context.putImageData(pixels, x, y)
}
Enjoy.
Hope this can help you:
( To "shear" a ndarray, you can use those methods: 'hi' and 'lo' )
var ndarray = require('ndarray');
var mat = ndarray(new Float64Array([1, 2, 3, 4, 5, 6, 7, 8, 9]), [3, 3]);
console.log(mat);
// 1 2 3
// 4 5 6
// 7 8 9
console.log(mat.get(1, 1)); // 5
console.log(mat.get(5, 0)); // 7
console.log(mat.get(34, 43)); // undefined
mat.set(1, 1, 100);
console.log(mat);
// 1 2 3
// 4 100 6
// 7 8 9
console.log(mat.index(1, 1)); // 4
console.log(mat.size); // 9
console.log(mat.dimension); // 2
var matLo = mat.lo(1, 1);
console.log(matLo);
// 100 6
// 8 9
console.log(matLo.get(0, 0)); // 100
console.log(matLo.get(0, 1)); // 6
console.log(matLo.get(1, 0)); // 8
console.log(matLo.get(1, 1)); // 9
var matHi = mat.hi(1, 1);
console.log(matHi);
// 1 2
// 4 100
console.log(matHi.get(0, 0)); // 1
console.log(matHi.get(0, 1)); // 2
console.log(matHi.get(1, 0)); // 4
console.log(matHi.get(1, 1)); // 100
var matStap = mat.step(-1);
console.log(matStap);
// 7 8 9
// 4 100 6
// 1 2 3
console.log(matStap.get(0, 0)); // 7
console.log(matStap.get(0, 1)); // 8
console.log(matStap.get(0, 2)); // 9
console.log(matStap.get(1, 0)); // 4
console.log(matStap.get(1, 1)); // 100
console.log(matStap.get(1, 2)); // 6
console.log(matStap.get(2, 0)); // 1
console.log(matStap.get(2, 1)); // 2
console.log(matStap.get(2, 2)); // 3
var matTranspose = mat.transpose(1,0);
console.log(matTranspose);
// 1 4 7
// 2 100 8
// 3 6 9
console.log(matTranspose.get(0, 0)); // 1
console.log(matTranspose.get(0, 1)); // 4
console.log(matTranspose.get(0, 2)); // 7
console.log(matTranspose.get(1, 0)); // 2
console.log(matTranspose.get(1, 1)); // 100
console.log(matTranspose.get(1, 2)); // 8
console.log(matTranspose.get(2, 0)); // 3
console.log(matTranspose.get(2, 1)); // 6
console.log(matTranspose.get(2, 2)); // 9