2013-07-30 2 views
0

Mon code source est de Calcul hétérogène avec OpenCL Chapitre 4 Exemples OpenCL de base> Rotation d'image. Le livre omet plusieurs détails critiques.Comment pouvez-vous aplatir les coordonnées de l'image dans un tableau 1D?

Mon problème majeur est que je ne sais pas comment initialiser le tableau que je fournis à leur noyau (ils ne vous disent pas comment). Ce que j'est:

int W = inImage.width(); 
int H = inImage.height(); 
float *myImage = new float[W*H]; 
    for(int row = 0; row < H; row++) 
     for(int col = 0; col < W; col++) 
      myImage[row*W+col] = col; 

que je l'offre à ce noyau:

__kernel void img_rotate(__global float* dest_data, __global float* src_data, int W, int H, float sinTheta, float cosTheta) 
{ 
    const int ix = get_global_id(0); 
    const int iy = get_global_id(1); 
    float x0 = W/2.0f; 
    float y0 = H/2.0f; 
    float xoff = ix-x0; 
    float yoff = iy-y0; 
    int xpos = (int)(xoff*cosTheta + yoff*sinTheta + x0); 
    int ypos = (int)(yoff*cosTheta - xoff*sinTheta + y0); 
    if(((int)xpos>=0) && ((int)xpos < W) && ((int)ypos>=0) && ((int)ypos<H)) 
    { 
     dest_data[iy*W+ix] = src_data[ypos*W+xpos]; 
     //dest_data[iy*W+ix] = src_data[iy*W+ix]; 
    } 
} 

Je vais avoir du mal à trouver la bonne valeur pour thêta aussi. Un nombre entier serait une valeur appropriée pour thêta, non?

float theta = 45; // 45 degrees, right? 
float cos_theta = cos(theta); 
float sin_theta = sin(theta); 
+1

bibliothèque 'cos' et' sin' acceptent toujours les radians - vous devriez convertir 45 degrés en radians – japreiss

Répondre

2

En écrivant mon code OpenCL, je traite toujours chaque noyau comme la lecture d'un jeu 3D de données, peu importe si les données sont 1D, 2D ou 3D:

__kernel void TestKernel(__global float *Data){ 
     k = get_global_id(0); //also z 
     j = get_global_id(1); //also y 
     i = get_global_id(2); //also x 

     //Convert 3D to 1D 
     int linear_coord = i + get_global_size(0)*j + get_global_size(0)*get_global_size(1)*k; 

     //do stuff 
} 

Quand vous faites la clEnqueueNDKernelRange (...), situé juste à la dimension à:

int X = 500; 
int Y = 300; 
int Z = 1; 

size_t GlobalDim = {Z, Y, X}; 

Cela nous allons tous mes noyaux travailler facilement dans toutes les dimensions.

Questions connexes