Sök…


Syntax

  • CascadeClassifier cascade = new CascadeClassifier ("cascade.xml"); // Skapar en kaskadklassificering från cascade.xml
  • Mattbild = Imgcodecs.imread ("image.png"); // Konverterar image.png till ett Mat (Matrix) -objekt
  • MatOfRect-detektioner = ny MatOfRect (); // Skapar en tom MatOfRect-fil (Matrix of Rectangles) som används som utgång för våra upptäcktsklasser
  • detections.toArray (); // Returnerar en matris med Rect-objekt som kan itereras över
  • Imgproc.rectangle (bild, ny punkt (rekt.x, rekt.y), ny punkt (rekt.x + rektvidd, rät.y + rekt.höjd), ny skalär (0, 255, 0)); // Ritar en grön rektangel från den första punktens x- och y-plats till den andra punktens x- och y-plats på Mat-objektets "bild". "rect" är ett Rect-objekt som vanligtvis tillhandahålls av detections.toArray (). Använder OpenCVs Point-klass.
  • Imgcodecs.imwrite ("output.png", bild); // Skriver det modifierade Mat-objektet "image" till "output.png"
  • CascadeClassifier.detectMultiScale (bild, detektioner); // Upptäcker alla objekt i Mat-objektets "bild" och matar upp detekteringarna i MatOfRect-objektet "detektioner"
  • CascadeClassifier.detectMultiScale (bild, detektioner, skalaFactor , minNabbor , flaggor , minSize , maxSize ); // Utför en detektion med ytterligare parametrar. Se detaljerna nedan.
  • Imgproc.ellipse (bild, centrum, axlar , 0, 0, 360, ny Scalar (255, 0, 255), tjocklek , linjetyp , 0); // Ritar en ellips på bilden i center . Använder OpenCVs Point-klass.

parametrar

Parameter detaljer
skalfaktor Hur mycket bildstorleken minskar vid varje bildskala. Standard = 1.1
minNeighbors Hur många grannar en kandidatrektangel ska ha innan du väljer den som ett upptäckt objekt. Standard = 4
flaggor Legacy flaggor. I de flesta fall bör detta ställas in på 0 . Standard = 0
minSize Minsta storlek en kandidat rektangel kan vara. Detta använder OpenCV: s Size . Kan användas för att minska detekteringstiden och CPU-användningen samt för att minska falska positiver.
maxSize Maximal storlek en kandidat rektangel kan vara. Detta använder OpenCV: s Size . Kan användas för att minska detekteringstiden och CPU-användningen samt för att minska falska positiver.
axlar Använder OpenCV: s storleksklass. Definierar ellipsens bredd och höjd.
tjocklek Linjens tjocklek, i pixlar.
linjetyp Har olika parametrar. 0 är den heldragna linjen, 8 är för en 8-ansluten linje, 4 är för en 4-ansluten linje och CV_AA är för en antialiated linje. Standard = 8

Få en statisk bild, upptäcka objekt på den och mata ut resultaten.

Observera att det här exemplet använder OpenCV 3.1.

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);
    
    }
}

Rect[] returneras av diceDetections.toArray() kan itereras över. Varje Rect inne i matrisen har fyra huvudegenskaper: x , y , width och height . x och y definierar rektangelns position uppe till vänster, och width och height returnerar ett int av rektangelns bredd och höjd. Detta används när du ritar rektanglar på bilder. Imgproc.rectangle funktionens minimala nödvändiga parametrar är följande:

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

Båda Point används för positionerna i det övre vänstra hörnet och det nedre högra hörnet. Dessa positioner är båda absoluta för den bild som tillhandahålls som den första parametern, inte för varandra. Därför måste du lägga till både rektangelns x eller y position förutom width eller height att korrekt definiera end .

Observera att Point klassen som används i dessa parametrar är inte Java standard bibliotekets Point klass. Du måste importera OpenCVs Point klass istället!

Upptäcker bilder från en videoenhet

Detta exempel introducerar klassen VideoCapture , där vi använder den för att ta en bild från en webbkamera och spara den i en bild.

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.
    
    }
}

Konvertera ett Mat-objekt till ett BufferedImage-objekt

Exemplet av Daniel Baggio togs direkt från detta StackExchange-svar , men har omposterats för synlighet.

Den här klassen tar ett Mat-objekt och returnerar BufferedImage-objektet som används av javax.swing biblioteken. Detta kan användas av ett Graphics att rita bilden.

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;
}

Upptäckter inom upptäckter

Det här exemplet använder Tärningar och de svarta fläckarna på tärningarna (pips) som vårt objekt. Eftersom exemplet är ganska långt, är det avgörande för att förstå exemplet att först förklara några viktiga begrepp.

Förstå det första exemplet "Få en statisk bild, upptäcka objekt på den och mata ut resultaten." är avgörande för att förstå detta exempel, särskilt hur OpenCV drar rektanglar.

Titta på följande bild:

ange bildbeskrivning här

Vi kommer att använda subimaging-metoden, där vi använder ett detekterat område som bas för att tillämpa fler upptäckter. Detta är bara möjligt om ett objekt alltid kommer att finnas inom ett annat objekt som vi kan upptäcka, till exempel våra pips på våra tärningar. Denna metod har flera fördelar:

  • Istället för att skanna hela bilden behöver vi bara skanna det område där vi vet att objektet kommer att befinna sig.
  • Tar bort alla risker för falska positiver utanför detekteringsområdet.

Vi gör detta genom att först tillämpa en kaskadklassificeringssökning över hela bilden för att ge oss ett MatOfRect objekt som innehåller våra stora objekt (tärningar, i det här fallet). Vi itererar sedan över Rect[] -fältet som ges av toArray() från MatOfRect objektet. Detta Rect objekt används för att skapa ett tillfälligt Mat objekt som "beskärs" till Rect objektets egenskaper ( x, y, width, height ) från den ursprungliga bilden, där vi sedan kan utföra detekteringar på det temporära Mat objektet. Med andra ord säger vi klassificeringen att bara utföra detekteringar på tärningsdelarna i bilden istället, och vi anger platsen för varje tärning genom att använda Rect objekten som vi fick från att utföra en detektering på hela bilden.

Rect objekten (pips) har emellertid sina egenskaper relativt deras tärningar och inte själva bilden. För att lösa det här problemet, när vi vill dra rektanglar till den verkliga bilden visar pips positioner, lägger vi både dice.x och dice.y till 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;
    }
}

getNextImage() returnerar ett Mat objekt, som tillsammans med de andra exemplen som publiceras kan kallas ständigt och kan konverteras till en BufferImage att ge en livestream som visar detekteringar.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow