Search code examples
c++imageimage-processingchain

image processing the Chain


I've this code below, and I was asked to modify it, to add x[] and y[], and save the coordinates of boundary into x[] and y[]

the code does read an image as matrix, 2X2, and if any object found, it calculate the perimeters. boundaries of the object found.

ps. Chain code, is basically Freeman Chain Code

I'll add a pic of how it works, enter image description here

can someone help me please, I would be very thankful,

// compute the chain code of the object begninning at pixel (i,j)
//and return the direction code as NN integers in the array C[] , and coordinates of boundary in x[] and y[]

    void chain8 (struct image *x, int *c, int i, int j, int *nn)
    {
        int val,n,m,q,r, di[9],dj[9],ii,dii;
        int lastdir, jj;

    /*      Table given index offset for each of the 8 directions.          */
        di[0] = 0;      di[1] = -1;     di[2] = -1;     di[3] = -1;
        dj[0] = 1;      dj[1] = 1;      dj[2] = 0;      dj[3] = -1;
        di[4] = 0;      di[5] = 1;      di[6] = 1;      di[7] = 1;
        dj[4] = -1;     dj[5] = -1;     dj[6] = 0;      dj[7] = 1;

        for (ii=0; ii<200; ii++) c[ii] = -1;    /* Clear the code table */
        val = x->data[i][j];    n = 0;  /* Initialize for starting pixel */
        q = i;  r = j;  lastdir = 4;

        do {
           m = 0;
           dii = -1; 
           for (ii=lastdir+1; ii<lastdir+8; ii++) {     /* Look for next */
              jj = ii%8;
              if (range(x,di[jj]+q, dj[jj]+r))
            if ( x->data[di[jj]+q][dj[jj]+r] == val) {
               dii = jj;    m = 1;
               break;
            } 
           }

           if (m) {     /* Found a next pixel ... */
            if (n<200) c[n++] = dii;        /* Save direction as code */
            q += di[dii];   r += dj[dii];
            lastdir = (dii+5)%8;
           } else break;        /* NO next pixel */
           if (n>200) break;
        } while ( (q!=i) || (r!=j) );   /* Stop when next to start pixel */

        *nn = n;
    }

Solution

  • The variables q and r contain current pixel coordinates. You start with pixel q = i, r = j. In the external loop you do:

    1. Find the boundary dirrection index dii. You sequentially (counterclockwise) look through all directions starting from the last direction lastdir and find pixel with color val. You use dii as direction index, from wich you can get pixel offsets using lookup tables di and dj.

    2. Updade current pixel position by adding pixel offsets (dx, dy) coresponded to direction dii to current coordinates q += di[dii]; r += dj[dii];

    You need to store q and r for bounary pixels to arrays bx and by. It's easy enough:

    bx[n] = q;
    by[n] = r;
    

    So you final code will be

    // compute the chain code of the object begninning at pixel (i,j)
    //and return the direction code as NN integers in the array C[] , and coordinates of boundary in bx[] and by[]
    
    void chain8(struct image *x, int* bx, int* by,  int *c, int i, int j, int *nn)
    {
       int val, n, m, q, r, di[9], dj[9], ii, dii;
       int lastdir, jj;
    
       /*      Table given index offset for each of the 8 directions.          */
       di[0] = 0;      di[1] = -1;     di[2] = -1;     di[3] = -1;
       dj[0] = 1;      dj[1] = 1;      dj[2] = 0;      dj[3] = -1;
       di[4] = 0;      di[5] = 1;      di[6] = 1;      di[7] = 1;
       dj[4] = -1;     dj[5] = -1;     dj[6] = 0;      dj[7] = 1;
    
       for (ii = 0; ii<200; ii++) by[ii] = bx[ii] = c[ii] = -1;    /* Clear the code table */
       val = x->data[i][j];    n = 0;  /* Initialize for starting pixel */
       q = i;  r = j;  lastdir = 4;
    
       do {
          m = 0;
          dii = -1;
          for (ii = lastdir + 1; ii<lastdir + 8; ii++) {     /* Look for next */
             jj = ii % 8;
             if (range(x, di[jj] + q, dj[jj] + r))
                if (x->data[di[jj] + q][dj[jj] + r] == val) {
                   dii = jj;    m = 1;
                   break;
                }
          }
    
          if (m) {     /* Found a next pixel ... */
             q += di[dii];   r += dj[dii];
             if (n < 200)
             {
                c[n] = dii;        /* Save direction as code */
                bx[n] = q;
                by[n] = r;
                n++;
             }
    
             lastdir = (dii + 5) % 8;
          }
          else break;        /* NO next pixel */
          if (n>200) break;
       } while ((q != i) || (r != j));   /* Stop when next to start pixel */
    
       *nn = n;
    }