Побочный эффект OpenCV.js: видео помещается в новую пустую матрицу без запроса - PullRequest
2 голосов
/ 02 мая 2019

Я пытаюсь отладить проблему, возникающую у меня с OpenCV.js. Я пытаюсь создать простую функцию поиска круга, но мой видеопоток отображается на моем холсте. Я свел его к наименьшему набору, который показывает проблему.

Что не имеет смысла, так это то, что я создаю новую пустую матрицу и отображаю ее, и вижу в ней мой видеопоток.

  1. Я начну с типичного способа обнаружения кругов: потоковое видео в матрицу scrMat, преобразование srcMat в оттенки серого grayMat, а затем вызов HoughCircles для обнаружения кругов от grayMat до circlesMat .
  2. Затем независимо создаю новый displayMat и отображаю его.
  3. Я вижу вывод ниже, где правая сторона - displayMat.

enter image description here

Каким-то образом displayMat заполняется. Эффект исчезнет, ​​если я закомментирую строку HoughCircles.

Как это происходит?

const cv = require('opencv.js');  // v1.2.1

const video = document.getElementById('video');
const width = 300;
const height = 225;
const FPS = 30;
let stream;

let srcMat = new cv.Mat(height, width, cv.CV_8UC4);
let grayMat = new cv.Mat(height, width, cv.CV_8UC1);
let circlesMat = new cv.Mat();

const cap = new cv.VideoCapture(video);

export default function capture() {
  navigator.mediaDevices.getUserMedia({ video: true, audio: false })
  .then(_stream => {
      stream = _stream;
      video.srcObject = stream;
      video.play();
      setTimeout(processVideo, 0)
  })
  .catch(err => console.log(`An error occurred: ${err}`));

  function processVideo () {
    const begin = Date.now();

    // these next three lines shouldn't affect displayMat
    cap.read(srcMat);
    cv.cvtColor(srcMat, grayMat, cv.COLOR_RGBA2GRAY);
    // if this line is commented out, the effect goes away
    cv.HoughCircles(grayMat, circlesMat, cv.HOUGH_GRADIENT, 1, 45, 75, 40, 0, 0);

    // this ought to simply create a new matrix and draw it
    let displayMat = new cv.Mat(height, width, cv.CV_8UC1);
    cv.imshow('canvasOutput', displayMat);

    const delay = 1000/FPS - (Date.now() - begin);
    setTimeout(processVideo, delay);
  }
}

1 Ответ

1 голос
/ 02 мая 2019

Скорее всего, displayMat создается в месте памяти, где некоторая обработка изображения была сделана с HoughCircles() или чем-то еще. Эта память была освобождена и стала доступной для размещения в ней новых объектов, но ни ее освобождение, ни новое создание Mat не очистили этот блок памяти.

Так что сначала очистите displayMat, так как он построен на месте некоторого "мусора", оставшегося от предыдущих операций, или используйте cv.Mat.zeros() для создания displayMat (zeros() заполняет весь новый матричный буфер нули).

let displayMat = cv.Mat.zeros(height, width, cv.CV_8UC1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...