Ici, je vais essayer d'extraire des caractères des sous-titres affichés sous Masami Broadcasting. Puisqu'il n'y a pas de fond, il semble tout à fait ainsi avec la binarisation.
Il est possible d'obtenir le personnage et la position avec une précision considérable en extrayant le personnage avec l'API google cloud vision, mais ici, je vais essayer d'obtenir le personnage par d'autres méthodes.
tesseract-ocr / pyocr
Tout d'abord, essayez la reconnaissance de caractères en utilisant tesseract
et pyocr
.
Ceci est l'image source.
Extrayez les personnages et les positions avec le script ci-dessous.
import sys
import pyocr
import pyocr.builders
import cv2
from PIL import Image
def imageToText(src):
tools = pyocr.get_available_tools()
if len(tools) == 0:
print("No OCR tool found")
sys.exit(1)
tool = tools[0]
dst = tool.image_to_string(
Image.open(src),
lang='jpn',
builder=pyocr.builders.WordBoxBuilder(tesseract_layout=6)
)
return dst
if __name__ == '__main__':
img_path = sys.argv[1]
out = imageToText(img_path)
img = cv2.imread(img_path)
sentence = []
for d in out:
sentence.append(d.content)
cv2.rectangle(img, d.position[0], d.position[1], (0, 0, 255), 2)
print("".join(sentence).replace("。","。\n"))
cv2.imshow("img", img)
cv2.imwrite("output.png ", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Article 25 Tous les citoyens ont le droit de mener une vie saine et culturellement minimale.
Les deux pays doivent s’efforcer d’améliorer et de promouvoir la protection sociale, la sécurité sociale et la santé publique dans tous les aspects de la vie.
(Droit de recevoir une éducation et procédure pour recevoir]Article 26 Tous les citoyens ont le droit de recevoir une éducation égale en fonction de leurs capacités, conformément à la loi.
2 Tous les citoyens sont tenus de faire suivre à leurs enfants une éducation ordinaire, comme l'exige la loi.
L'enseignement obligatoire est gratuit.
[Droits et obligations du travail, normes des conditions de travail et interdiction de la maltraitance des enfants] Article 27 Tous les citoyens ont le droit et l'obligation de travailler.
2 Les normes relatives aux salaires, aux heures de travail, au repos et aux autres conditions de travail sont fixées par la loi.
3 Les enfants ne doivent pas l'utiliser.
Droit des travailleurs d'organisation et d'action de groupe] Article 28 Le droit d'union des travailleurs et le droit de négociation de groupe et d'autres actions de groupe sont garantis.
Droits de propriété] Article 29 Les droits de propriété ne sont pas violés.
2 Le contenu des droits de propriété est stipulé par la loi de manière à être conforme au bien-être public.
3 La propriété privée peut être utilisée pour le public moyennant une juste compensation.
Dans l'image des seuls caractères obtenus à partir de word ou html, les caractères eux-mêmes peuvent être obtenus, mais la position exacte des caractères semble difficile à obtenir. Ce que je veux ici, c'est la position en unités de phrase, mais même si je l'ajuste avec le paramètre tesseract_layout = 6
, il semble que je ne puisse l'obtenir qu'en unités de caractères.
J'ai essayé l'extraction linéaire par binarisation et conversion Hough, mais j'essaierai d'appliquer l'OCR par ROI (découpage d'une partie de l'image) uniquement sur la partie où les sous-titres sont susceptibles d'apparaître une fois.
Je me suis demandé si je ne pouvais extraire que les sous-titres gris de la zone, mais il m'est difficile de savoir ce que je suis susceptible de faire car je souffre de gens: criez:
import sys
import cv2
import os
import numpy as np
import pyocr
import pyocr.builders
from PIL import Image, ImageDraw, ImageFont
import time
def process(src):
kernel = np.ones((3,3),np.uint8)
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
o_ret, o_dst = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
dst = cv2.morphologyEx(o_dst, cv2.MORPH_OPEN, kernel)
return cv2.bitwise_not(dst)
def imageToText(tool, src):
tmp_path = "temp.png "
cv2.imwrite(tmp_path, src)
dst = tool.image_to_string(
Image.open(tmp_path),
lang='jpn',
builder=pyocr.builders.WordBoxBuilder(tesseract_layout=6)
)
sentence = []
for item in dst:
sentence.append(item.content)
return "".join(sentence)
def createTextImage(src, sentence, px, py, color=(8,8,8), fsize=28):
tmp_path = "src_temp.png "
cv2.imwrite(tmp_path, src)
img = Image.open(tmp_path)
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("./IPAfont00303/ipag.ttf", fsize)
draw.text((px, py), sentence, fill=color, font=font)
img.save(tmp_path)
return cv2.imread(tmp_path)
if __name__ == '__main__':
tools = pyocr.get_available_tools()
if len(tools) == 0:
print("No OCR tool found")
sys.exit(1)
tool = tools[0]
cap = cv2.VideoCapture('one_minutes.mp4')
cap_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
cap_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
telop_height = 50
fourcc = cv2.VideoWriter_fourcc('m','p','4','v')
writer = cv2.VideoWriter('extract_telop_text.mp4',fourcc, fps, (cap_width, cap_height + telop_height))
start = time.time()
count = 0
try :
while True:
if not cap.isOpened():
break
if cv2.waitKey(1) & 0xFF == ord('q'):
break
ret, frame = cap.read()
if frame is None:
break
telop = np.zeros((telop_height, cap_width, 3), np.uint8)
telop[:] = tuple((128,128,128))
gray_frame = process(frame)
roi = gray_frame[435:600, :]
txt = imageToText(tool, roi)
images = [frame, telop]
frame = np.concatenate(images, axis=0)
font = cv2.FONT_HERSHEY_SIMPLEX
seconds = round(count/fps, 4)
cv2.putText(frame, "{:.4f} [sec]".format(seconds),
(cap_width - 250, cap_height + telop_height - 10),
font,
1,
(0, 0, 255),
2,
cv2.LINE_AA)
writer.write(createTextImage(frame, txt, 20, cap_height + 10))
count += 1
print("{}[sec]".format(seconds))
except cv2.error as e:
print(e)
writer.release()
cap.release()
print("Done!!! {}[sec]".format(round(time.time() - start,4)))
―― J'utilise PIL au lieu d'openCV pour écrire des caractères japonais, mais lorsque je transmets les données, j'enregistre temporairement le fichier image. Pour cette raison, il a fallu plus de 10 minutes pour générer la vidéo: sweat_smile: Y a-t-il un bon moyen: déçu_relieved:
Exemple)
tmp_path = "src_temp.png "
#Sortie des données d'image utilisées dans openCV
cv2.imwrite(tmp_path, src)
#Lire les données avec PIL
img = Image.open(tmp_path)
--Le flux avant la reconnaissance de caractères est le suivant.
def process(src):
kernel = np.ones((3,3),np.uint8)
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
o_ret, o_dst = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
dst = cv2.morphologyEx(o_dst, cv2.MORPH_OPEN, kernel)
return cv2.bitwise_not(dst)
Kampe interfère un peu avec la reconnaissance des caractères, mais je pense qu'il peut être lu dans une certaine mesure.
Ensuite, essayons la reconnaissance de caractères à l'aide de l'API Google Cloud Vision. J'ai essayé la démo de https://cloud.google.com/vision/, mais la précision est toujours élevée.
Recommended Posts