[PYTHON] Zeichnen Sie Figuren mit OpenCV und PIL

Einführung

Wenn Sie ein Konservenpapier herstellen, werden Sie es dabei verstehen. Dies ist ein Artikel für mich. Ich wollte einen Artikel schreiben, der sich auf OpenCV spezialisiert hat, aber aus irgendeinem Grund musste ich auch über PIL schreiben. Einige Argumente werden weggelassen.

OpenCV

Erstellen Sie ein monochromes Basisbild numpy.full (Form, Füllwert, Typ)

Da die Bilddaten von OpenCV ein Numpy-Array sind, können Sie mit np.full () ein monochromes Bild erstellen. Im Falle eines schwarzen Hintergrunds kann ich etwas einfacher schreiben, aber ich werde es weglassen, weil es nicht ausreicht, sich einzeln zu erinnern.

Zeichne eine Figur

Die folgende Funktion verarbeitet das angegebene Bild. Was bedeutet das? img = cv2.line(img, ...) Und der Rückgabewert muss nicht selbst neu zugewiesen werden cv2.line(img, ...) Der Wert von "img" ändert sich nur durch Schreiben. Wenn Sie dies nicht möchten, müssen Sie das Originalbild als separates Objekt kopieren. Aus diesem Grund habe ich in diesem Artikel "img_rect = img_origin.copy ()" festgelegt.

Zeichnen Sie eine Linie cv2.line (img, pt1, pt2, Farbe, Dicke)

Zeichnen Sie ein quadratisches cv2.rectangle (img, pt1, pt2, Farbe, Dicke)

Zeichne einen Kreis cv2.circle (Bild, Mittelpunkt, Radius, Farbe, Dicke)

Verwenden Sie cv2.ellipse (), um einen Bogen zu zeichnen.

Zeichnen Sie eine Ellipse oder einen Bogen cv2.ellipse (Bild, Mitte, Achsen, Winkel, Startwinkel, Endwinkel, Farbe, Dicke).

Der Winkel kann eine kleine Zahl sein. Außerdem ist die Drehrichtung von der x-Achse zur y-Achse positiv. Mathematische xy-Koordinaten sind gegen den Uhrzeigersinn, aber im Computerkoordinatensystem ist die y-Achse nach unten gerichtet, sodass sie gegen den Uhrzeigersinn positiv ist. Mit anderen Worten, so etwas. ellipse.png

Nun, selbst wenn ich bisher schreibe, werde ich es sowieso nicht benutzen.

Zeichnen Sie ein Polygon cv2.polylines (img, pts, isClosed, Farbe, Dicke)

Das Schreiben von * pts * ist kompliziert, aber Sie müssen es beherrschen, um mit der Konturerkennung zu spielen. Lassen Sie uns also unser Bestes tun, um uns daran zu erinnern. Im folgenden Beispielprogramm ist eine selbst erstellte Funktion enthalten, mit der dieselbe Figur mehrmals gezeichnet werden kann. Wurden Sie von der PEP-Polizei verhaftet, wenn Sie den Raum genutzt haben, um sie auszurichten?

polylines_test.py


import numpy as np
import cv2

###Funktion zum Versetzen der Koordinaten
# [(x1,y1), (x2,y2)]Wann(a,b)Von[(x1+a,y1+b), (x2+a, y2+b)]machen
def position_offset(pos, offset):
    np_newpos = np.array(pos) + np.array(offset)
    list_newpos = list(map(tuple, np_newpos.tolist()))
    return list_newpos


###Erstellen Sie ein monochromatisches Basisbild
imgCV = np.full((180,200,3), (128,128,128), dtype = np.uint8)

###Machen Sie 3 gleiche Faltlinien
pos = [(10,10), (80,60), (80,10), (60,30)]
offset1 = (  0,  0)
offset2 = (100, 40)
offset3 = (100,100)
pts1 = np.array(position_offset(pos, offset1))
pts2 = np.array(position_offset(pos, offset2))
pts3 = np.array(position_offset(pos, offset3))

###Zeichnen Sie ein Polygon
#Zeichnen Sie ein Polygon
cv2.polylines(imgCV, [pts1]      , True, (255,0,0), 3)

#Zeichnen Sie mehrere Polygone gleichzeitig
cv2.polylines(imgCV, [pts2, pts3], True, (0,0,255), 3)

cv2.imshow("polylines", imgCV)
cv2.waitKey(0)
cv2.destroyAllWindows()

Das Ergebnis ist dies. CV_test.png

Füllen Sie das Polygon cv2.fillPoly (img, pts, color)

Füllen Sie Polygone genau mit Aussparungen. Wikipedia hat einen Artikel namens Concave Square In der Enzyklopädie für Kinder, die ich vor langer Zeit gelesen habe, hieß sie "Arrow's Negata".

