10

次のようなキャプチャ画像があります。

マカフィーのTesserCapというユーティリティを使用して、画像に「チョッピング」フィルターを適用できます。(実行する前に、画像に白と黒の2色しかないことを確認しました。)テキストボックスに値2のフィルターを使用した結果に非常に感銘を受けました。ほとんどのノイズを正確に除去しましたが、本文はそのままにして、次のようになりました。

自分のスクリプトの1つにこのようなものを実装したかったので、TesserCapが使用している画像処理ライブラリを見つけようとしました。何も見つかりませんでした。画像を処理するために独自のコードを使用していることがわかりました。次に、プログラムがどのように機能するかを正確に説明するこのホワイトペーパーを読みました。それは私にこのチョッピングフィルターが何をするかについての次の説明を与えました:

指定されたグレースケール値の連続するピクセル数が数値ボックスに指定された数より少ない場合、チョッピングフィルターは、ユーザーの選択に従って、これらのシーケンスを0(黒)または255(白)に置き換えます。CAPTCHAは水平方向と垂直方向の両方で分析され、対応する変更が行われます。

私はそれが何をしているのか理解できません。私のスクリプトはPythonであるため、PILを使用して、説明されている引用のようなピクセルを操作してみました。簡単そうに聞こえますが、フィルターが何をしているのか正確にわからなかったためか、失敗しました。

(これは、円形のパターンを使用するわずかに異なるキャプチャから作られています。)

また、ImageMagickのconvert.exeで簡単に実行できるかどうかを確認してみました。彼らの-chopオプションは完全に異なるものです。-medianをいくつかの-morphologyコマンドと一緒に使用すると、ノイズの一部を減らすのに役立ちましたが、厄介なドットが表示され、文字が非常に歪んでしまいました。TesserCapでチョッピングフィルターを実行するほど簡単ではありませんでした。

だから、私の質問は次のとおりです:PythonでTesserCapのチョッピングフィルターを実装するにはどうすればよいですか?PILまたはImageMagickを使用していますか?そのチョッピングフィルターは、私が試したどの代替手段よりもはるかにうまく機能しますが、それを再現することはできないようです。私はこれに何時間も取り組んできましたが、まだ何も理解していません。

4

2 に答える 2

10

このアルゴリズムは基本的に、複数のターゲット ピクセル (この場合は白以外のピクセル) が連続して存在するかどうかをチェックし、ピクセル数がチョップ ファクター以下の場合はそれらのピクセルを変更します。

たとえば、#が黒で-が白であるピクセルのサンプル行では、 のチョップ ファクターを適用すると、2に変換--#--###-##---#####---#-#され------###-------#####-------ます。これは、2 ピクセル以下の一連の黒ピクセルがあり、これらの一連のピクセルが白に置き換えられるためです。2 ピクセルを超える連続したシーケンスが残ります。

これは、投稿の元の画像の Python コード (以下) に実装されているチョップ アルゴリズムの結果です。

「みじん切り」イメージ

これを画像全体に適用するには、このアルゴリズムをすべての行とすべての列で実行するだけです。これを実現する Python コードは次のとおりです。

import PIL.Image
import sys

# python chop.py [chop-factor] [in-file] [out-file]

chop = int(sys.argv[1])
image = PIL.Image.open(sys.argv[2]).convert('1')
width, height = image.size
data = image.load()

# Iterate through the rows.
for y in range(height):
    for x in range(width):

        # Make sure we're on a dark pixel.
        if data[x, y] > 128:
            continue

        # Keep a total of non-white contiguous pixels.
        total = 0

        # Check a sequence ranging from x to image.width.
        for c in range(x, width):

            # If the pixel is dark, add it to the total.
            if data[c, y] < 128:
                total += 1

            # If the pixel is light, stop the sequence.
            else:
                break

        # If the total is less than the chop, replace everything with white.
        if total <= chop:
            for c in range(total):
                data[x + c, y] = 255

        # Skip this sequence we just altered.
        x += total


# Iterate through the columns.
for x in range(width):
    for y in range(height):

        # Make sure we're on a dark pixel.
        if data[x, y] > 128:
            continue

        # Keep a total of non-white contiguous pixels.
        total = 0

        # Check a sequence ranging from y to image.height.
        for c in range(y, height):

            # If the pixel is dark, add it to the total.
            if data[x, c] < 128:
                total += 1

            # If the pixel is light, stop the sequence.
            else:
                break

        # If the total is less than the chop, replace everything with white.
        if total <= chop:
            for c in range(total):
                data[x, y + c] = 255

        # Skip this sequence we just altered.
        y += total

image.save(sys.argv[3])
于 2012-06-29T01:07:45.750 に答える
3

次のようなものを試してください(疑似コード):

for each row of pixels:
    if there is a group of about 3 or more pixels in a row, leave them
    else remove the pixels

次に、列に対して同じことを繰り返すだけです。少しでも効果がありそうです。このように水平方向と垂直方向の両方に移動すると、水平線/垂直線も削除されます。

于 2012-06-28T23:20:44.333 に答える