107 lines
3.3 KiB
JavaScript
107 lines
3.3 KiB
JavaScript
const path = require('path');
|
|
const fs = require('fs');
|
|
const { cv, drawBlueRect } = require('opencv4nodejs/ut');
|
|
// const { extractResults } = require('./dnn/ssdUtils');
|
|
|
|
if (!cv.xmodules.dnn) {
|
|
throw new Error('exiting: opencv4nodejs compiled without dnn module');
|
|
}
|
|
|
|
const modelPath = path.resolve(__dirname,
|
|
'../data/text-models/frozen_east_text_detection.pb');
|
|
const imgPath = path.resolve(__dirname, '../data/text-data/detection.png');
|
|
|
|
if (!fs.existsSync(modelPath)) {
|
|
console.log('could not find EAST model');
|
|
console.log('download the model from: https://github.com/oyyd/frozen_east_text_detection.pb/blob/71415464412c55bb1d135fcdeda498e29a67effa/frozen_east_text_detection.pb?raw=true'
|
|
+ ' or create a .pb model from https://github.com/argman/EAST');
|
|
throw new Error('exiting: could not find EAST model');
|
|
}
|
|
|
|
const MIN_CONFIDENCE = 0.5;
|
|
const NMS_THRESHOLD = 0.4;
|
|
const SIZE = 320;
|
|
|
|
function decode(scores, geometry, confThreshold) {
|
|
const [numRows, numCols] = scores.sizes.slice(2);
|
|
const boxes = [];
|
|
const confidences = [];
|
|
|
|
for (let y = 0; y < numRows; y += 1) {
|
|
for (let x = 0; x < numCols; x += 1) {
|
|
const score = scores.at([0, 0, y, x]);
|
|
|
|
if (score < MIN_CONFIDENCE) {
|
|
continue;
|
|
}
|
|
|
|
const offsetX = x * 4;
|
|
const offsetY = y * 4;
|
|
const angle = geometry.at([0, 4, y, x]);
|
|
const cos = Math.cos(angle);
|
|
const sin = Math.sin(angle);
|
|
|
|
const h = geometry.at([0, 0, y, x]) + geometry.at([0, 2, y, x]);
|
|
const w = geometry.at([0, 1, y, x]) + geometry.at([0, 3, y, x]);
|
|
|
|
const endX = offsetX + (cos * geometry.at([0, 1, y, x])) + (sin * geometry.at([0, 2, y, x]));
|
|
const endY = offsetY - (sin * geometry.at([0, 1, y, x])) + (cos * geometry.at([0, 2, y, x]));
|
|
const startX = endX - w;
|
|
const startY = endY - h;
|
|
|
|
boxes.push(new cv.Rect(
|
|
startX,
|
|
startY,
|
|
endX - startX,
|
|
endY - startY,
|
|
));
|
|
confidences.push(score);
|
|
}
|
|
}
|
|
|
|
return [boxes, confidences];
|
|
}
|
|
|
|
function detection(modelAbsPath, imgAbsPath) {
|
|
const net = cv.readNetFromTensorflow(modelPath);
|
|
const img = cv.imread(imgAbsPath);
|
|
const [imgHeight, imgWidth] = img.sizes;
|
|
const widthRatio = imgWidth / SIZE;
|
|
const heightRatio = imgHeight / SIZE;
|
|
|
|
const inputBlob = cv.blobFromImage(img, 1,
|
|
new cv.Size(SIZE, SIZE), new cv.Vec3(123.68, 116.78, 103.94), true, false);
|
|
|
|
net.setInput(inputBlob);
|
|
|
|
const outBlobNames = [
|
|
'feature_fusion/Conv_7/Sigmoid',
|
|
'feature_fusion/concat_3',
|
|
];
|
|
|
|
const [scores, geometry] = net.forward(outBlobNames);
|
|
const [boxes, confidences] = decode(scores, geometry, MIN_CONFIDENCE);
|
|
|
|
const indices = cv.NMSBoxes(
|
|
boxes,
|
|
confidences, MIN_CONFIDENCE, NMS_THRESHOLD
|
|
);
|
|
|
|
indices.forEach((i) => {
|
|
const rect = boxes[i];
|
|
const imgRect = new cv.Rect(
|
|
rect.x * widthRatio,
|
|
rect.y * heightRatio,
|
|
rect.width * widthRatio,
|
|
rect.height * heightRatio,
|
|
)
|
|
drawBlueRect(img, imgRect);
|
|
});
|
|
|
|
cv.imshowWait('EAST text detection', img);
|
|
}
|
|
|
|
detection(
|
|
modelPath,
|
|
imgPath
|
|
); |