Füllen Sie das konvexe Polygon cv2.fillConvexPoly (Bild, Punkte, Farbe).

Wenn Sie wissen, dass es sich um ein konvexes Polygon handelt, können Sie es schneller verwenden. Wenn Sie dies mit einem konkaven Polygon verwenden, wird kein Fehler verursacht, es bleiben jedoch unbemalte Bereiche zurück.

Zeichne Zeichen cv2.putText (img, text, org, fontFace, fontScale, Farbe, Dicke)

Schriftarten, die mit cv2.putText () verwendet werden können

Die folgenden 8 Typen können verwendet werden. HERSHEY ist keine Schokolade, sondern eine von Dr. Hercy entwickelte Vektorschrift.

Durch Kombinieren mit cv2.FONT_ITALIC (da es sich um eine integrierte Konstante handelt, fügen Sie sie hinzu) kann es schräg gestellt werden.

Finden Sie die Breite und Höhe des Textes cv2.getTextSize (Text, fontFace, fontScale, Dicke)

Verwenden Sie diese Funktion, wenn Sie den Text in der Mitte der Abbildung platzieren möchten. Es gibt zwei Ausgänge. Die Größe des durch "(Breite, Höhe)" dargestellten Textes und die y-Koordinate der Grundlinie vom niedrigsten Punkt der Zeichenfolge aus gesehen. Letzteres ist dasjenige, das unten herausspringt, wie "y" und "p".

Beispiel für eine Charakterdarstellung

putText_test.py


import numpy as np
import cv2

fonts=[cv2.FONT_HERSHEY_SIMPLEX,
       cv2.FONT_HERSHEY_PLAIN,
       cv2.FONT_HERSHEY_DUPLEX,
       cv2.FONT_HERSHEY_COMPLEX,
       cv2.FONT_HERSHEY_TRIPLEX,
       cv2.FONT_HERSHEY_COMPLEX_SMALL,
       cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,
       cv2.FONT_HERSHEY_SCRIPT_COMPLEX]

#Erstellen Sie ein monochromatisches Basisbild
img = np.full((360,600,3), (255,255,255), dtype = np.uint8)

for i, font in enumerate(fonts):
    for j in range(2):
        for k in range(2):
            x, y = 200*(j+1)*k+10, i*40+50
            fnt = font if j == 0 else font + cv2.FONT_ITALIC
            text = "sample_{}".format(fnt)
            cv2.putText(img,
                        text = text,
                        org = (x, y),
                        fontFace = fnt,
                        fontScale = 1,
                        color = (0, 0, 255*j),
                        thickness=1)

            #Basislinie unbenutzt
            (w, h), _ = cv2.getTextSize(text = text,
                                        fontFace = fnt,
                                        fontScale = 1,
                                        thickness = 1)
            cv2.rectangle(img, (x, y), (x+w, y-h), (255, 0, 0))
            cv2.circle(img, (x, y), 3, (255, 0, 0))

