[PYTHON] Créer une fonction pour décrire les polices japonaises avec OpenCV

introduction

Ceci est une continuation de Dernière fois.

La fonction «cv2.putText ()» qui décrit le texte dans OpenCV ne peut pas utiliser le japonais. Comme c'est possible avec PIL, il existe de nombreuses méthodes sur le Web qui n'utilisent PIL que pour cette partie, mais j'ai publié une fonction unique qui peut être une alternative à cv2.putText () simplement parce que je l'ai essayé pour le moment. Il n'y avait pas de place. Alors je l'ai fait moi-même. Je suis désolé s'il existe une méthode standard simplement parce que mes compétences en recherche sont faibles.

version:  OpenCV 4.1.2.30  Pillow 7.0

la revue

Dessinez des caractères avec OpenCV cv2.putText (img, text, org, fontFace, fontScale, couleur, épaisseur)

Dessinez des caractères avec PIL ImageDraw.text (xy, text, fill, font)

La cible est un objet ImageDraw.Draw créé à partir d'une image PIL.

Cela signifie

Faites-en une fonction

cv2.imshow () ne peut pas être utilisé Google Colab a sa propre fonction ** cv2_imshow () **. Ensuite, nous avons nommé la fonction d'origine qui décrit les polices japonaises dans OpenCV ** cv2_putText () **.

Tout d'abord, préparez deux fonctions. C'est une fonction qui convertit OpenCV et PIL, que j'ai écrit dans cet article.

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

Partie 1

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)
    """
Je l'ajouterai ici plus tard
    """
    imgCV = pil2cv(imgPIL)
    return imgCV

C'est la même chose que de nombreux prédécesseurs pour créer une image PIL une fois, dessiner du texte japonais dessus, puis le renvoyer à une image OpenCV, mais cv2.putText (img, text, org, fontFace, fontScale, color, thick) La particularité est qu'il peut être utilisé de la même manière que . Bien sûr, si vous dites "Je veux utiliser le japonais, mais la police et la taille sont fixes", vous pouvez définir les arguments par défaut.

Comparons les résultats de sortie de cv2.putText () et cv2_putText ().

python


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

def pil2cv(imgPIL):
    #Ceux listés ci-dessus

def cv2pil(imgCV):
    #Ceux listés ci-dessus

def cv2_putText_1(img, text, org, fontFace, fontScale, color):
    #Ceux listés ci-dessus

def main():
    img = np.full((200,400,3), (160,160,160), dtype=np.uint8)

    #Ordinairement cv2.putText()Dessiner du texte avec
    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)
    """
Je l'ajouterai ici plus tard
    """

    #Dessinez du texte japonais avec votre propre fonction
    text = "Japonais aussi\n possible"
    x, y = 200,100
    fontPIL = "Dflgs9.TTC" #DF Reiga Song
    size = 40
    colorBGR = (255,0,0) # cv2.putText()Comme avec, défini dans l'ordre de 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()

Le résultat est le suivant. cv_jp_font_test_1.png

Les coordonnées y doivent avoir la même valeur, mais les hauteurs sont désactivées. C'est parce que, comme je l'ai écrit dans la section critique, * org * dans cv2.putText () spécifie le coin inférieur gauche, et * xy * dans ʻImageDraw.text () `spécifie le coin supérieur droit. Traitons-le pour que vous puissiez le comprendre.

python


# cv2_putText_1()Ajoutez ce qui suit à la ligne de commentaire de
    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()Ajoutez ce qui suit à la ligne de commentaire de
    (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))

Le résultat est le suivant. cv_jp_font_test_2.png

Dans l'article précédent, je n'ai pas utilisé la ligne de base obtenue par cv2.getTextSize (), mais cette fois j'ai essayé de dessiner un carré en l'incluant. Je ne sais pas pourquoi les carrés PIL ne correspondent pas subtilement au texte japonais. Peut-être que le bogue mentionné par cette personne est lié.

Quoi qu'il en soit, pour rendre votre propre fonction compatible avec * org * dans cv2.putText (), vous devez modifier cette partie.

Partie 2

Voici une version modifiée de la norme de hauteur.

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

Vous pouvez obtenir une image comme celle-ci en remplaçant cv2_putText_1 dans main () par cv2_putText_2. Similaire à cv2.putText (), j'ai pu dessiner le texte en spécifiant le coin inférieur gauche. cv_jp_font_test_3.png

Cependant, je n'aime pas la spécification que * org * spécifie en bas à gauche dans cv2.putText (), donc je préfère cv2_putText_1 ().

Partie 3

Si vous spécifiez la police et la taille de la police avec cv2.putText (), la taille du texte à dessiner est déterminée. Si vous calculez la taille appropriée avec la police spécifiée, vous pouvez modifier le programme existant comme indiqué dans ici avec une modification minimale. Vous pouvez changer de police TrueType! J'ai pensé, mais j'ai arrêté parce que c'était gênant. ..

À la fin

Si vous en faites une fonction, vous pouvez utiliser les polices japonaises de la même manière que cv2.putText (). C'était une histoire. Cependant, bien sûr, notez que le japonais n'est pas disponible dans le nom de fenêtre de cv2.imshow () ou dans le nom de fichier de cv2.imwrite ().

Au fait, comment pouvons-nous créer (b, g, r) à partir du taple (r, g, b)? Dans ma fonction cette fois, je retire chaque élément et change l'ordre pour faire un nouveau taple, mais ce n'est pas une solution élégante. Vous pouvez convertir les taples en liste, inverser l'ordre, puis les convertir à nouveau en taples, mais c'est loin d'être élégant.

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)

S'il vous plaît laissez-moi savoir s'il existe une bonne façon de faire l'expérience de aha, comme ʻimg [:,:, :: -1] `lors de la conversion d'une image RVB en BGR.

