What to use as inputs in OpenCV calibrateCamera cameraMatrix and distCoeffs parameters? - node.js

I'm trying to get calibrateCamera working on my Node.js backend. The library is working fine, but I'm having trouble with the OpenCV functions not giving any error messages if I have faulty inputs. I'm kind of flying in the dark.
But that's beside the point. I've taken 17 images of the chessboard calibration pattern, and got the code to detect the pattern in all of the images. Everything works just fine until I call cv.calibrateCamera(), probably due to me not knowing what I should use as the required inputs for cameraMatrix and distCoeff (4th and 5th input parameters). However, I can't be 100% this is the issue because of not receiving any error messages from errors in the cv... functions.
I tried to follow the example at https://docs.opencv.org/3.1.0/dc/dbb/tutorial_py_calibration.html , but on python in the tutorial you can use None as inputs to cameraMatrix and distCoeff. I tried to use null, but that didn't work either.
Any help would be appreciated.
const size = new cv.Size(9,6);
let mat = null;
let objpt = [];
for(let i=0;i<9;i++) {
for(let j=0;j<6;j++) {
objpt.push(cv.Point(2.5*i,2.5*j,0))
}
}
let objectPoints = [];
let imagePoints =[];
for (let i=0; i < 17;i++) {
mat = cv.imread('./calib/calib'+(i+1)+'.jpg');
let smallmat = mat.resize(756,1008);
const corners = smallmat.findChessboardCorners(size);
if (corners.returnValue) {
objectPoints = objectPoints.concat(objpt);
imagePoints = imagePoints.concat(corners.corners);
}
}
// THIS IS WHERE EXECUTION JUST STOPS WITH NO ERROR MESSAGE
cv.calibrateCamera(
objectPoints,
imagePoints,
new cv.Size(756,1008),
new cv.Mat(3, 3, cv.CV_32FC1,0),
[0,0,0,0,0]
);

According to the test parameters should be passed like this:
[_objectPoints, _objectPoints],
[imagePoints, imagePoints],
imageSize,
_cameraMatrix,
distCoefficients
where
const _cameraMatrix = new cv.Mat([
[800, 0, 100],
[0, 800, 100],
[0, 0, 1]
], cv.CV_64F);
and
const distCoefficients = [0, 0.5, 1.0, 1.0];

Related

Is there a way to recognize that a declarativeContent rule was matched in a chrome extension?

I was hoping that the setIconFct is called only when the condition is met. However, x = 1 even if the tab is not on "google.com" (condition is met). How can I found out, if the condition was met programmatically? As you see, I am changing the Icon, is there a way to find out, if the icon was changed, can I read properties of the icon? This would be just one idea, to find out that the condition was met through the fact that the icon was changed, I am open to any other ideas - eventually I need to find out if the condition was met or not and then run my own code. (I was also playing with RequestContentScript but it seems not to do anything in V3).
var x = 0;
function setIconFct (color, callback) {
x = 1;
const canvas = new OffscreenCanvas(16, 16);
const context = canvas.getContext('2d');
context.clearRect(0, 0, 16, 16);
context.fillStyle = color; // Green
context.fillRect(0, 0, 16, 16);
context.font = '19px arial';
context.fillText('X', 0,12);
const imageData = context.getImageData(0, 0, 16, 16);
var action = new chrome.declarativeContent.SetIcon({imageData: imageData});
callback(action);
}
chrome.declarativeContent.onPageChanged.removeRules(undefined, () => {
setIconFct(function(setIcon) {
chrome.declarativeContent.onPageChanged.addRules([
{
conditions : [
new chrome.declarativeContent.PageStateMatcher({
hostSuffix: 'google.com',
})
],
actions : [ setIcon ]
}
]);
});
});
I tried to execute my own code in case the conditions of pageStateMatcher was met. I was not able to find out if the condition was met.

How can I load an exported Tileset (image collection) from Tiled in Phaser 3?