cv2.imshow("hershey fonts",img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Die mittlere Spalte ist eine normale Schriftart und die rechte Spalte ist kursiv. Die linke ist eine Zusammensetzung der beiden. Es gibt einige Schriftarten, die nicht kursiv wirken.

cv_fonts.png

PIL

Erstellen Sie ein monochromes Basisbild Image.new (Modus, Größe, Farbe)

Zeichne eine Figur

Um eine Figur auf ein Bild zu zeichnen, erstellen Sie ein ImageDraw.Draw-Objekt anstelle des Bildes selbst und zeichnen Sie darauf.

Zeichnen Sie eine Linie (gefaltete Linie) ImageDraw.line (xy, Füllung, Breite, Verbindung)

Wahrscheinlich ein Fehler, aber bei Verwendung von "Joint =" Kurve "" muss die Beschreibung der Koordinatengruppe "xy = [(x1, y1), (x2, y2), ...]" sein. Wenn "xy = [x1, y1, x2, y2, ...]", tritt ein Fehler auf. Wenn Sie eine Faltlinie mit der Standardfarbe zeichnen, ohne * füllen * zu setzen, ist die Kurvenverarbeitung zur Hälfte abgeschlossen.

Zeichnen Sie ein Quadrat ImageDraw.rectangle (xy, Füllung, Umriss, Breite)

Zeichnen Sie einen Kreis (Ellipse) ImageDraw.ellipse (xy, Füllung, Umriss, Breite)

Ich habe mich gefragt, warum es solche Spezifikationen hat, aber als ich darüber nachdachte, gab es viele Zeichensoftware mit solchen Spezifikationen.

Zeichnen Sie ein Polygon ImageDraw.polygon (xy, Füllung, Umriss)

Wenn Sie die Linie und das Rechteck kennen, können Sie es beherrschen. Derzeit kann die Linienbreite nicht angegeben werden und ist auf 1 festgelegt.

Andere

PIL.ImageDraw.ImageDraw.point (* xy *, * fill ), um (mehrere) Punkte zu zeigen ImageDraw.arc ( xy *, * start *, * end *, * fill *, * width ) ImageDraw.chord ( xy *, * start *, * end *, * fill *, * umriss *, * width ) ImageDraw.pieslice ( xy *, * Start *, * Ende *, * Füllung *, * Umriss *, * Breite *) kann zum Zeichnen einer Fächerform (Bogen + Radius) verwendet werden. Die Winkeleinheit ist Grad, die wie cv2.ellipse () von OpenCV ab 3 Uhr im Uhrzeigersinn zunimmt.

Buchstaben zeichnen

Die Methode zum Zeichnen von PIL-Zeichen verwendet die Schriftart auf dem PC, sodass auch Japanisch verwendet werden kann.

Zeichen zeichnen ImageDraw.text (xy, Text, Füllung, Schriftart)

Geben Sie die Zeichenschrift ImageFont.truetype (Schriftart, Größe) an.

Finden Sie die Breite und Höhe des Textes ImageDraw.textsize (Text, Schriftart)

Im Gegensatz zu cv2.getTextSize () ist die Ausgabe nur "(Breite, Höhe)".

PIL-Probe

Es ist eine Menge Dinge geworden. Auch hier wird die selbst erstellte Funktion position_offset () verwendet.

PIL_test.py


import numpy as np
from PIL import Image, ImageDraw, ImageFont

###Funktion zum Versetzen der Koordinaten
# [(x1,y1), (x2,y2)]Wann(a,b)Von[(x1+a,y1+b), (x2+a, y2+b)]machen
def position_offset(pos, offset):
    np_newpos = np.array(pos) + np.array(offset)
    list_newpos = list(map(tuple, np_newpos.tolist()))
    return list_newpos


###Erstellen Sie ein monochromatisches Basisbild
imgPIL = Image.new("RGB", (640,480), (128,128,128))

###Erstellen Sie ein Draw-Objekt
draw = ImageDraw.Draw(imgPIL)

###Gestrichelten Linie
pos = [(10,10), (80,60), (80,10), (60,30)]

### line
for i in range(6):
    # y=0 : joint =Gefaltete Linie, wenn Keine eingestellt ist und die Füllung weggelassen wird.
    draw.line(xy = position_offset(pos,(100*i,0)),
              width = i*5,
              joint = None)

    # y=100 : joint = "curve"Gebogene Linie wenn
    draw.line(xy = position_offset(pos,(100*i,100)),
              fill = (0,255,255),
              width = i*5,
              joint = "curve")

    # y=Rechtes Ende von 200:Verbindung ohne Angabe der Füllung= "curve"Verhalten wenn
    #Es muss sich nicht in der for-Schleife befinden, aber ich habe es hier eingefügt, um den Vergleich zu erleichtern.
    draw.line(xy = position_offset(pos,(100*5,200)),
              width = 25,
              joint = "curve")
    

###Selbst wenn dieselbe Koordinatengruppe wie die Polygonlinie verwendet wird, wird sie zu einem geschlossenen Polygon.
#Geben Sie die Füllung an
draw.polygon(xy = position_offset(pos,(0,200)),
             fill = (255,0,0))

#Gliederung angeben
draw.polygon(xy = position_offset(pos,(100,200)),
             outline = (0,255,0))

#Geben Sie Füllung und Gliederung an
draw.polygon(xy = position_offset(pos,(200,200)),
             fill = (255,0,0),
             outline = (0,255,0))


###Rechteck und Ellipse
pos=[(10,0), (200,70)] #Lassen Sie uns die Reihenfolge der beiden Punkte ändern
for i in range(3):
    draw.rectangle(xy = position_offset(pos,(200*i,300)),
                   fill = None,
                   outline = (0,0,255),
                   width = i*5) #width kann 1 sein, auch wenn es 0 ist

    draw.ellipse(xy = position_offset(pos,(200*i,300)),
                 fill = (255,255,0),
                 outline = (0,255,0),
                 width = i*5)

###Bogen, Akkord und Pieslice
start, end = 45, 300
#Bogen Bogenumriss wird abgekürzt
draw.arc(xy = position_offset(pos,(0,400)),
         start = start,
         end = end,
         width = 4)

#Akkordfolge
draw.chord(xy = position_offset(pos,(200,400)),
           start = start,
           end = end,
           fill = (255,0,0),
           outline = (0,255,0))

#Pieslice fächerförmig
draw.pieslice(xy = position_offset(pos,(400,400)),
              start = start,
              end = end,
              fill = (255,0,0),
              outline = (0,255,0))


###Buchstaben zeichnen
#Zeichnen Sie Zeichen mit minimalen Einstellungen
draw.text(xy = (520,190),
          text = "bug? -> ")

#Zeichnen Sie Zeichen in der angegebenen Schriftart
#Die Schriftart war DF Reiga Song
font = ImageFont.truetype(font="Dflgs9.TTC",
                          size=30)
draw.text(xy = (440,250),
          text = "Fehler? →",
          fill = (0,0,0),          
          font = font)

###Bild anzeigen
imgPIL.show()

Das Ergebnis ist dies. PIL_test.png

Am Ende

Vielen Dank an teratail für die Erstellung meiner eigenen Funktion position_offset (). Vielen Dank. https://teratail.com/questions/234513

Vorschau beim nächsten Mal

Ich möchte Japanisch in OpenCV anzeigen. Zu diesem Zweck sollte PIL nur für diesen Teil verwendet werden. Es gibt viele solcher Artikel im Internet, aber ich bin nicht zufrieden mit ihnen. Ich werde meine Vorfahren nicht entlassen, aber ich möchte eine praktischere Funktion schaffen.

Recommended Posts

Zeichnen Sie Figuren mit OpenCV und PIL
Neuronales Netzwerk mit OpenCV 3 und Python 3
Zeichnen Sie eine Illustration mit Python + OpenCV
Zeichnen Sie einen Pfeil (Vektor) mit opencv / python
Zeichnen Sie eine Aquarellillusion mit Kantenerkennung in Python3 und openCV3
Bilder mit Pupil, Python und OpenCV aufnehmen
Zeichnen Sie mit ArcPy eine Figur auf dem Feature-Layer
Hallo Welt- und Gesichtserkennung mit OpenCV 4.3 + Python
Installieren Sie OpenCV 4.0 und Python 3.7 unter Windows 10 mit Anaconda
Wavelet-Konvertierung von Bildern mit PyWavelets und OpenCV
Feature Matching mit OpenCV 3 und Python 3 (A-KAZE, KNN)
PIL-Installation mit Pip
Katze zurück mit OpenCV erkennen
Zeichnen Sie eine erdähnliche Flussanimation mit Matplotlib und Cartopy
Ermitteln Sie den Tragezustand der Maske mit OpenCV und Raspberry Pi
So schleifen und spielen Sie ein GIF-Video mit openCV ab
Sprites mit OpenCV drehen
Ubuntu 20.04 auf Himbeer-Pi 4 mit OpenCV und mit Python verwenden
RaspberryPi Zero und OpenCV
Datenerweiterung mit openCV
[Python] Webkamera-Rahmengröße und FPS-Einstellungen mit OpenCV
Laden / Anzeigen und Beschleunigen von GIF mit Python [OpenCV]
Fehlerbehebung bei der Installation von OpenCV auf Raspberry Pi und der Erfassung
Mit und ohne WSGI
Einfache TopView mit OpenCV
Stolpern Sie mit opencv3 von Homebrew
Bildverarbeitung mit PIL
Trennen Sie Farbbilder in RGB-Bilder und zeigen Sie sie mit OpenCV an
Erstellen Sie eine WEB-Überwachungskamera mit Raspberry Pi und OpenCV
Die Geschichte der Anzeige von Bildern mit OpenCV oder PIL (nur)
Konvertieren Sie Videos mit ffmpeg + python + opencv in Schwarzweiß
Programmieren mit Python und Tkinter
Zeichnen Sie die Bezier-Kurve mit Go
Ver- und Entschlüsselung mit Python
Arbeiten Sie mit tkinter und Maus
Bildverarbeitung mit PIL (Pillow)
Gesichtserkennung mit OpenCV von Python
Zeichnen Sie mit NetworkX ein Diagramm
"Apple-Verarbeitung" mit OpenCV3 + Python3
Python und Hardware-Verwenden von RS232C mit Python-
Zeichne Hallo Welt mit mod_wsgi
Versuchen Sie die Kantenerkennung mit OpenCV
Bildbearbeitung mit Python OpenCV
Kameraerfassung mit Python + OpenCV
[Python] Verwenden von OpenCV mit Python (Basic)
Binarisieren Sie Fotodaten mit OpenCV
Echtzeit-Kantenerkennung mit OpenCV
Gesichtserkennung mit Python + OpenCV
Holen Sie sich Bildfunktionen mit OpenCV
Super Auflösung mit SRGAN und ESRGAN
Group_by mit sqlalchemy und sum
Gesichtserkennung / Schneiden mit OpenCV
Python mit Pyenv und Venv
Probieren Sie OpenCV mit Google Colaboratory aus
Zeichnen Sie mit networkx ein Diagramm
Mit mir, NER und Flair
Verwenden von OpenCV mit Python @Mac
Anwendungen mit PyOpenCL (PIL & PyOpenGL)
Bilderkennung mit Keras + OpenCV
Funktioniert mit Python und R.