2016-06-05 1 views
2

В OpenCV можно указать интересующую область через маску в качестве входного сигнала для алгоритма детектирования признаков. С моей точки зрения, я ожидал бы огромного прироста производительности, но простой тест с небольшим ROI не может это подтвердить.Детекторы функции OpenCV - маска ROI для лучшей производительности?

Можно ли ожидать повышения производительности при использовании масок в OpenCV? Или нужно обрезать изображения?

ответ

1

Я не уверен, если это то, что вы ищете (особенно, так как это в Java), но проверить this file, в частности, функция в строке 121.

Вот это для вашего удобства:

MatOfRect diceDetections = new MatOfRect(); // Essentially an array of locations where our dice features were detected. (Stupid wrappers) 

    // Note that detectMultiScale has thrown an unknown exception before (literally, unknown). This is to prevent crashing. 
    try { 
     diceCascade.detectMultiScale(image, diceDetections, 1.1, 4, 0, new Size(20, 20), new Size(38, 38)); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    // Debug, used for console output 
    String curDetect = ""; 

    // Iterates for every Dice ROI 
    for (int i = 0; i < diceDetections.toArray().length; i++) { 

     Rect diceRect = diceDetections.toArray()[i]; 

     // Draws rectangles around our detected ROI 
     Point startingPoint = new Point(diceRect.x, diceRect.y); 
     Point endingPoint = new Point(diceRect.x + diceRect.width, diceRect.y + diceRect.height); 
     Imgproc.rectangle(image, startingPoint, endingPoint, new Scalar(255, 255, 0)); 

     MatOfRect pipDetections = new MatOfRect(); 

     try { 
      /* 
      * Now this is interesting. We essentially create a sub-array of the image, with our dice ROI as the image. Then we perform the detection on the image. This gives us the relative 
      * positions of our pip ROIs to the dice ROI. Later on, we can draw the circles around the pip ROI, with the centers' positions adjusted by adding the dice ROI positions, so that it 
      * renders properly. This is an amazing trick, as it not only eliminates false positives in non-dice ROIs, but it reduces how many pixels the classifier has to analyze to only at most 
      * 38 x 38 pixels (because of the size restraints provided while detecting dice ROIs). This means we can set the precision to an insane level, without performance loss. 
      */ 
      pipCascade.detectMultiScale(image.submat(diceRect), pipDetections, 1.01, 4, 0, new Size(2, 2), new Size(10, 10)); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     // Gets the number of detected pips and draws a cricle around the ROI 
     int numPips = 0; 
     for (int y = 0; y < pipDetections.toArray().length; y++) { 
      Rect pipRect = pipDetections.toArray()[y]; // Provides the relative position of the pips to the dice ROI 
      /* 
      * Finds the absolute center of a pip. diceRect.x and diceRect.y provides the top-left position of the dice ROI. pipRect.x and pipRect.y provides the top-left position of the pip ROI. 
      * Normally, to find a center of an object with size (w, h) with the top-left point (x, y), we divide the width and height by two, and then add on the x pos to the width and y pos to 
      * the height. Now, since pipDetections only provide relative positioning to the dice ROI, we also need to add the dice position to find our absolute center position (aka relative to 
      * the entire image). 
      */ 
      Point center = new Point(diceRect.x + pipRect.x + pipRect.width/2, diceRect.y + pipRect.y + pipRect.height/2); 
      Imgproc.ellipse(image, center, new Size(pipRect.width/2, pipRect.height/2), 0, 0, 360, new Scalar(255, 0, 255), 1, 0, 0); 

      numPips++; 
     } 

в общем, у меня есть два классификаторы, один признать DICE (строка 129) и один признать зернышки (черные точки) на кости. Он получает массив ROI для костей, а затем для каждого элемента в массиве, возьмите подматрицу изображения (расположенную в ROI) и попросите классификатор пинга по этой матрице вместо всего изображения (строка 156). Однако, если вы пытаетесь отобразить обнаружение (пипсы в моем примере), вам нужно будет компенсировать его положением ROI, в котором вы находитесь, следовательно, работа по линиям 171 и 172.

Я уверен, что это обеспечивает тот же выигрыш в производительности, который вы ищете, просто не обязательно одним и тем же способом (subimaging vs masking).

+0

Это именно то, что я искал. Для меня не важно, нужно ли использовать маски или субимазы, чтобы получить прирост производительности, но в первую очередь я подумал, что OpenCV уже реализовал что-то вроде субимации внутри детекторов функций. –

2

Скорее всего, маска просто удаляет все ключевые точки за пределами маски, поэтому OpenCV все еще должен разобрать все изображение.

Вы можете уменьшить размер вашего изображения, чтобы улучшить скорость

Смежные вопросы