1

私の目標は、値= 255の画像ピクセルを0に変換することです。つまり、すべての真っ白なピクセルを削除します。opencvとopenclを使用したPythonのコードは次のとおりです。

import os
import glob
import cv2 as cv
import numpy as np
import pyopencl as cl

def filter_image( ):

    platforms = cl.get_platforms()
    devices = platforms[0].get_devices( cl.device_type.ALL )
    context = cl.Context( [devices[0]] )
    cQ = cl.CommandQueue( context )
    kernel = """
        __kernel void filter( global uchar* a, global uchar* b ){
                int y = get_global_id(0);
                int x = get_global_id(1);

                int sizex = get_global_size(1);

                if( a[ y*sizex + x ] != 255 )
                        b[ y*sizex + x ] = a[ y*sizex + x ];
            }"""

    program = cl.Program( context, kernel ).build()

    for i in glob.glob("*.png"):

        image = cv.imread( i, 0 )        
        b = np.zeros_like( image, dtype = np.uint8 )
        rdBuf = cl.Buffer( 
                context,
                cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR,
                hostbuf = image
                          )

        wrtBuf = cl.Buffer( 
                context,
                cl.mem_flags.WRITE_ONLY,
                b.nbytes
                          )

        program.filter( cQ, image.shape, None, rdBuf, wrtBuf ).wait()
        cl.enqueue_copy( cQ, b, wrtBuf ).wait()
        cv.imshow( 'a', b )
        cv.waitKey( 0 )

def Filter( ):
    os.chdir('D:\image')
    filter_image( )
    cv.destroyAllWindows()

私が直面している問題は、上記のプログラムのようにループを使用すると、ロジックが最初の画像に対してのみ機能することです。つまり、白いピクセルは最初の画像に対してのみ削除されますが、後続の画像には影響がありません。つまり、出力画像は入力画像と同じであり、値=255のピクセルには何の影響もありません。これは単純なはずです。解決策が見つかりません。

この問題の解決にご協力ください。

ありがとうございました。

4

1 に答える 1

3

カーネルでは、画像のピクセルが白bの場合、画像のピクセルを何にも設定していません。a次のように変更する必要があります。

b[y * sizex + x] = (a[y * sizex + x] == 255) ? 0 : a[y * sizex + x];

これにより、画像aのピクセルが白の場合は画像bのピクセルがゼロに設定され、それ以外の場合はピクセルが変更されずにコピーされます。また、この種の操作をインプレースで実行して、必要なバッファーが1つだけになるようにすることも検討してください。

于 2013-01-21T13:44:17.733 に答える