Recommended Posts

Créer une fonction pour décrire les polices japonaises avec OpenCV
Comment créer une fonction récursive
Rendre la fonction de dessin de polices japonaises dans OpenCV en général
Comment créer une caméra de surveillance (caméra de sécurité) avec Opencv et Python
J'ai essayé de créer une fonction de similitude d'image avec Python + OpenCV
Un mémorandum pour faire WebDAV uniquement avec nginx
Comment créer un dictionnaire avec une structure hiérarchique.
Je veux faire un jeu avec Python
Essayez de créer un code de "décryptage" en Python
Essayez de créer un groupe de dièdre avec Python
[Python] Comment gérer les caractères japonais avec openCV
Faire un décorateur de fonction
Faisons un outil de veille de commande avec python
[Pratique] Créez une application Watson avec Python! # 2 [Fonction de traduction]
Comment faire un jeu de tir avec toio (partie 1)
Comment appeler une fonction
Rendre avec la syntaxe facile
Faites une loterie avec Python
Faire un feu avec kdeplot
Associez Python Enum à une fonction pour la rendre appelable
Je veux créer un éditeur de blog avec l'administrateur de django
Expérimentez pour créer un PDF indépendant pour Kindle avec Python
Je veux faire une macro de clic avec pyautogui (désir)
Comment faire un simple jeu Flappy Bird avec Pygame
Je veux faire une macro de clic avec pyautogui (Outlook)
J'ai essayé de créer une caméra de surveillance à détection de mouvement avec OpenCV en utilisant une caméra WEB avec Raspberry Pi
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
Tokyo Corona: faites une prédiction simple à partir de données ouvertes avec la fonction exponentielle curve_fit
[Road to Intermediate Python] Appelez une instance de classe comme une fonction avec __call__
Rubyist a essayé de créer une API simple avec Python + bouteille + MySQL
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
[Introduction à Python] Comment fractionner une chaîne de caractères avec la fonction split
Faisons une interface graphique avec python.
Faites un son avec le notebook Jupyter
[Python 3.8 ~] Comment définir intelligemment des fonctions récursives avec des expressions lambda
Comment créer un bot slack
[3ème] J'ai essayé de créer un certain outil de type Authenticator avec python
Faisons une rupture de bloc avec wxPython
Comment faire une commande pour lire le fichier de paramètres avec pyramide
Créez un simple OMR (lecteur de feuille de marque) avec Python et OpenCV
Comment créer un robot - Avancé
Essayez de créer un type de service Web avec un langage de balisage 3D
[Python] Faire de la fonction une fonction lambda
Créer un système de recommandation avec python
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
[Introduction] Je veux créer un robot Mastodon avec Python! 【Débutants】
[Blender] Comment créer un plug-in Blender
Créer un filtre avec un modèle django
J'ai essayé de créer une application todo en utilisant une bouteille avec python
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
Faisons un graphe avec python! !!
Créer un lecteur vidéo avec PySimpleGUI + OpenCV 3 Ajout de la fonction de masque
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
Faisons un spacon avec xCAT
Comment créer un robot - Basic