Zoeken…


Syntaxis

  • CascadeClassifier cascade = nieuwe CascadeClassifier ("cascade.xml"); // Maakt een cascade-classifier van cascade.xml
  • Mat afbeelding = Imgcodecs.imread ("image.png"); // Converteert image.png naar een Mat (Matrix) -object
  • MatOfRect detecties = nieuwe MatOfRect (); // Maakt een leeg MatOfRect-bestand (Matrix of Rectangles) dat wordt gebruikt als uitvoer voor onze detectieklassen
  • detections.toArray (); // Retourneert een reeks Rect-objecten die kunnen worden herhaald
  • Imgproc.rectangle (afbeelding, nieuw punt (rect.x, rect.y), nieuw punt (rect.x + rect.width, rect.y + rect.height), nieuwe Scalar (0, 255, 0)); // Tekent een groen omlijnde rechthoek van de x- en y-locaties van het eerste punt naar de x- en y-locatie van het tweede punt op de "afbeelding" van het Mat-object. "rect" is een object Rect, meestal geleverd door detections.toArray (). Gebruikt de Point-klasse van OpenCV.
  • Imgcodecs.imwrite ("output.png", afbeelding); // Schrijft het gewijzigde Mat-object "image" naar de "output.png"
  • CascadeClassifier.detectMultiScale (afbeelding, detecties); // Detecteert elk object in het Mat-object "afbeelding" en voert de detecties uit in het MatOfRect-object "detecties"
  • CascadeClassifier.detectMultiScale (afbeelding, detecties, scaleFactor , minNeighbours , vlaggen , minSize , maxSize ); // Voert een detectie uit met aanvullende parameters. Zie de onderstaande details.
  • Imgproc.ellipse (afbeelding, midden, assen , 0, 0, 360, nieuwe Scalar (255, 0, 255), dikte , lineType , 0); // Tekent een ellips op de afbeelding in het center van het punt. Gebruikt de Point-klasse van OpenCV.

parameters

Parameter Details
schaal factor Hoeveel de afbeeldingsgrootte op elke afbeeldingsschaal wordt verkleind. Standaard = 1.1
minNeighbors Hoeveel buren een kandidaat-rechthoek moet hebben voordat deze als een gedetecteerd object wordt geselecteerd. Standaard = 4
vlaggen Oude vlaggen. In de meeste gevallen moet dit op 0 worden ingesteld. Standaard = 0
minSize Minimale grootte die een kandidaat-rechthoek kan zijn. Dit maakt gebruik van de klasse Size OpenCV. Kan worden gebruikt om de detectietijd en het CPU-gebruik te verminderen en om valse positieven te verminderen.
maxSize Maximale grootte die een kandidaat-rechthoek kan zijn. Dit maakt gebruik van de klasse Size OpenCV. Kan worden gebruikt om de detectietijd en het CPU-gebruik te verminderen en om valse positieven te verminderen.
as Gebruikt OpenCV's Size-klasse. Bepaalt de breedte en hoogte van de ellips.
dikte Dikte van de lijn, in pixels.
Linetype Heeft verschillende parameters. 0 is de ononderbroken lijn, 8 is voor een 8-verbonden lijn, 4 is voor een 4-verbonden lijn en CV_AA is voor een CV_AA . Standaard = 8

Een statisch beeld krijgen, items erop detecteren en de resultaten uitvoeren.

Merk op dat dit voorbeeld OpenCV 3.1 gebruikt.

import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;

public class Classifier {
    private CascadeClassifier diceCascade = new
        CascadeClassifier("res/newMethod/diceCascade.xml");
    private Mat image;
    private String loc = "path/to/image.png";
    private String output = "path/to/output.png";

