Translating code to Julia

Translating code from another language to Julia isn’t hard, especially so if that language is Matlab or even Python. I have been translating code from Python, and the biggest issues I have found are with code having array starting values of 0, versus Julia’s 1, and some of Pythons more eclectic ways of expressing things. Similarly with C.

Consider the case of a point detector, a simple filter to find discontinuities in an image. It basically applies a mask to all the pixels in the image, and the result is an image where the edges have been enhanced. Here is what the mask looks like:

pointDmask

Here is an example of a piece of C code and its equivalent in Julia. Here is the code in C:

void PointDetector(struct image pI, struct image *pO)
{
  int x, y, i, j, sum;
  int mask[3][3] = {{-1,-1,-1}, {-1,8,-1}, {-1,-1,-1}};
 
  // Allocate space for the new image
  pO->pixel = malloc(pI.nrows*sizeof(int *));
  for (i=0; i<pI.nrows; i=i+1)
    pO->pixel[i] = (int *)malloc(pI.ncols*sizeof(int *)); 
  pO->nrows = pI.nrows; 
  pO->ncols = pI.ncols; 

  // Copy the pixels from the original image (edge pixels)
  for (x=0; x<pI.nrows; x++)
    for (y=0; y<pI.ncols; y++)
      pO->pixel[x][y] = pI.pixel[x][y]; 
 
  // Filter the image using the mask
  for (x=1; x<pI.nrows-1; x++)
    for (y=1; y<pI.ncols-1; y++){
      sum = 0;
      for (i=-1;i<=1;i++)
        for (j=-1;j<=1;j++)
          sum = sum + pI.pixel[x+i][y+j] * mask[i+1][j+1];
      if (sum > 255)
        sum = 255;
      else if (sum < 0)
        sum = 0;
      pO->pixel[x][y] = sum;
    }
}

Due to the potentially large size of an image, a dynamic array is used to store the image, contained within a struct that also holds values for the number of rows and columns in the image.

struct image
{
    int nrows;
    int ncols;
    int **pixel;
};

Now consider the function translated into Julia:

function pointDetector(img)

    dx,dy = size(img)
    mask = [-1 -1 -1; -1 8 -1; -1 -1 -1]
    imgP = copy(img)

    for i=2:dx-1, j=2:dy-1
        block = img[i-1:i+1,j-1:j+1]
        conv = block .* mask
        sumb = sum(conv)
        if sumb > 255
            sumb = 255
        elseif sumb < 0
            sumb = 0
        end
        imgP[i,j] = sumb
    end
    return imgP
end

The Julia function is much simpler. this stems partially from the simpler nature of the structure used to store the image (a simple array, with transparent storage), and partially from the lack of additional loops to deal with simple things like copying the image. The C function uses 7 for loops, the Julia function uses one (technically a nested loop). Copying the image is simpler, and does not require a structure which incorporate the dimensions of the array (again, transparent). Extraction of the “block” is achieved through array slicing, and convolution of the block with the mask is by means of element-wise multiplication. Finally, the sum uses the built-in function sum(). There is also no need to deal with dynamic arrays. I don’t have anything against dynamic arrays in C, but they do make code more “complex” looking, and they are a pain to debug. Also notice that depending on whether the struct image is passed by “value” (pI) or “reference” (pO), they uses different notation, “.” or “->” respectively (and this is just annoying).

So this translation was easy – not to say they all will be, but a good experience with less overhead.

And if you are wondering what the function actually does? Here is an example.

pointDeg

The image on the left is the original, the one on the right is after processing with the point detector algorithm.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s