Я пытаюсь реализовать гауссовский фильтр для изображений из кода, который я нашел в Интернете, используя Python и PyOpenCL. Мои исходные изображения - массивы numpy, но я смущен, как в том, что я должен использовать для передачи изображений на графический процессор.Преобразование OpenCL в pyOpenCL Array или numpy ndarray
Первоначально ядро получает изображения OpenCL в качестве входных данных. Это работает отлично, и ядро работает правильно, однако я не нашел способ преобразовать вывод вычисления графического процессора (также OpenCL Image) в массив numpy. Это необходимо, так как после запуска фильтра GPU мне придется выполнять другие вычисления.
Я попытался с помощью pyOpenCL массива, но было 2 проблемы в этом случае:
- Не знаю, как сказать ядру, что вход будет массив, так как она представляет собой структуру данных pyOpenCL, не OpenCL.
- Не нашел эквивалент
read_imagef
, который будет использоваться в массивах pyOpenCL, и я использую эту функцию в своем ядре. - Не удалось получить результат GPU, скопированный обратно на хост. Я бы продолжал получать «
cl_array
не имеет ошибки get()» модуля.
Я хотел бы знать:
- Есть ли способ, чтобы сообщить ядру, что он получит массив, так же, как я использую
image2d_t
сказать, что вход является изображение? - Что я могу использовать в качестве эквивалента для OpenCL's
read_imagef
для массивов pyOpenCL?
Большое спасибо заранее. Код ядра ниже:
Ядро:
__kernel void gaussian(__read_only image2d_t inputImage,
__read_only image2d_t filterImage,
__write_only image2d_t outputImage,
const int nInWidth,
const int nFilterWidth){
const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
const int xOut = get_global_id(0);
const int yOut = get_global_id(1);
float4 sum = (float4)(0.0, 0.0, 0.0, 1.0);
for(int r = 0; r < nFilterWidth; r++){
for(int c = 0; c < nFilterWidth; c++){
int2 location = (xOut + r, yOut + c);
float4 filterVal = read_imagef(filterImage, sampler, location);
float4 inputVal = read_imagef(inputImage, sampler, location);
sum.x += filterVal.x * inputVal.x;
sum.y += filterVal.y * inputVal.y;
sum.z += filterVal.z * inputVal.z;
sum.w = 1.0;
}
}
int2 outLocation = (xOut, yOut);
write_imagef(outputImage, outLocation, sum);
}