[PYTHON] Suchen Sie mit opencv nach phasenidentischen zusammengesetzten Wörtern

Einführung

Kennen Sie ein Kartenspiel namens Topolo Memory? Es ist ein Spiel, bei dem Sie um die Karte kämpfen, wenn Sie eine Figur derselben Phase auf einer Karte finden. Als ich dieses Spiel mit einem Freund gespielt habe, habe ich ein Spiel hinzugefügt, um nach Redewendungen in derselben Phase zu suchen. Daher werde ich die Lösung mit Hilfe von opencv analysieren.

Umgebung

OS:macOSX Python: 3.6.8 opencv: 4.0.0.21 numpy: 1.15.0

meint

Verwenden Sie das Mecab-Wörterbuch als Wörterbuch. Suche aus allen Nomenklaturwörterbüchern (228297).

Extraktion

Öffnen Sie die CSV-Dateien nacheinander und extrahieren Sie nur die Schlüsselwörter. In numpy.array konvertieren und dann in Scheiben schneiden. Verbinden Sie all dies.

csvnoun.py


import csv
import codecs
import numpy as np
from functools import reduce
csvs = [
    "Noun.csv",
    "Noun.adjv.csv",
    "Noun.adverbal.csv",
    "Noun.demonst.csv",
    "Noun.nai.csv",
    "Noun.name.csv",
    "Noun.number.csv",
    "Noun.org.csv",
    "Noun.others.csv",
    "Noun.place.csv",
    "Noun.proper.csv",
    "Noun.verbal.csv"
]
filedelimitor = "~/mecab-ipadic-2.7.0-20070801/"
def csv_1(csv_file):
    with codecs.open(filedelimitor+csv_file, "r","euc_jp") as f:
        reader = csv.reader(f)
        csv_words = [k for k in reader]
        csv_words_np = np.array(csv_words)
        return(csv_words_np[:,0].tolist())

words = reduce(lambda x,y:x+y,[csv_1(k) for k in csvs])
print(words[0:10])
print("Menge:",len(words))

In der Handumgebung dauert es ungefähr 2 Sekunden.

Generieren

Da es schwierig ist, japanische Zeichen mit opencv auszugeben, wird es mit Kissen generiert.

char_img.py


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

img = Image.new("L",(500, 500),"white")
char = "Ah"
jpfont = ImageFont.truetype("/System/Library/Fonts/Hiragino Kaku Gothic W4.ttc",500)
draw = ImageDraw.Draw(img)
draw.text((0,0),char,font=jpfont,fill="black")
img_cv = np.array(img,dtype=np.uint8)

Wenn Sie es unter einem anderen Betriebssystem als OSX ausführen möchten, ändern Sie jpfont in eine geeignete Schriftart.

Analyse

Da opencv eine Funktion namens cv2.findContours hat, verwenden Sie diese. Eine Funktion, die die Kontur eines Binärbilds erkennt. (Referenz: http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_contours/py_contours_begin/py_contours_begin.html) Wenn das Flag (zweites Argument) auf RETR_TREE gesetzt ist, behält die Hierarchie die gesamte hierarchische Struktur bei. Verwenden Sie diese hierarchische Struktur. Hierarchie wird in der Struktur [Next, Previous, First_Child, Parent] gespeichert. Von diesen wird nur ein Elternteil verwendet, da die Struktur durch Untersuchen aller Eltern gefunden werden kann. Die Suche mit First_child und Next erfordert weniger Berechnung, aber selbst komplizierte Zeichen überschreiten nicht 20 Teile, sodass wir alle suchen. Da cv2.findContours den Hintergrund auf 0 setzt, ist die mit 0 als Kind die äußerste Zeile. Da der Linienteil ein gerades übergeordnetes Element hat, zählen Sie die Elemente mit einem geraden Index als übergeordnetes Element. Schließlich konvertiert es die Zeichenfolge zeichenweise, verkettet sie und sortiert sie und gibt sie zur Suche zurück.

string_topology.py


topology_dic = {}
jpfont = ImageFont.truetype("/System/Library/Fonts/Hiragino Kaku Gothic W4.ttc",500)

def char_topology(char):
    if char in topology_dic:
        return topology_dic[char]
    else:
        img = Image.new("L",(500, 500),"white")
        draw = ImageDraw.Draw(img)
        draw.text((0,0),char,font=jpfont,fill="black")
        img_cv = np.array(img,dtype=np.uint8)
        ret,thresh = cv2.threshold(img_cv,127,255,0)
        contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
        img_cv_con = np.zeros((500,500,3),np.uint8)
        cv2.drawContours(img_cv_con,contours,-1,(0,255,0),3)
        parent = [k[3] for k in hierarchy[0]]
        topology = [parent.count(k)
                    for k in range(len(parent)) if parent[k]%2 == 0]
        topology_dic[char] = topology
        return topology

def string_topology(string):
    topology = reduce(lambda x,y:x+y,[char_topology(k) for k in string])
    topology.sort()
    return topology

Suche

Konvertiert die Listenzeichenfolge in eine Topologie und gibt eine Übereinstimmung aus.

search.py


in_topology = string_topology(sys.argv[1])
print(in_topology)
for k in words:
    if in_topology == string_topology(k):
        print(k)

Code

Wenn Sie alle verbinden, sieht es so aus.

same_topology.py


import cv2
import os
from PIL import Image, ImageDraw, ImageFont
import numpy as np
from functools import reduce
import csv
import codecs
import sys

