nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

Selenium4

はじめに

Selenium 4で参考になりそうな記事を集めます。

ファインチューニング

https://dev.classmethod.jp/articles/detect_number_plate/

文字数カウントを作成する

文字数カウントする処理を記載します

def count_characters_excluding(s, exclusions=(' ', ',')):
    """
    文字列sの中の文字数をカウントし、exclusionsに含まれる文字を除外します。
    """
    filtered_text = ''.join([char for char in s if char not in exclusions])
    return len(filtered_text)

# 使用例
text = "こんにちは、 みなさん。"
print(count_characters_excluding(text))  # 11と出力されます(空白、カンマを除外)
def calculate_difference_and_ratio(actual, expected):
    # 文字数のカウント
    actual_count = len(actual)
    expected_count = len(expected)
    
    # 期待値と実測値の差分を求める
    count_difference = actual_count - expected_count
    
    # 実測値が期待値からどれだけ離れたかの比率を求める
    # ここでは、実測値と期待値の差分の絶対値を期待値で割っています
    ratio = abs(count_difference) / expected_count * 100

    return actual_count, expected_count, count_difference, ratio

# 実測値
actual = "xxx"
# 期待値
expected = "xxx"

actual_count, expected_count, count_difference, ratio = calculate_difference_and_ratio(actual, expected)

print(f"実測値の文字数: {actual_count}")
print(f"期待値の文字数: {expected_count}")
print(f"文字数の差分: {count_difference}")
print(f"実測値が期待値から離れている比率: {ratio:.2f}%")

Azure Computer Visionを用いて、OCRを実行!

本記事について

Azure Computer Visionを用いて、OCRを実行します。

コード

import os
import time
from azure.cognitiveservices.vision.computervision import ComputerVisionClient
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.vision.computervision.models import OperationStatusCodes
from azure.cognitiveservices.vision.computervision.models import ComputerVisionOcrErrorException
import pprint

key = os.environ["AZURE_ACCOUNT_KEY"]
endpoint = os.environ["AZURE_END_POINT"]

def detect_texts_from_image(image_path) -> list[str]:
    """
    与えられた画像ファイルパスから画像を読み込み、その画像から抽出した文字列のリストを返します。

    Parameters:
        image_path (str): 画像ファイルのパス。読み込む画像のファイルパスを指定します。

    Returns:
        list[str]: 画像から抽出した文字列のリスト。画像内のテキストが空の場合、空のリストを返します。
    """

    computervision_client = ComputerVisionClient(endpoint, CognitiveServicesCredentials(key))
    local_image = open(image_path, "rb")

    try:
        recognize_results = computervision_client.read_in_stream(local_image, language="ja", raw=True)
    except ComputerVisionOcrErrorException as e:
        print("errors:", e.response)
        return None

    # 結果を取得するための操作IDを取得
    operation_location_remote = recognize_results.headers["Operation-Location"]
    operation_id = operation_location_remote.split("/")[-1]

    # 結果が利用可能になるまで待つ
    while True:
        get_text_results = computervision_client.get_read_result(operation_id)
        if get_text_results.status not in ["notStarted", "running"]:
            break
        time.sleep(1)

    result_lines: list[str] = []

    # テキストの出力
    if get_text_results.status == OperationStatusCodes.succeeded:
        for text_result in get_text_results.analyze_result.read_results:
            for line in text_result.lines:
                result_lines.append(line.text)

        return result_lines
    else:
        print(f"OperationStatusCodesがsucceeded以外 [{get_text_results.status}]")
        return None


image_path = "./input_images/レンタカー/レンタカー予約詳細.png"  # ローカルの画像パス

result_lines = detect_texts_from_image(image_path)

if result_lines is not None:
    pprint.pprint(result_lines)

    # 改行を含んだ文字列のリストを作成する
    result_lines_with_newlines = [line + '\n' for line in result_lines]

    with open("./output_text/output.txt", "w", encoding="utf-8") as f:
        f.writelines(result_lines_with_newlines)

else:
    print("画像から文字列取得に失敗しました。")

参考リンク

Google Cloud Translationを用いて、各言語に同時に翻訳実行します

翻訳の自動化について

翻訳の自動化はGoogle Cloud Translation以外には、DeepLのAPIを用いることも可能です

Google Translate Sample

# Imports the Google Cloud Translation library
from google.cloud import translate
import pandas as pd


# Initialize Translation client
def translate_text(
        target_string: str,
        project_id: str,
        source_language: str,
        target_language: str) -> translate.TranslationServiceClient:
    """Translating Text."""

    client = translate.TranslationServiceClient()

    location = "global"

    parent = f"projects/{project_id}/locations/{location}"

    # Translate text from English to French
    # Detail on supported types can be found here:
    # https://cloud.google.com/translate/docs/supported-formats
    response = client.translate_text(
        request={
            "parent": parent,
            "contents": [target_string],
            "mime_type": "text/plain",  # mime types: text/plain, text/html
            "source_language_code": source_language,
            "target_language_code": target_language,
        }
    )

    return response.translations[0].translated_text