I want to load an image collection tileset into my phaser game. I know that with tilesets that are just one image you can just load that image into phaser, but what about an image collection? In Tiled I saw the options to export that tileset as either .tsx or .json, but I don't know if that helps in my case. The reason I need this is because I have some objects that are too big to be used as tiles. I can load them into Tiled and place them like I want to, but obviously they don't show up in my game, unless I can import that tileset into phaser. Does anyone know how to do that, or maybe you know a better option than using an image collection?
Well after some tests, and updating my Tiled version to 1.9.2, it seems there is an pretty simple way.
As long as the tileset collection is marked as "Embeded in map"
(I could have sworn, this checkbox was hidden/deactivated, when selecting "Collection of Images", in my early Tiled version)
Export the map as json
Load map and tile-images
preload() {
this.load.tilemapTiledJSON('map', 'export.tmj');
this.load.image('tile01', 'tile01.png');
this.load.image('tile02', 'tile02.png');
...
}
create Phaser TileSets, just use the filename from the json as the tilsetName (this is the "tricky" part, atleast for me)
create() {
var map = this.make.tilemap({ key: 'map' });
var img1 = map.addTilesetImage( 'tile01.png', 'tile01');
var img2 = map.addTilesetImage( 'tile02.png', 'tile02');
...
// create the layer with all tilesets
map.createLayer('Tile Layer 1', [img1, img2, ...]);
...
}
This should work, atleast with a "Collection of images", with images that have a size of 8x8 pixel (since I don't know the needed/intended Images size, I didn't want to waste time testing various images-sizes needlessly).
Here a small demo:
(due to CORS-issues the map data is inserted as jsonObject and the textures are generate and not loaded)
const mapJsonExport = {"compressionlevel":-1,"height":10,"infinite":false,"layers":[{"compression":"","data":"AQAAAAEAAAACAAAAAgAAAAEAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAIAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAACAAAAAQAAAAEAAAACAAAAAgAAAAEAAAABAAAAAgAAAAIAAAABAAAAAgAAAAIAAAACAAAAAgAAAAEAAAACAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAIAAAACAAAAAgAAAAEAAAACAAAAAgAAAAEAAAACAAAAAQAAAAEAAAACAAAAAQAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAEAAAABAAAAAgAAAAEAAAABAAAAAQAAAAEAAAACAAAAAQAAAAIAAAACAAAAAgAAAAEAAAABAAAAAgAAAAEAAAACAAAAAgAAAAIAAAACAAAAAgAAAAEAAAABAAAAAgAAAAIAAAACAAAAAgAAAAEAAAACAAAAAQAAAA==","encoding":"base64","height":10,"id":1,"name":"Tile Layer 1","opacity":1,"type":"tilelayer","visible":true,"width":10,"x":0,"y":0}],"nextlayerid":2,"nextobjectid":1,"orientation":"orthogonal","renderorder":"right-down","tiledversion":"1.9.2","tileheight":8,"tilesets":[{"columns":0,"firstgid":1,"grid":{"height":1,"orientation":"orthogonal","width":1},"margin":0,"name":"tiles","spacing":0,"tilecount":2,"tileheight":8,"tiles":[{"id":0,"image":"tile01.png","imageheight":8,"imagewidth":8},{"id":1,"image":"tile02.png","imageheight":8,"imagewidth":8}],"tilewidth":8}],"tilewidth":8,"type":"map","version":"1.9","width":10};
var config = {
width: 8 * 10,
height: 8 * 10,
zoom: 2.2,
scene: { preload, create }
};
function preload() {
// loading inline JSON due to CORS-issues with the code Snippets
this.load.tilemapTiledJSON('map', mapJsonExport);
// generating texture instead of loading them due to CORS-issues with the code Snippets
let graphics = this.make.graphics({add: false});
graphics.fillStyle(0xff0000);
graphics.fillRect(0, 0, 8, 8);
graphics.generateTexture('tile01', 8, 8);
graphics.fillStyle(0x000000);
graphics.fillRect(0, 0, 8, 8);
graphics.generateTexture('tile02', 8, 8);
}
function create () {
let map = this.make.tilemap({ key: 'map' });
let img1 = map.addTilesetImage( 'tile01.png', 'tile01');
let img2 = map.addTilesetImage( 'tile02.png', 'tile02');
map.createLayer('Tile Layer 1', [img1, img2], 0, 0);
}
new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>

Getting bus error when composing a lot of images with sharp

