Dies ist eine Fortsetzung von Letztes Mal.
Die Funktion "cv2.putText ()", die Text in OpenCV beschreibt, kann kein Japanisch verwenden. Da es mit PIL möglich ist, gibt es im Web viele Methoden, die PIL nur für diesen Teil verwenden, aber ich habe eine einzigartige Funktion veröffentlicht, die eine Alternative zu "cv2.putText ()" sein kann, nur weil ich es vorerst versucht habe. Es gab keinen Platz. Also habe ich es selbst gemacht. Es tut mir leid, wenn es eine Standardmethode gibt, nur weil meine Suchfähigkeiten gering sind.
Ausführung: OpenCV 4.1.2.30 Pillow 7.0
(x, y)
an.Das Ziel ist ein ImageDraw.Draw-Objekt, das aus einem PIL-Image erstellt wurde.
(x, y)
an.\ n
sind ebenfalls in Ordnung.cv2.putText ()
ist ein aussagekräftiges Argument, da es sich um eine Vektorschrift handelt. Es spielt keine Rolle, ob es nicht in PIL ist.
Ansonsten scheint es möglich zu sein, "cv2.putText ()" durch "ImageDraw.text ()" zu ersetzen.cv2.imshow ()
kann nicht verwendet werden Google Colab hat eine eigene Funktion ** cv2_imshow () **.
Anschließend haben wir die ursprüngliche Funktion, die japanische Schriftarten beschreibt, in OpenCV ** cv2_putText () ** benannt.
Bereiten Sie zunächst zwei Funktionen vor. Dies ist eine Funktion, die OpenCV und PIL konvertiert, die ich in [diesem Artikel] geschrieben habe (https://qiita.com/mo256man/items/a2bfdf2393953314fa39).
python
import numpy as np
import cv2
from PIL import Image, ImageDraw, ImageFont
def pil2cv(imgPIL):
imgCV_RGB = np.array(imgPIL, dtype = np.uint8)
imgCV_BGR = np.array(imgPIL)[:, :, ::-1]
return imgCV_BGR
def cv2pil(imgCV):
imgCV_RGB = imgCV[:, :, ::-1]
imgPIL = Image.fromarray(imgCV_RGB)
return imgPIL
python
def cv2_putText_1(img, text, org, fontFace, fontScale, color):
x, y = org
b, g, r = color
colorRGB = (r, g, b)
imgPIL = cv2pil(img)
draw = ImageDraw.Draw(imgPIL)
fontPIL = ImageFont.truetype(font = fontFace, size = fontScale)
draw.text(xy = (x,y), text = text, fill = colorRGB, font = fontPIL)
"""
Ich werde es später hier hinzufügen
"""
imgCV = pil2cv(imgPIL)
return imgCV
Es ist dasselbe wie bei vielen Vorgängern, ein PIL-Bild einmal zu erstellen, japanischen Text darauf zu zeichnen und es dann in ein OpenCV-Bild zurückzugeben, jedoch cv2.putText (img, Text, org, fontFace, fontScale, Farbe, Dicke) Die Funktion ist, dass es auf die gleiche Weise wie
verwendet werden kann.
Wenn Sie sagen "Ich möchte Japanisch verwenden, aber die Schriftart und Größe sind fest", können Sie natürlich die Standardargumente festlegen.
Vergleichen wir die Ausgabeergebnisse von cv2.putText ()
und cv2_putText ()
.
python
import numpy as np
import cv2
from PIL import Image, ImageDraw, ImageFont
def pil2cv(imgPIL):
#Die oben aufgeführten
def cv2pil(imgCV):
#Die oben aufgeführten
def cv2_putText_1(img, text, org, fontFace, fontScale, color):
#Die oben aufgeführten
def main():
img = np.full((200,400,3), (160,160,160), dtype=np.uint8)
#Normalerweise cv2.putText()Zeichnen Sie Text mit
text = "OpenCV"
x, y = 50, 100
fontCV = cv2.FONT_HERSHEY_SIMPLEX
fontScale = 1
colorBGR = (255,0,0)
thickness = 1
cv2.putText(img = img,
text = text,
org = (x,y),
fontFace = fontCV,
fontScale = fontScale,
color = colorBGR,
thickness = thickness)
"""
Ich werde es später hier hinzufügen
"""
#Zeichnen Sie japanischen Text mit Ihrer eigenen Funktion
text = "Japanisch auch\n möglich"
x, y = 200,100
fontPIL = "Dflgs9.TTC" #DF Reiga Song
size = 40
colorBGR = (255,0,0) # cv2.putText()Wie bei, definiert in der Reihenfolge der BGR
img = cv2_putText_1(img = img,
text = text,
org = (x,y),
fontFace = fontPIL,
fontScale = size,
color = colorBGR)
cv2.imshow("cv2_japanese_test", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
Das Ergebnis ist dies.
Die y-Koordinaten sollten den gleichen Wert haben, aber die Höhen sind ausgeschaltet. Dies liegt daran, dass, wie ich im Überprüfungsabschnitt geschrieben habe, * org * in cv2.putText ()
unten links und * xy * in ImageDraw.text ()
oben rechts angibt.
Lassen Sie es uns verarbeiten, damit Sie es verstehen können.
python
# cv2_putText_1()Fügen Sie der Kommentarzeile von Folgendes hinzu
w, h = draw.textsize(text, font = fontPIL)
draw.rectangle([(x,y), (x+w,y+h)], outline = (255,0,0), width = 1)
draw.ellipse([(x-3,y-3), (x+3,y+3)], None, (255,0,0), 1)
# main()Fügen Sie der Kommentarzeile von Folgendes hinzu
(w, h), b = cv2.getTextSize(text = text,
fontFace = fontCV,
fontScale = fontScale,
thickness = thickness)
pt1 = (x, y - h)
pt2 = (x + w, y + b)
cv2.rectangle(img, pt1, pt2, (0,0,255), 1)
cv2.circle(img, (x,y), 5, (0,0,255))
Das Ergebnis ist dies.
Im vorherigen Artikel habe ich nicht die von cv2.getTextSize ()
erhaltene Grundlinie verwendet, aber diesmal habe ich versucht, ein Quadrat einschließlich dieser zu zeichnen.
Ich bin mir nicht sicher, warum die PIL-Quadrate nicht subtil zum japanischen Text passen. Möglicherweise ist der von dieser Person erwähnte Fehler verwandt.
Um Ihre eigene Funktion mit * org * in cv2.putText ()
kompatibel zu machen, müssen Sie diesen Teil ändern.
Hier ist eine modifizierte Version des Höhenstandards.
python
def cv2_putText_2(img, text, org, fontFace, fontScale, color):
x, y = org
b, g, r = color
colorRGB = (r, g, b)
imgPIL = cv2pil(img)
draw = ImageDraw.Draw(imgPIL)
fontPIL = ImageFont.truetype(font = fontFace, size = fontScale)
w, h = draw.textsize(text, font = fontPIL)
draw.text(xy = (x,y-h), text = text, fill = colorRGB, font = fontPIL)
imgCV = pil2cv(imgPIL)
return imgCV
Sie können ein Bild wie dieses erhalten, indem Sie "cv2_putText_1" in "main ()" in "cv2_putText_2" ändern. Ähnlich wie bei "cv2.putText ()" konnte ich den Text durch Angabe der unteren linken Ecke zeichnen.
Ich mag jedoch nicht die Angabe, dass * org * unten links in cv2.putText ()
angibt, daher bevorzuge ichcv2_putText_1 ()
.
Wenn Sie die Schriftart und Schriftgröße mit "cv2.putText ()" angeben, wird die Größe des zu zeichnenden Textes bestimmt. Wenn Sie die entsprechende Größe mit der angegebenen Schriftart basierend darauf berechnen, können Sie das vorhandene Programm wie in hier gezeigt mit minimalen Änderungen ändern. Sie können zur TrueType-Schriftart wechseln! Ich dachte, aber ich hörte auf, weil es mühsam war. ..
Wenn Sie es zu einer Funktion machen, können Sie japanische Schriftarten auf die gleiche Weise wie "cv2.putText ()" verwenden. Es war eine Geschichte. Beachten Sie jedoch, dass Japanisch im Fensternamen "cv2.imshow ()" oder im Dateinamen "cv2.imwrite ()" nicht verfügbar ist.
Wie können wir übrigens ein "(b, g, r)" aus dem "(r, g, b)" Taple erstellen? In meiner Funktion nehme ich diesmal jedes Element heraus und ändere die Reihenfolge, um einen neuen Taple zu erstellen, aber es ist keine elegante Lösung. Sie könnten die Taples in eine Liste konvertieren, die Reihenfolge umkehren und sie dann wieder in Taples konvertieren, aber das ist alles andere als elegant.
python
r, g, b = 0, 128, 255
RGB = (r, g, b)
BGR = tuple(list(RGB)[::-1])
print (RGB) # (0, 128, 255)
print (BGR) # (255, 128, 0)
Bitte lassen Sie mich wissen, ob es eine gute Möglichkeit gibt, Aha zu erleben, z. B. "img [:,:, :: -1]", wenn Sie ein RGB-Bild in BGR konvertieren.
Recommended Posts