Cannot load file with opencv.js

Hello everyone,
I’m trying to make use of the Haar-cascade face detection in an add-on.

I declared the xml file as a web accessible resource in the manifest.json and I also set the runtime file url according to the Mozilla documentation.

When I try printing the file in the console everything seems fine, but when I try to load it with the OpenCV cascade-classifier it can’t open the file.

This works fine

function testXML(){
  // URL or path to your XML file
  let face_url = browser.runtime.getURL('haarcascade_frontalface_default.xml');

  // Fetch the XML file
  fetch(face_url)
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not OK');
      }
      return response.text();
    })
    .then(xmlText => {
      // Process the XML text data
      console.log('XML file content:', xmlText);
      // Parse or manipulate the XML content as needed
    })
    .catch(error => {
      console.error('Error fetching the XML file:', error);
    });
}

But when I try to load it with an OpenCV cascade classifier, it just gives me this error:
[ERROR:0@4.715] global persistence.cpp:519 open Can’t open file: ‘moz-extension://b5fda0e1-3d96-44a3-84b6-5690d91d5429/haarcascade_frontalface_default.xml’ in read mode

function modifyImage(image) {  

  let src = cv.imread(image);
  let gray = new cv.Mat();
  cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0);
  let faces = new cv.RectVector();
  let eyes = new cv.RectVector();
  let face_url = browser.runtime.getURL('haarcascade_frontalface_default.xml');
  let faceCascade = new cv.CascadeClassifier(face_url);
  
  // detect faces
  let msize = new cv.Size(0,0);
  console.log('test1');
  faceCascade.detectMultiScale(gray, faces, 1.1, 3, 0, msize, msize);
  console.log('test2');
  for (let i = 0; i < faces.size(); i++) {
    let roiGray = gray.roi(faces.get(i));
    let roiSrc = src.roi(faces.get(i));
    let point1 = new cv.Point(faces.get(i).x, faces.get(i).y);
    let point2 = new cv.Point(faces.get(i).x + faces.get(i).width,
                              faces.get(i).y + faces.get(i).heigt);
    console.log('Face: point1: ', point1, ' point2: ', point2);

    /* detect eyes in face ROI
    eyeCascade.detectMultiScale(roiGray, eyes);
    for (let j = 0; j < eyes.size(); ++j) {
        let point1 = new cv.Point(eyes.get(j).x, eyes.get(j).y);
        let point2 = new cv.Point(eyes.get(j).x + eyes.get(j).width,
                                  eyes.get(j).y + eyes.get(j).heigt);
        console.log('Face: point1: ', point1, ' point2: ', point2);
    }*/
    roiGray.delete(); roiSrc.delete();
  }
  src.delete(); gray.delete(); faceCascade.delete();
  eyeCascade.delete(); faces.delete(); eyes.delete();
}

I also can’t see the problem in the OpenCV.js source code because it’s built with emscripten and not exactly readable.

I’ve been messing with the file path for days, but no matter what I try I can’t get OpenCV to load the xml file.

It’s hard to say, try to put the file in the “web_accessible_resources” array:

Alternatively, fetch the file manually and covert it to Data URL (and then store it in “face_url”.
Something like this:

// Fetch the XML file
fetch(xmlFileURL)
  .then(response => response.blob())
  .then(blob => {
    // Read the Blob as Data URI
    const reader = new FileReader();
    reader.onload = e => {
      console.log('Data URI:', e.target.result);
    };
    reader.readAsDataURL(blob);
  })

I had already put the file in the “web_accessible_resources” array.
Fetching the file and converting it to a Data URL didn’t solve the problem either, but thanks for trying.

Looking at other forums, it seems like the file path is a common issue, and it only seems to work when running OpenCV.js in node.js and then using the absolute file path.

1 Like