Hello, I am developing a project with the Ionic Angular platform. In my project, I am using the Cordova Camera Preview plugin to continuously process images from the phone camera with OpenCV. That is, images from the phone camera are processed every 100ms. The application works fine for the first 30-40 seconds. However, after that, it gives the error “Failed to allocate 1240308 bytes in function ‘OutOfMemoryError’”, and stops image processing. I have written the code I use below. I am deleting all of the Mat variables I use, but I still get the same error. How can deal with OutOfMemoryError of Opencv.js. Thank you for your help.
TestFunction() {
try {
this.cameraPreviewService.getCameraSize().then(cameraSize => {
this.cameraSize = JSON.parse(cameraSize);
this.captureImage().then(res => {
console.log(res)
requestAnimationFrame(this.TestFunction.bind(this));
})
}).catch(error => { console.log(error) });
} catch (error) {
console.log( error)
}
}
captureImage(): Promise<string> {
return new Promise((resolve, reject) => {
try {
let data = JSON.parse(JSON.stringify(this.cameraPreviewOptions))
this.cameraPreviewService.testFunction(data).subscribe(response => {
this.imgUrl = 'data:image/png;base64,' + response.imageBytes;
let imageMAT = cv.imread(this.ImageElement);
let desiredWidth = this.answerShadowDivWidth;
let desiredHeight = this.answerShadowDivHeight;
let dsize = new cv.Size(desiredWidth, desiredHeight);
this.rotateImage(imageMAT);
cv.resize(this.output, imageMAT, dsize, 0, 0, cv.INTER_LINEAR);
this.findRectforImage(imageMAT);
if (imageMAT) {
imageMAT.delete();
this.output.delete();
this.rotationMatrix.delete();
}
resolve("Image process is Finished")
})
} catch (error) {
resolve(error);
}
})
}
findRectforImage(imageMAT) {
try {
let rectCoordinates = [];
let contours = new cv.MatVector();
let hierarchy = new cv.Mat();
let gray = new cv.Mat();
cv.cvtColor(imageMAT, gray, cv.COLOR_RGBA2GRAY, 0);
cv.threshold(gray, gray, 100, 255, cv.THRESH_BINARY);
cv.findContours(gray, contours, hierarchy, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE);
for (let i = 0; i < contours.size(); ++i) {
let cnt = contours.get(i);
let rect = cv.boundingRect(cnt);
let aspectRatio = rect.width / rect.height;
if (aspectRatio >= 0.9 && aspectRatio <= 1.1 && rect.width >= 15) {
//Rectangle found
cv.drawContours(imageMAT, contours, i, [0, 255, 0, 255], 2, cv.LINE_AA, hierarchy, 100);
}
}
cv.imshow(this.canvas, imageMAT);
hierarchy.delete();
gray.delete();
} catch (error) {
console.log("ERROR IN FINDCOUNTOUR====>>>>>", error);
throw cv.exceptionFromPtr(error).msg;
}
}
rotateImage(image) {
try {
this.output = new cv.Mat();
let size = new cv.Size();
size.width = image.cols;
size.height = image.rows;
// To add transparent borders
let scalar = new cv.Scalar(0, 0, 0, 0);
let center;
let padding;
let height = size.height;
let width = size.width;
if (height > width) {
center = new cv.Point(height / 2, height / 2);
padding = (height - width) / 2;
// Pad out the left and right before rotating to make the width the same as the height
cv.copyMakeBorder(image, this.output, 0, 0, padding, padding, cv.BORDER_CONSTANT, scalar);
size.width = height;
} else {
center = new cv.Point(width / 2, width / 2);
padding = (width - height) / 2;
// Pad out the top and bottom before rotating to make the height the same as the width
cv.copyMakeBorder(image, this.output, padding, padding, 0, 0, cv.BORDER_CONSTANT, scalar);
size.height = width;
}
// Do the rotation
this.rotationMatrix = cv.getRotationMatrix2D(center, -90, 1);
cv.warpAffine(
this.output,
this.output,
this.rotationMatrix,
size,
cv.INTER_LINEAR,
cv.BORDER_CONSTANT,
new cv.Scalar()
);
let rectangle;
if (height > width) {
rectangle = new cv.Rect(0, padding, height, width);
} else {
/* These arguments might not be in the right order as my solution only needed height
* > width so I've just assumed this is the order they'll need to be for width >=
* height.
*/
rectangle = new cv.Rect(padding, 0, height, width);
}
// Crop the image back to its original dimensions
this.output = this.output.roi(rectangle);
} catch (error) {
console.log("ERROR IN ROTATEMAGE====>>>>>", error);
throw cv.exceptionFromPtr(error).msg;
}
}