csvs = [
    "Noun.csv",
    "Noun.adjv.csv",
    "Noun.adverbal.csv",
    "Noun.demonst.csv",
    "Noun.nai.csv",
    "Noun.name.csv",
    "Noun.number.csv",
    "Noun.org.csv",
    "Noun.others.csv",
    "Noun.place.csv",
    "Noun.proper.csv",
    "Noun.verbal.csv"
]
filedelimitor = "~/mecab-ipadic-2.7.0-20070801/"
def csv_1(csv_file):
    with codecs.open(filedelimitor+csv_file, "r","euc_jp") as f:
        reader = csv.reader(f)
        csv_words = [k for k in reader]
        csv_words_np = np.array(csv_words)
        return(csv_words_np[:,0].tolist())

words = reduce(lambda x,y:x+y,[csv_1(k) for k in csvs])

topology_dic = {}
jpfont = ImageFont.truetype("/System/Library/Fonts/Hiragino Kaku Gothic W4.ttc",500)

def char_topology(char):
    if char in topology_dic:
        return topology_dic[char]
    else:
        img = Image.new("L",(500, 500),"white")
        draw = ImageDraw.Draw(img)
        draw.text((0,0),char,font=jpfont,fill="black")
        img_cv = np.array(img,dtype=np.uint8)
        ret,thresh = cv2.threshold(img_cv,127,255,0)
        contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
        img_cv_con = np.zeros((500,500,3),np.uint8)
        cv2.drawContours(img_cv_con,contours,-1,(0,255,0), 3)
        parent = [k[3] for k in hierarchy[0]]
        topology = [parent.count(k)
                    for k in range(len(parent)) if parent[k]%2 == 0]
        topology_dic[char] = topology
        return topology

def string_topology(string):
    topology = reduce(lambda x,y:x+y,[char_topology(k) for k in string])
    topology.sort()
    return topology



in_topology = string_topology(sys.argv[1])
print(in_topology)
for k in words:
    if in_topology == string_topology(k):
        print(k)

Ausgabeergebnis


$ python topology.py Tokio
[0, 0, 0, 1, 4]
Gegrillte Spieße
Lotus stehen
Nimm einen Hintern
Ast
Extraktion
Summe
Schönes Kind
Erreichen
zukünftige Angelegenheiten
Fall
Koitus
Feuerwehrauto
Feinheit
Geld zurück
Schließe
riesiges Projektil
...

Ein zusammengesetztes Wort, das dieselbe Phase wie das erste Argument hat, wird ausgegeben. In der Handumgebung wird es in ca. 30 Sekunden ausgegeben.

Ergänzung

Dieses Mal haben wir die Tofu-Zeichen nicht verarbeitet, aber es sollte so sein (ich denke, dass das ipa-Wörterbuch ausgegeben werden kann, ohne Tofu zu werden ...). Es wurde darauf hingewiesen, dass "Zeiten" und "Loro" möglicherweise nicht vom gleichen Typ sind, aber unter dem Gesichtspunkt der Kontinuität sollten sie vom gleichen Typ sein. ~~ Vielleicht. ~~ (Ich glaube, ich habe keine Mathematikkenntnisse, daher würde ich es begrüßen, wenn ein Experte dies kommentieren würde.)

Recommended Posts

Suchen Sie mit opencv nach phasenidentischen zusammengesetzten Wörtern
Suchen Sie nach dem Namen der OpenCV-Funktion
Suchen Sie nach Dateien mit der angegebenen Erweiterung
Heat Map für die Rastersuche mit Matplotlib
[Python] Bilder mit OpenCV lesen (für Anfänger)
Kausales Denken und kausale Suche von Python (für Anfänger)
Sequentielle Suche mit Python
Katze zurück mit OpenCV erkennen
Binarisierung mit OpenCV / Python
[Boto3] Suchen Sie mit der List Users API nach Cognito-Benutzern
Dichotomie mit Python
Datenbank mit db.py durchsuchen
Datenerweiterung mit openCV
OpenCV für Python-Anfänger
Einfache TopView mit OpenCV
Stolpern Sie mit opencv3 von Homebrew
Gesichtserkennung mit OpenCV von Python
"Apple-Verarbeitung" mit OpenCV3 + Python3
Versuchen Sie die Kantenerkennung mit OpenCV
Suchliste nach doppelten Elementen
Erstellen / Suchen / Erstellen einer Tabelle mit PynamoDB
Bildbearbeitung mit Python OpenCV
Kameraerfassung mit Python + OpenCV
Vollbit-Suche mit Go
[Python] Verwenden von OpenCV mit Python (Basic)
OpenCV3-Installation für Python3 @macOS
Binarisieren Sie Fotodaten mit OpenCV
Suchen Sie nach Zeichenfolgen in Dateien
Loop-Video-Laden mit opencv
Vollbit-Suche mit Python
Ich kann nicht mit # google-map suchen. ..
Suchen Sie in numpy.array nach True
Holen Sie sich Bildfunktionen mit OpenCV
Gesichtserkennung / Schneiden mit OpenCV
Suchmaschinen arbeiten mit Python
Suche nach Twitter-Tweets mit Python
Probieren Sie OpenCV mit Google Colaboratory aus
Erstellung eines Kaskadenklassifikators mit opencv
Optimieren Sie die Websuche mit Python
Verwenden von OpenCV mit Python @Mac
Bilderkennung mit Keras + OpenCV
Anime-Gesichtserkennung mit OpenCV
Erstellen Sie eine gestreifte Illusion mit Gammakorrektur für Python3 und openCV3
Erstellen Sie einen Effektor für Videokonferenzen mit Spout + OpenCV + dlib (Teil 1).