Connaissez-vous un jeu de cartes appelé Topolo Memory? C'est un jeu dans lequel si vous trouvez une figure de la même phase écrite sur une carte, vous vous disputez la carte. Quand j'ai joué à ce jeu avec un ami, j'ai ajouté un jeu pour rechercher des idiomes avec la même phase, donc j'analyserai la solution de cela à l'aide d'opencv.
OS:macOSX Python: 3.6.8 opencv: 4.0.0.21 numpy: 1.15.0
Utilisez le dictionnaire mecab comme dictionnaire. Recherche dans tous les dictionnaires de nomenclature (228297).
Ouvrez les fichiers csv un par un et extrayez uniquement les mots-clés. Convertissez en numpy.array puis découpez. Connectez tout cela.
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("Quantité:",len(words))
Cela prend environ 2 secondes dans l'environnement de la main.
Comme il est difficile de sortir des caractères japonais avec opencv, il est généré avec oreiller.
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)
Si vous souhaitez l'exécuter sur un autre système que OSX, remplacez jpfont par une police appropriée.
Depuis opencv a une fonction appelée cv2.findContours, utilisez ceci. Une fonction qui détecte le contour d'une image binaire. (Référence: 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) Lorsque l'indicateur (deuxième argument) est défini sur RETR_TREE, la hiérarchie conserve toute la structure hiérarchique. Utilisez cette structure hiérarchique. la hiérarchie est stockée dans la structure [Next, Previous, First_Child, Parent]. Parmi ceux-ci, seul le parent est utilisé car la structure peut être trouvée en examinant tous les parents. La recherche à l'aide de First_child et Next nécessite moins de calculs, mais même les caractères complexes ne dépassent pas 20 parties, nous recherchons donc tout. Puisque cv2.findContours définit l'arrière-plan sur 0, celui avec 0 comme enfant est la ligne la plus externe. Puisque la partie ligne a un parent pair, comptez les éléments qui ont un index pair comme parent. Enfin, il convertit la chaîne caractère par caractère, la concatène, la trie et la renvoie pour la recherche.
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
Convertit la chaîne de liste en topologie et génère une correspondance.
search.py
in_topology = string_topology(sys.argv[1])
print(in_topology)
for k in words:
if in_topology == string_topology(k):
print(k)
Si vous les connectez tous, cela ressemblera à ceci.
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)
Résultat de sortie
$ python topology.py Tokyo
[0, 0, 0, 1, 4]
Brochettes grillées
Support de lotus
Prends un cul
Branche
Extraction
Somme
Bel enfant
Atteindre
affaires futures
Cas
coït
Voiture d'incendie
Finesse
Argent de retour
fermoir
énorme projectile
...
Un mot composé qui a la même phase que le premier argument est sorti. Dans l'environnement de la main, il sera émis dans environ 30 secondes.
Cette fois, nous n'avons pas traité les caractères tofu, mais ça devrait l'être (je pense que le dictionnaire ipa peut sortir sans devenir tofu ...). Il a été souligné que les "temps" et "loro" peuvent ne pas être du même type, mais du point de vue de la continuité, ils devraient être du même type. ~~ Peut-être. ~~ (Je pense que je n'ai pas de connaissances en mathématiques, alors j'apprécierais qu'un expert commente)
Recommended Posts