I'm trying to get YOLOv4 detection to work using OpenCV.js.
It looks like I've successfully gotten the net read using
const net = cv.readNetFromDarknet(files.config, files.weights);
And I'm using getBlobFromImage
from the tutorial to get the network input:
getBlobFromImage = function(inputSize, mean, std, swapRB, image) {
let mat;
if (typeof(image) === 'string') {
mat = cv.imread(image);
} else {
mat = image;
}
let matC3 = new cv.Mat(mat.matSize[0], mat.matSize[1], cv.CV_8UC3);
cv.cvtColor(mat, matC3, cv.COLOR_RGBA2BGR);
let input = cv.blobFromImage(matC3, std, new cv.Size(inputSize[0], inputSize[1]),
new cv.Scalar(mean[0], mean[1], mean[2]), swapRB);
matC3.delete();
return input;
}
However, when I try to run forward
on the network, I get an error that says Uncaught
followed by a seemingly random number.
I've tried
net.setInput(blob)
net.forward()
And I get the error.
I found a source online that said you need to use layer names and an output vector using forward2
, so I've tried that with hardcoded layer names (as OpenCV.js doesn't expose a method to get layer names):
net.setInput(blob)
const outs = new cv.MatVector();
net.forward2(outs, ["yolo_139", "yolo_150", "yolo_161"]);
And I still get the uncaught error. I've also resized my image so width and height are both multiples of 32, which I read somewhere was necessary.
Any ideas? I've been searching for answers but haven't found anything yet.
Edit: More detail on error
I just tried running it a few times, and here is the output:
Uncaught 279968808
Uncaught 279899688
[then, after refresh]
Uncaught 279968808
Uncaught 279899688
Here's the stack trace:
___cxa_throw opencv.js:30
<anonymous> opencv.js line 30 > WebAssembly.instantiate:899300
<anonymous> opencv.js line 30 > WebAssembly.instantiate:898391
<anonymous> opencv.js line 30 > WebAssembly.instantiate:315351
<anonymous> opencv.js line 30 > WebAssembly.instantiate:315293
<anonymous> opencv.js line 30 > WebAssembly.instantiate:545156
<anonymous> opencv.js line 30 > WebAssembly.instantiate:525900
<anonymous> opencv.js line 30 > WebAssembly.instantiate:525121
<anonymous> opencv.js line 30 > WebAssembly.instantiate:65086
<anonymous> opencv.js line 30 > WebAssembly.instantiate:65049
<anonymous> opencv.js line 30 > WebAssembly.instantiate:5596483
dynCall_iiiii opencv.js:30
dynCall_iiiii_9 opencv.js line 30 > Function:4
constructor_body opencv.js:30
constructor opencv.js:30
Mat opencv.js line 30 > Function:4
matFromImageData opencv.js:30
imread opencv.js:30
getBlobFromImage DetectApp.js:24
run DetectApp.js:63
<anonymous> debugger eval code:1
So that's an instance of it failing to run getBlobFromImage
, but that only fails occasionally, it usually succeeds. Here's the more common stack trace, with a failure in dnn_Net$forward2
:
___cxa_throw opencv.js:30
<anonymous> opencv.js line 30 > WebAssembly.instantiate:899300
<anonymous> opencv.js line 30 > WebAssembly.instantiate:898391
<anonymous> opencv.js line 30 > WebAssembly.instantiate:315351
<anonymous> opencv.js line 30 > WebAssembly.instantiate:315293
<anonymous> opencv.js line 30 > WebAssembly.instantiate:545156
<anonymous> opencv.js line 30 > WebAssembly.instantiate:525900
<anonymous> opencv.js line 30 > WebAssembly.instantiate:526317
<anonymous> opencv.js line 30 > WebAssembly.instantiate:697106
<anonymous> opencv.js line 30 > WebAssembly.instantiate:327453
<anonymous> opencv.js line 30 > WebAssembly.instantiate:529953
<anonymous> opencv.js line 30 > WebAssembly.instantiate:2720179
<anonymous> opencv.js line 30 > WebAssembly.instantiate:2717263
<anonymous> opencv.js line 30 > WebAssembly.instantiate:2717095
<anonymous> opencv.js line 30 > WebAssembly.instantiate:3384719
<anonymous> opencv.js line 30 > WebAssembly.instantiate:3323788
<anonymous> opencv.js line 30 > WebAssembly.instantiate:3318607
<anonymous> opencv.js line 30 > WebAssembly.instantiate:3365552
<anonymous> opencv.js line 30 > WebAssembly.instantiate:2646791
<anonymous> opencv.js line 30 > WebAssembly.instantiate:141167
<anonymous> opencv.js line 30 > WebAssembly.instantiate:204282
<anonymous> opencv.js line 30 > WebAssembly.instantiate:5596551
dynCall_viiii opencv.js:30
dynCall_viiii_1868 opencv.js line 30 > Function:4
dnn_Net$forward2 opencv.js line 30 > Function:10
run DetectApp.js:66
<anonymous> debugger eval code:1
The error messages are quite opaque. If you're running on the latest build and still this crashes without clear error messages, perhaps submit an issue on OpenCV's github but check first if that hasn't been reported already.
I did not see any resizing in your inference code. If the inference code you have doesn't already resize inputs, you should try adding that.
Neural networks usually expect inputs of a specific size*. For YOLOv4 that might be 416x416 or 224x224 (tiny?), which are determined when the network is designed.
During training, either all the inputs are already the right size, or the training script resizes the inputs.
* fully convolutional networks take arbitrary sizes