    public void detImg() {
    
        Mat image = Imgcodecs.imread(loc); // Reads the image
    
        MatOfRect diceDetections = new MatOfRect(); // Output container
        diceCascade.detectMultiScale(image, diceDetections); // Performs the detection
    
        // Draw a bounding box around each detection.
        for (Rect rect : diceDetections.toArray()) {
            Imgproc.rectangle(image, new Point(rect.x, rect.y),
                new Point(rect.x + rect.width, rect.y + rect.height),
                new Scalar(0, 255, 0));
        }
    
        // Save the visualized detection.
        Imgcodecs.imwrite(output, image);
    
    }
}

De Rect[] geretourneerd door diceDetections.toArray() kan worden herhaald. Elk Rect in de array heeft vier hoofdeigenschappen: x , y , width en height . x en y definiëren de positie linksboven van de rechthoek en width en height retourneert een int van de breedte en hoogte van de rechthoek. Dit wordt gebruikt bij het tekenen van rechthoeken op afbeeldingen. De minimaal vereiste parameters van de functie Imgproc.rectangle zijn als volgt:

Imgproc.rectangle(Mat image, Point start, Point end, Scalar color);

Beide Point worden gebruikt voor de functies van de linkerbovenhoek en de rechteronderhoek. Deze posities zijn beide absoluut voor de afbeelding die als eerste parameter wordt gegeven, niet voor elkaar. U moet dus zowel de x of y positie van de rechthoek toevoegen naast de width of height om het end correct te definiëren.

Merk op dat de Point klasse die in deze parameters wordt gebruikt, niet de Point klasse van Java's standaardbibliotheek is. In plaats daarvan moet u de Point klasse van OpenCV importeren!

Afbeeldingen van een videoapparaat detecteren

Dit voorbeeld introduceert de VideoCapture klasse, waar we deze gebruiken om een afbeelding van een webcam te maken en op te slaan in een afbeelding.

import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;

public class Classifier {
    private CascadeClassifier diceCascade = new
        CascadeClassifier("res/newMethod/diceCascade.xml");
    private Mat image;
    private String loc = "path/to/image.png";
    private String output = "path/to/output.png";
    private VideoCapture vc = new VideoCapture();

    public void detImg() {
        vc.open(0); // Opens the video stream

        Mat image = new Mat(); // Creates an empty matrix
        vc.read(image); // Reads the image from the video stream and
            writes it to the image matrix.
    
        MatOfRect diceDetections = new MatOfRect(); // Output container
        diceCascade.detectMultiScale(image, diceDetections); // Performs the detection
    
        // Draw a bounding box around each detection.
        for (Rect rect : diceDetections.toArray()) {
            Imgproc.rectangle(image, new Point(rect.x, rect.y),
                new Point(rect.x + rect.width, rect.y + rect.height),
                new Scalar(0, 255, 0));
        }
    
        // Save the visualized detection.
        Imgcodecs.imwrite(output, image);

        vc.release(); // Closes the stream.
    
    }
}

Een Mat-object omzetten in een BufferedImage-object

Dit voorbeeld van Daniel Baggio is rechtstreeks overgenomen uit dit StackExchange-antwoord , maar is opnieuw geplaatst voor zichtbaarheid.

Deze klasse neemt een Mat-object en retourneert het BufferedImage-object dat wordt gebruikt door de javax.swing bibliotheken. Dit kan door een Graphics object worden gebruikt om de afbeelding te tekenen.