project_id = "spherical-bloom-394122"
target_text = "吾輩わがはいは猫である。名前はまだ無い。どこで生れたかとんと見当けんとうがつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。"

result = translate_text(target_text, project_id, "ja", "en")
print(type(result))
print(result)

language_list = ["ja", "en", "fr", "de", "it", "pt", "es", "nl", "ru", "ko", "zh-hans", "zh-hant", "tr"]

translated_text_list = []

for target_language in language_list:
    if "ja" == target_language:
        continue
    result_text = translate_text(target_text, project_id, "ja", target_language)
    translated_text_list.append(result_text)

print(type(translated_text_list))
print(translated_text_list)

data = [
    [language_list],
    [translated_text_list],
]

df = pd.DataFrame(data)

df

Google Cloud Vision API

Google Cloud Visionの設定について

Google Cloud Vision APIサンプルコード

画像から文字列を抽出して、実際に取り出してきた値と期待値を比較して類似度を求めます

import io
import os
import difflib
from google.cloud import vision


def detect_texts_from_image(image_path: str) -> list[str]:
    """
    画像から文字列を抽出して表示します

    Parameters:
        image_path (str): 画像ファイルパスを指定する

    Returns:
        list[str]: 画像から抽出した文字列のリスト。
                   API呼び出し時のエラー発生時、画像から文字列を検出できなかった場合はエラーを返す
    """
    try:
        # 画像をバイナリデータとして読み込む
        with io.open(image_path, 'rb') as image_file:
            content = image_file.read()

        # Google Cloud Vision APIのクライアントを作成
        client = vision.ImageAnnotatorClient()

        # 画像内のテキストを抽出する
        image = vision.Image(content=content)
        response = client.text_detection(image=image)

        # 画像内にテキストが存在しない場合
        if not response.text_annotations:
            print("画像内に文字列を検出できませんでした。")
            return None

        result_text: str = response.text_annotations[0].description
        print(result_text)
        return result_text.splitlines()

    except Exception as e:
        # エラーが発生した場合の処理
        print("エラーが発生しました:", str(e))
        return None


def calculate_similarity(actual: str, expected: str) -> float:

    # SequenceMatcherオブジェクトを作成
    seq_matcher = difflib.SequenceMatcher(None, actual, expected)
    # 類似度を取得
    result = seq_matcher.ratio()
    return result


image_path = os.path.abspath("{任意の画像ファイル}.jpg")
detect_text_lines = detect_texts_from_image(image_path)

for item_actual in detect_text_lines:
    類似度= calculate_similarity(item_actual , "期待値の文字列")

Python + TesseractでOCR

はじめに

PythonとTesseractでOCRを実施しようとした場合は、日本文字列をそのままOCRに書けるとあまり精度が出ません。

import os
from PIL import Image
from PIL import ImageEnhance
import pyocr
import cv2
import difflib


def start_setting():
    TESSERACT_PATH = r'C:\Program Files\Tesseract-OCR'
    TESSDATA_PATH = r'C:\Program Files\Tesseract-OCR\tessdata'

    os.environ["PATH"] += os.pathsep + TESSERACT_PATH
    os.environ["TESSDATA_PREFIX"] = TESSDATA_PATH


def set_border(before_image, after_image, border: int = 125):
    for x in range(size[0]):
        for y in range(size[1]):
            r, g, b = before_image.getpixel((x, y))
            if r > border or g > border or b > border:
                r = 255
                g = 255
                b = 255
            after_image.putpixel((x, y), (r, g, b))


start_setting()

if not os.path.exists("./Convert"):
    # ディレクトリが存在しない場合、ディレクトリを作成する
    os.makedirs("./Convert")


# pyocrへ利用するOCRエンジンをTesseractに指定する。
tools = pyocr.get_available_tools()
print(tools[0].get_name())
tool = tools[0]
print("Will use tool '%s'" % (tool.get_name()))

# OCR対応言語を確認する
langs = tool.get_available_languages()
print("Available languages: %s" % ", ".join(langs))
lang = langs[0]
print("Will use lang '%s'" % (lang))

# OCR対象の画像ファイルを読み込む
img = Image.open('./Image/jp_text_pattern_modify.png')
img = img.convert('L')
img.save("./Convert/result_gray.jpg")

# コントラストを上げる
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(4.0)
img.save("./Convert/result_gray_contrast.jpg")

# 画像を読みやすいように加工。
img = img.convert('RGB')
size = img.size
border_image = Image.new('RGB', size)

set_border(img, border_image, 230)
border_image.save("./Convert/border_image.jpg")

result_text_from_img = tool.image_to_string(
    border_image,
    lang='jpn',
    builder=pyocr.builders.TextBuilder()
)
# txt is a Python string


print(result_text_from_img)
result_text_from_img = result_text_from_img.replace(' ', '')

word_boxes = tool.image_to_string(
    border_image,
    lang="eng",
    builder=pyocr.builders.WordBoxBuilder()
)


expected = "私のテキスト入力は完璧です。"
diff = difflib.Differ()
diffs = diff.compare(result_text_from_img, expected)

for diff in diffs:
    print(diff)

Open-CV

【python】OpenCVのインストール方法 | 資格マフィア

参考リンク