I'm trying to compose a ton of images (2300) into a transparent png using sharp. I'm trying that with the following code:
await sharp({
create: {
width: 256,
height: 256,
channels: 4,
background: { r: 0, g: 0, b: 0, alpha: 0 },
},
})
.composite(images)
.png()
.toBuffer();
Where images is an array generated like this:
const pinSvg = fs.readFileSync("./icon_web_pin_record_basic.svg");
const pinWidth = 18;
const pinHeight = 25;
const generateImageFromLocationArray = (locations) => {
const images = [];
for (let i = 0; i < locations.length; i++) {
const [x, y] = locations[i];
images.push({
input: pinSvg,
blend: "add",
left: x - Math.floor(pinWidth / 2),
top: y - pinHeight,
});
}
return images;
};
With a few images, everything works fine, but with 2300 images, I get the following error:
[1] 12202 bus error node index.js
I have tried to set sharp.cache(false), but that has not worked. Any idea how to solve it? I suppose I'm getting some overflow, but I do not know how to fix it.

Create a grid on top of an image

I hope you are all well and safe.
In NodeJS, I wanted to create a grid on top of an image. Like this:
Image without grid
Image with grid
Can someone tell me, please, how can I achieve this (some library or something)?
After creating the grid, I would like to go square by square and check the information for each square. Does anyone have any ideas?
Thank you very much for your time!
The first answer has a native Cairo dependency... Below I used pureimage instead, which has Pure JS implementations of jpeg and png encoding.
static drawParallel = (canvas, step, isYAxis) => {
const c2d = canvas.getContext('2d')
const numberOfSteps = (canvas.width / step) | 0
const end = isYAxis ? canvas.height : canvas.width
console.log(`Steps: ${numberOfSteps}\n`)
c2d.lineWidth = 1.1 // PureImage hides thin lines
c2d.strokeStyle = 'rgba(255,192,203,0.69)'
for (let i = 1; i < numberOfSteps; i++) {
const from = i * step
const to = i * step
const mx = isYAxis ? [from, 0, to, end] : [0, from, end, to]
console.log(`Stroking ${mx[0]}, ${mx[1]} to ${mx[2]}, ${mx[3]}`)
c2d.beginPath()
c2d.moveTo(mx[0], mx[1])
c2d.lineTo(mx[2], mx[3])
c2d.stroke()
}
}
source: https://stackblitz.com/edit/feathersjs-7kqlyt
I would use Canvas. You can use it for all sorts of image jobs and editing. For example, you could get a transparent PNG image of the grid and lay it on:
const Canvas = require("canvas");
const canvas = Canvas.createCanvas(619, 319);
const ctx = canvas.getContext("2d");
let img = await Canvas.loadImage("./path/to/image.png");
ctx.drawImage(img, 0, 0, img.width, img.height);
let grid = await Canvas.loadImage("./path/to/grid.png");
ctx.drawImage(grid, 0, 0, canvas.width, canvas.height);
console.log(canvas.toDataURL());
I myself managed to get something like this.

Tweening Colors on Spark AR via Script

what would be the equivalent of a transition Patch in Reactive script? I would like to tween a color from say 0,0,0,1 to 1,1,1,1 in RGBA. I know ho to animate a single value as alpha, like this:
const timeDriver = Animation.timeDriver(timeDriverParameters);
const alphaSampler = Animation.samplers.linear(1, 0);
const alphaAnimation = Animation.animate(timeDriver, alphaSampler);
mymaterial.opacity = alphaAnimation;
Using visual patches you can use a Transform Patch to link a Vector3 to an animation progress. I cannot find something like this anywhere in the docs for reactive script. anyone can tell me?
Thank you!
you need to look at ShaderModule. Find the material by name, and then you can use setTexture.
const R = require('Reactive');
const A = require('Animation');
const S = require('Shaders');
const Materials = require('Materials');
const material = Materials.get('matName');
const driver = A.timeDriver({ durationMilliseconds : 1000});
const sampler = A.samplers.linear(
[1, 1, 1, 1],
[0, 0, 0, 1]
);
const colorAnimation = A.animate(
driver,
sampler
);
material.setTexture(
R.pack4(
colorAnimation.get(0),
colorAnimation.get(1),
colorAnimation.get(2),
colorAnimation.get(3)
),
{textureSlotName: S.DefaultMaterialTextures.DIFFUSE}
);
Here i've used ArrayOfScalarSamplers, but it's not crucial.

Resources