Tensorflow js server side classification with mobilenet and blazeface - node.js

I'm trying to use tensorflowjs with an already built model, at the beginning I had a problem with blazeface because it didn't find face on photo (that display just faces) and so I'm trying with mobilenet and same probleme the result are non sens. So pretty sur it came from the format of image I'm sending.
So this is my code:
module.exports = {
blazeface: require('#tensorflow-models/blazeface'),
mobilenet: require('#tensorflow-models/mobilenet'),
tf: require("#tensorflow/tfjs-node"),
fs: require("fs"),
sizeOf: require("image-size"),
async structureData(imageLink) {
let data = this.fs.readFileSync(imageLink);//return a buffer
const dimension = await this.sizeOf(imageLink);
const tensorflowImage = {
data: data,
width: dimension.width,
height: dimension.height
};
console.log(tensorflowImage)
return tensorflowImage;
},
async detectFace(imageLink) {
let image = await this.structureData(imageLink);
const model = await this./*blazeface*/mobilenet.load();
const returnTensors = false;
const predictions = await model.classify(image);
console.log(predictions);
}
}
So this code do not result of an error but the result are this =>
[
{
className: 'theater curtain, theatre curtain',
probability: 0.03815646469593048
},
{
className: 'web site, website, internet site, site',
probability: 0.0255243219435215
},
{ className: 'matchstick', probability: 0.02520526386797428 }
]
and with any photo (here it's a banana in white background).
So I'm pretty sur i need to rebuilt the structureData function but I don't know how ...
I also tried this with uint32array
async structureData(imageLink) {
let data = this.fs.readFileSync(imageLink);
data = new Uint32Array(data);
const dimension = await this.sizeOf(imageLink);
const tensorflowImage = {
data: data,
width: dimension.width,
height: dimension.height
};
console.log(tensorflowImage)
return tensorflowImage;
},
But I'm getting this error.
Error: pixels passed to tf.browser.fromPixels() must be either an HTMLVideoElement, HTMLImageElement, HTMLCanvasElement, ImageData in browser, or OffscreenCanvas, ImageData in webworker or {data: Uint32Array, width: number, height: number}, but was Object
remember that i'm using node and so I can't (or don't think I can) us HTMLimageelement
Thanks a lot :)

By using a tensor, a video or image element as parameter to the model, it will be able to do the classification.
let data = this.fs.readFileSync(imageLink);
tensor = tf.node.decodeImage(data, 3)
await model.classify(tensor)

Related

How to center continued text using PdfKit?

I have this code:
const PDFDocument = require("pdfkit");
const QRCode = require("qrcode");
const fs = require("fs");
const exec = async () => {
const doc = new PDFDocument({ layout: "landscape" });
doc.pipe(fs.createWriteStream("output.pdf"));
for (let pageNumber = 1; pageNumber <= 1000; pageNumber++) {
const url = await QRCode.toDataURL("I am a url!");
doc
.image(url, 10, 100, {
width: 420,
height: 420,
align: "center",
valign: "center",
})
doc
.font("Helvetica")
.fontSize(50)
.fillColor("#000")
.text(`Item `, 465, 200, { continued: true })
.fontSize(55)
.font("Courier-Bold")
.fillColor("#1b83c5")
.text(`${pageNumber}`);
doc
.font("Helvetica-Bold")
.fontSize(40)
.fillColor("#000")
.text("Order and Pay", 420, 320);
doc.addPage();
}
doc.end();
};
exec();
Which would produce something like this:
It looks centered and all, but as pages increase it will no longer be centered since the numbers are fixed.
I saw in the docs that there's an align property, but the docs didn't explain how to handle continued text.
Any working examples?
Maybe it's a little late, but I found a solution battling with the same problem:
First you need to create a constant with the width of the container you want to center your text in: (this value you have to calculate or invent, but it's easy to do that)
const containerWidth = 100 // as an example
Then, you need to create a variable that contains a plain string that contains all the text you want to center, in your example:
var appendedText = `Item ${pageNumber}`
To finish, you need to use pdf-kit's function: widthOfString, and add the text in the document as follows:
const xOffset = 465 // The original X offset value
doc
.text(`Item `, xOffset + (containerWidth / 2) - (doc.widthOfString(appendedText) / 2), 200, { continued: true })
.text(`${pageNumber}`);
Removed the text styling lines for clarity, but you have to add them later.

Display images from Node (MERN)

I’m building a MERN App and trying to display image saved in MongoDB on the fronted. I use Multer and Sharp to process images when saved to database like so:
const buffer = await sharp(req.file.path)
.resize({ width: 160, height: 160 })
.png()
.toBuffer();
group.groupImgUrl = Buffer.from(buffer, "binary").toString("base64");
await group.save();

when I console.log(group.groupImgUrl), it gives me the following output: new Binary(Buffer.from("6956….73d3d", "hex"), 0)
On the frontend side, I receive the groupImgUrl in different formats, sometimes in typed array, sometimes in string. when the response is in shape: groupImgUrl: { type: Buffer; data: Array }, I can transform the typed array and display it properly:
let base64Str = "";
if ("data" in group.groupImgUrl) {
response.group.groupImgUrl.data.forEach((index: number) => {
base64Str += String.fromCharCode(index)
})
}
<img src = `data:image/png;base64,${src}` />
However, when I receive the groupImgUrl in string format, it’s somehow tampered and cannot display correctly using src = data:image/png;base64,${src}
My question is, how come I receive the same image in different formats, and how to display them properly?

React Native Redux Component not rerendering on Redux State Change

I am working on a shopping basket component in React Native. The content and price of the basket get saved in the global redux store. When the user selects an item, an action gets dispatched to add the item to the basket and to update the total basket price.
The UI however does not get updated on this global state change.
My Reducer
const INITIAL_STATE = {
basket: [],
basketPrice: 0,
};
const mainReducer = (state = INITIAL_STATE, action) => {
const stateCpy = state;
switch (action.type) {
case 'SET_BASKET':
stateCpy.basket = action.payload
return stateCpy;
case 'ADD_TO_BASKET':
stateCpy.basket.push(action.payload)
return stateCpy
case 'REMOVE_FROM_BASKET':
let tempItems = stateCpy.basket
for (var x = 0; x < stateCpy.basket.length; x++) {
if (stateCpy.basket[x]._id === action.payload) {
tempItems.splice(x, 1)
break;
}
}
stateCpy.basket = tempItems
return stateCpy
case 'SET_BASKET_PRICE':
stateCpy.basketPrice = action.payload
console.log(stateCpy.basketPrice)
return stateCpy
default:
return state
}
};
export default mainReducer
My Actions
const setBasket = basket => ({
type: 'SET_BASKET',
payload: basket,
});
const addToBasket = item => ({
type: 'ADD_TO_BASKET',
payload: item,
});
const removeFromBasket = item_id => ({
type: 'REMOVE_FROM_BASKET',
payload: item_id,
});
const setBasketPrice = price => ({
type: 'SET_BASKET_PRICE',
payload: price,
});
export default actions = {
setBasket,
addToBasket,
removeFromBasket,
setBasketPrice
}
My UI Component
...
import { useSelector, useDispatch } from 'react-redux'
export const RestaurantView = ({ navigation, route }) => {
const basket = useSelector((state) => state.basket)
const basketPrice = useSelector((state) => state.basketPrice)
const dispatch = useDispatch()
...
function calcBasketPrice(){
let tempBasketPrice = 0
basket.forEach(element => {
tempBasketPrice += element.price
});
return tempBasketPrice
}
function addToBasket(item) {
dispatch(actions.setBasketPrice(calcBasketPrice() + item.price))
dispatch(actions.addToBasket(item))
}
return ( <View>
<ItemCard onPress={addToBasket}> </ItemCard>
<Text style={{ textAlign: "right", padding: 15, fontSize: 20 }}> {basketPrice}</Text>
</View>)
}
When logging the basketPrice to console in the reducer, it logs the correct, updated value on each press/dispatch but there no changes in the UI. When a local state change is made to force a rerender, it renders with the correct value from the global store.
Your stateCpy variable is actually not a copy, but just a reference to state - so your reducer is actually modifying the old redux state instead of creating a new one.
Since this is a very outdated style of Redux and in modern Redux createSlice reducers it is totally okay to modify state, I would recommend you not to fix this in legacy Redux, but to take a look at modern Redux - which is also less error-prone and about 1/4 of the code you would write with legacy Redux.
Rewriting your reducer is not a lot of work and in the long run you will really benefit from the (since 2019) new style.
Take a look at the official Redux tutorial

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.

How and when to use PIXI.RenderTexture

I am building a tool which visualises bicycle wheels. It uses approximately 100 PIXI.Graphics to build the entire wheel, which is all placed in a PIXI.Container and then rendered. It seems like quite a lot to render every frame, so I was looking into the PIXI.RenderTexture class and thought it might make sense to use it in this case. So question 1, is this a good use case? and question 2, how can I use it because I am having trouble working it out.
const options = {
transparent: true,
antialias: true,
backgroundColor: 0xffffff,
resolution: window.devicePixelRatio,
view: canvasEle,
};
const app = new PIXI.Application(width, height, options);
const wrapper = new PIXI.Container(); // Wrapper is used for zooming and panning the wheel
app.stage.addChild(wrapper);
const wheel = new Wheel(wheelOpts); // Returns PIXI.Container full of PIXI.Graphics
wrapper.addChild(wheel);
And my attempt to use the renderTexture is as follows. But I can't seem to work it out
const options = {
transparent: true,
antialias: true,
backgroundColor: 0xffffff,
resolution: window.devicePixelRatio,
view: canvasEle,
};
const app = new PIXI.Application(width, height, options);
const wrapper = new PIXI.Container(); // Wrapper is used for zooming and panning the wheel
app.stage.addChild(wrapper);
const wheelRenderTexture = new PIXI.RenderTexture.create(width, height);
const wheelSprite = new PIXI.Sprite(wheelRenderTexture)
wrapper.addChild(wheelSprite)
const wheel = new Wheel(wheelOpts); // Returns PIXI.Container full of PIXI.Graphics
app.ticker.add(() =>
{
app.renderer.render(wheel, wheelRenderTexture);
})
Thanks for any help
I worked out how to use it and made a small jsfiddle https://jsfiddle.net/hp98ygz5/1/
const width = 600
const height = 600
var app = new PIXI.Application(width, height, {backgroundColor : 0xffffff});
document.body.appendChild(app.view);
const wheelRenderTexture = PIXI.RenderTexture.create(width, height);
const wheelRenderSprite = new PIXI.Sprite(wheelRenderTexture);
app.stage.addChild(wheelRenderSprite)
const wheelContainer = new PIXI.Container()
//app.stage.addChild(wheelContainer)
wheelContainer.addChild(drawCircle(100,100,50,0xfec3dc,2,0Xfe68a4))
wheelContainer.addChild(drawCircle(100,100,20,0xFFCC66,2,0X55ff77))
app.renderer.render(wheelContainer,wheelRenderTexture)
I am not sure what was wrong with the above example but it works now

Resources