private BufferedImage toBufferedImage(Mat m) {
    if (!m.empty()) {
        int type = BufferedImage.TYPE_BYTE_GRAY;
        if (m.channels() > 1) {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
        int bufferSize = m.channels() * m.cols() * m.rows();
        byte[] b = new byte[bufferSize];
        m.get(0, 0, b); // get all the pixels
        BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
        final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        System.arraycopy(b, 0, targetPixels, 0, b.length);
        return image;
    }
    
    return null;
}

Detecties binnen detecties

Dit voorbeeld gebruikt dobbelstenen en de zwarte vlekken op de dobbelstenen (de pips) als ons object. Omdat het voorbeeld vrij lang is, is het eerst van cruciaal belang om enkele sleutelconcepten uit te leggen om het voorbeeld te begrijpen.

Inzicht in het eerste voorbeeld: "Een statische afbeelding ophalen, items erop detecteren en de resultaten uitvoeren." is van cruciaal belang om dit voorbeeld te begrijpen, vooral hoe OpenCV rechthoeken tekent.

Bekijk de volgende afbeelding:

voer hier de afbeeldingsbeschrijving in

We zullen de subimaging-methode gebruiken, waarbij we een gedetecteerd gebied gebruiken als basis voor het toepassen van meer detecties. Dit is alleen mogelijk als een object zich altijd in een ander object bevindt dat we kunnen detecteren, zoals onze pitten op onze dobbelstenen. Deze methode heeft verschillende voordelen:

  • In plaats van de hele afbeelding te scannen, hoeven we alleen het gebied te scannen waar we weten dat het object zich zal bevinden.
  • Verwijdert elke kans op valse positieven buiten het detectiegebied.

We doen dit door eerst een cascade-classificatiescan over de hele afbeelding toe te passen om ons een MatOfRect object te geven dat onze grote objecten bevat (dobbelstenen, in dit geval). Vervolgens doorlopen we de Rect[] toArray() gegeven door de functie toArray() van het object MatOfRect . Dit object Rect wordt gebruikt bij het maken van een tijdelijk Mat object dat wordt "bijgesneden" naar de eigenschappen van het Rect object ( x, y, width, height ) van de oorspronkelijke afbeelding, waar we vervolgens detecties kunnen uitvoeren op het tijdelijke Mat object. Met andere woorden, we vertellen de classificator om in plaats daarvan alleen detecties uit te voeren op de dobbelsteengedeelten van de afbeelding, en we specificeren de positie van elke dobbelsteen met behulp van de Rect objecten die we hebben gekregen van het uitvoeren van een detectie op de hele afbeelding.

De Rect objecten (pips) hebben echter hun eigenschappen ten opzichte van hun dobbelstenen, en niet de afbeelding zelf. Om dit probleem op te lossen, als we willen rechthoeken vestigen op de werkelijke afbeelding die plaatsen de pitten, voegen we zowel dice.x en dice.y naar de start Point .

import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;

public class Classifier {

    private CascadeClassifier diceCascade =
        new CascadeClassifier("res/newMethod/diceCascade.xml");
    private CascadeClassifier pipCascade =
        new CascadeClassifier("res/newMethod/pipCascade6.xml");
    private VideoCapture vc = new VideoCapture();
    private Mat image;

    public void openVC(int index) {
        vc.open(index);
    }

    public void closeVC() {
        vc.close();
    }

    public Mat getNextImage() {
        image = new Mat();
        vc.read(image); // Sets the matrix to the current livestream frame.
        
        MatOfRect diceDetections = new MatOfRect(); // Output container
    
        // See syntax for explainations on addition parameters
        diceCascade.detectMultiScale(image, diceDetections, 1.1, 4, 0, new Size(20, 20),
            new Size(38, 38));
        
        // 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();
            
            pipCascade.detectMultiScale(image.submat(diceRect), pipDetections, 1.01, 4, 0,
                new Size(2, 2), new Size(10, 10));
            
            // Gets the number of detected pips and draws a cricle around the ROI
            for (int y = 0; y < pipDetections.toArray().length; y++) {
                // Provides the relative position of the pips to the dice ROI
                Rect pipRect = pipDetections.toArray()[y];
                
                // See syntax explaination
                // Draws a circle around our pips
                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);
            }
        }
        
        return image;
    }
}

De functie getNextImage() retourneert een Mat object, dat samen met de andere geposte voorbeelden constant kan worden aangeroepen en kan worden geconverteerd naar een BufferImage , om een livestream te bieden die detecties BufferImage .



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow