5

編集:ハワードのおかげで、ここでコードを修正しました。現在は機能しているようです。

EDIT2 : コードを更新して、当初の意図どおりに垂直方向のぼかしを含めました。さまざまな設定で得られたサンプル出力:ぼかし比較 images.jpg

ぼかし操作の別のリファレンス (Java):初心者向けのぼかし


元の投稿:

基本的な画像処理について学び、この単純なBlur メソッド(「結果の再利用」の下の 2 番目の関数 BlurHorizo​​ntal) を Pythonで複製しようとしています。PIL には既にぼかし機能があることは知っていますが、基本的なピクセル操作を自分で試してみたいと思います。

この関数はソース画像を取得し、特定の半径に基づいて RGB ピクセル値を平均し、処理された画像を新しいファイルに書き込みます。私の問題は、完全に間違った平均値を持つ多くのピクセルを取得していることです (たとえば、特定の領域で赤ではなく明るい緑の線が表示されるなど)。

ぼかし半径が 2 の場合、平均化方法は、入力ピクセルを中心とする 5 つのピクセルの RGB 値を加算します。「スライディング ウィンドウ」を使用して実行中の合計を維持し、送信ピクセル (左側) を減算し、新しい受信ピクセル (ウィンドウの右側) を追加します。ぼかし方法はこちら

サンプル:ぼかしテスト画像 output.jpg

私が間違っていたアイデアはありますか?画像の一部の部分がきれいにぼやけているのに、他の部分が周囲の領域とはまったく関係のない色で塗りつぶされている理由はわかりません。

ご協力いただきありがとうございます。

FIXED WORKING コード(Howard に感謝)

import Image, numpy, ImageFilter
img = Image.open('testimage.jpg')

imgArr = numpy.asarray(img) # readonly

# blur radius in pixels
radius = 2

# blur window length in pixels
windowLen = radius*2+1

# columns (x) image width in pixels
imgWidth = imgArr.shape[1]

# rows (y) image height in pixels
imgHeight = imgArr.shape[0]

#simple box/window blur
def doblur(imgArr):
    # create array for processed image based on input image dimensions
    imgB = numpy.zeros((imgHeight,imgWidth,3),numpy.uint8)
    imgC = numpy.zeros((imgHeight,imgWidth,3),numpy.uint8)

    # blur horizontal row by row
    for ro in range(imgHeight):
        # RGB color values
        totalR = 0
        totalG = 0
        totalB = 0

        # calculate blurred value of first pixel in each row
        for rads in range(-radius, radius+1):
            if (rads) >= 0 and (rads) <= imgWidth-1:
                totalR += imgArr[ro,rads][0]/windowLen
                totalG += imgArr[ro,rads][1]/windowLen
                totalB += imgArr[ro,rads][2]/windowLen

        imgB[ro,0] = [totalR,totalG,totalB]

        # calculate blurred value of the rest of the row based on
        # unweighted average of surrounding pixels within blur radius
        # using sliding window totals (add incoming, subtract outgoing pixels)
        for co in range(1,imgWidth):
            if (co-radius-1) >= 0:
                totalR -= imgArr[ro,co-radius-1][0]/windowLen
                totalG -= imgArr[ro,co-radius-1][1]/windowLen
                totalB -= imgArr[ro,co-radius-1][2]/windowLen
            if (co+radius) <= imgWidth-1:
                totalR += imgArr[ro,co+radius][0]/windowLen
                totalG += imgArr[ro,co+radius][1]/windowLen
                totalB += imgArr[ro,co+radius][2]/windowLen

            # put average color value into imgB pixel

            imgB[ro,co] = [totalR,totalG,totalB]

    # blur vertical

    for co in range(imgWidth):
        totalR = 0
        totalG = 0
        totalB = 0

        for rads in range(-radius, radius+1):
            if (rads) >= 0 and (rads) <= imgHeight-1:
                totalR += imgB[rads,co][0]/windowLen
                totalG += imgB[rads,co][1]/windowLen
                totalB += imgB[rads,co][2]/windowLen

        imgC[0,co] = [totalR,totalG,totalB]

        for ro in range(1,imgHeight):
            if (ro-radius-1) >= 0:
                totalR -= imgB[ro-radius-1,co][0]/windowLen
                totalG -= imgB[ro-radius-1,co][1]/windowLen
                totalB -= imgB[ro-radius-1,co][2]/windowLen
            if (ro+radius) <= imgHeight-1:
                totalR += imgB[ro+radius,co][0]/windowLen
                totalG += imgB[ro+radius,co][1]/windowLen
                totalB += imgB[ro+radius,co][2]/windowLen

            imgC[ro,co] = [totalR,totalG,totalB]

    return imgC

# number of times to run blur operation
blurPasses = 3

# temporary image array for multiple passes
imgTmp = imgArr

for k in range(blurPasses):
    imgTmp = doblur(imgTmp)
    print "pass #",k,"done."

imgOut = Image.fromarray(numpy.uint8(imgTmp))

imgOut.save('testimage-processed.png', 'PNG')
4

2 に答える 2

2

回線に問題があると思います

for rads in range(-radius, radius):

これは radius-1 のみに実行されます (範囲は最後を除外します)。2 番目の範囲引数に 1 を追加します。

更新:行内に別の小さな問題があります

if (co-radius-1) > 0:

どちらであるべきか

if (co-radius-1) >= 0:
于 2011-04-03T06:13:46.193 に答える