Ejemplo n.º 1
0
F2D* harris(I2D* im)
{
    F2D *img1;
    F2D *g1, *g2, *g;
    F2D *Ix, *Iy;
    F2D *Ix2, *Iy2, *IxIy;
    F2D *v, *R, *Rmax, *Rnm;
    float eps;
    F2D *sobel, *sob, *temp, *temp1;    
    I2D *win, *x, *y;
    int i;
    
    g1 = fSetArray(5,5,0);
    g2 = fSetArray(3,3,0);

    asubsref(g1,0) = 1;
    asubsref(g1,1) = 4;
    asubsref(g1,2) = 6;
    asubsref(g1,3) = 4;
    asubsref(g1,4) = 1;

    asubsref(g1,5) = 4;
    asubsref(g1,6) = 16;
    asubsref(g1,7) = 24;
    asubsref(g1,8) = 16;
    asubsref(g1,9) = 4;

    asubsref(g1,10) = 6;
    asubsref(g1,11) = 24;
    asubsref(g1,12) = 36;
    asubsref(g1,13) = 24;
    asubsref(g1,14) = 6;

    asubsref(g1,15) = 4;
    asubsref(g1,16) = 16;
    asubsref(g1,17) = 24;
    asubsref(g1,18) = 16;
    asubsref(g1,19) = 4;

    asubsref(g1,20) = 1;
    asubsref(g1,21) = 4;
    asubsref(g1,22) = 6;
    asubsref(g1,23) = 4;
    asubsref(g1,24) = 1;

    asubsref(g2,0) = 1;
    asubsref(g2,1) = 2;
    asubsref(g2,2) = 1;
    
    asubsref(g2,3) = 2;
    asubsref(g2,4) = 4;
    asubsref(g2,5) = 2;

    asubsref(g2,6) = 1;
    asubsref(g2,7) = 2;
    asubsref(g2,8) = 1;
    
    g = fDivide(g1, 256);
    sob = fMallocHandle(1,3);
    asubsref(sob,0) = -0.5;
    asubsref(sob,1) = 0;
    asubsref(sob,2) = 0.5;

    {
        F2D* imf;
        imf = fiDeepCopy(im);
        img1 = ffConv2(imf, g);
        fFreeHandle(imf);
    }

    Ix = ffConv2(img1, sob); 
    fFreeHandle(sob);
    sob = fMallocHandle(3,1);
    asubsref(sob,0) = -0.5;
    asubsref(sob,1) = 0;
    asubsref(sob,2) = 0.5;
    Iy = ffConv2(img1, sob);

    fFreeHandle(g);
    g = fDivide(g2, 16);
    eps = 2.2204e-16;
    sobel = fTimes(Ix, Ix);
    Ix2 = ffConv2(sobel, g);
    fFreeHandle(sobel);

    sobel = fTimes(Iy, Iy);
    Iy2 = ffConv2(sobel, g);
    fFreeHandle(sobel);

    sobel = fTimes(Ix, Iy);
    IxIy = ffConv2(sobel, g);
    fFreeHandle(sobel);
 
    temp = fTimes(Ix2, Iy2);
    temp1 = fTimes(IxIy, IxIy);
    sobel = fMinus(temp, temp1);

    fFreeHandle(temp);
    temp = fPlus(Ix2, Iy2);

    for(i=0; i<(temp->height*temp->width); i++)
        asubsref(temp,i) += eps;

    R = ffDivide(sobel, temp);
    
    win = iSetArray(1,2,3);
    Rmax = maxWindow(R, win);
    Rnm = supress(R, Rmax);

    v = fFind3(Rnm);
    
    iFreeHandle(win);
    fFreeHandle(Rmax);
    fFreeHandle(Rnm);
    fFreeHandle(R);
    
    fFreeHandle(img1);
    fFreeHandle(g1);
    fFreeHandle(g2);
    fFreeHandle(g);
    fFreeHandle(Ix);
    fFreeHandle(Iy);
    fFreeHandle(Ix2);
    fFreeHandle(Iy2);
    fFreeHandle(IxIy);
    fFreeHandle(sobel);
    fFreeHandle(sob);
    fFreeHandle(temp);
    fFreeHandle(temp1);
//    iFreeHandle(x);
//    iFreeHandle(y);
    
    return v;
}
Ejemplo n.º 2
0
/*
 * Core that apply a 3x3(Configurable) 2d Convolution, Erode, Dilate on
 * grayscale images
 * http://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_1/ug902-vivado-high-level-synthesis.pdf
 * */
void doImgProc(hls::stream<uint_8_side_channel>& inStream,
               hls::stream<int_8_side_channel> & outStream,
               char                              kernel[KERNEL_DIM * KERNEL_DIM],
               int                               operation)
{
#pragma HLS INTERFACE axis port=inStream
#pragma HLS INTERFACE axis port=outStream
#pragma HLS INTERFACE s_axilite port=return bundle=CRTL_BUS
#pragma HLS INTERFACE s_axilite port=operation bundle=CRTL_BUS
#pragma HLS INTERFACE s_axilite port=kernel bundle=KERNEL_BUS

  // Defining the line buffer and setting the inter dependency to false through
  // pragmas
  hls::LineBuffer<KERNEL_DIM, IMG_WIDTH, unsigned char> lineBuff;
  hls::Window<KERNEL_DIM, KERNEL_DIM, short> window;

  // Index used to keep track of row,col
  int idxCol       = 0;
  int idxRow       = 0;
  int pixConvolved = 0;

  // Calculate delay to fix line-buffer offset
  int waitTicks  = (IMG_WIDTH * (KERNEL_DIM - 1) + KERNEL_DIM) / 2;// 241;
  int countWait  = 0;
  int sentPixels = 0;


  int_8_side_channel  dataOutSideChannel;
  uint_8_side_channel currPixelSideChannel;

  // Iterate on all pixels for our 320x240 image, the HLS PIPELINE improves our
  // latency
  for (int idxPixel = 0; idxPixel < (IMG_WIDTH * IMG_HEIGHT); idxPixel++) {
#pragma HLS PIPELINE

    // Read and cache (Block here if FIFO sender is empty)
    currPixelSideChannel = inStream.read();

    // Get the pixel data
    unsigned char pixelIn = currPixelSideChannel.data;

    // Put data on the LineBuffer
    lineBuff.shift_up(idxCol);
    lineBuff.insert_top(pixelIn, idxCol); // Will put in val[2] of line buffer
                                          // (Check Debug)

    // Put data on the window and multiply with the kernel
    for (int idxWinRow = 0; idxWinRow < KERNEL_DIM; idxWinRow++) {
      for (int idxWinCol = 0; idxWinCol < KERNEL_DIM; idxWinCol++) {
        // idxWinCol + pixConvolved, will slide the window ...
        short val = (short)lineBuff.getval(idxWinRow, idxWinCol + pixConvolved);

        // Multiply kernel by the sampling window
        val = (short)kernel[(idxWinRow * KERNEL_DIM) + idxWinCol] * val;
        window.insert(val, idxWinRow, idxWinCol);
      }
    }

    // Avoid calculate out of the image boundaries and if we can convolve
    short valOutput = 0;

    if ((idxRow >= KERNEL_DIM - 1) && (idxCol >= KERNEL_DIM - 1)) {
      switch (operation) {
      case 0:

        // Convolution
        valOutput = sumWindow(&window);
        valOutput = valOutput / 8;

        // Avoid negative values
        if (valOutput < 0) valOutput = 0;
        break;

      case 1:

        // Erode
        valOutput = minWindow(&window);
        break;

      case 2:

        // Dilate
        valOutput = maxWindow(&window);
        break;
      }

      pixConvolved++;
    }

    // Calculate row and col index
    if (idxCol < IMG_WIDTH - 1) {
      idxCol++;
    }
    else {
      // New line
      idxCol = 0;
      idxRow++;
      pixConvolved = 0;
    }

    /*
     * Fix the line buffer delay, on a 320x240 image with 3x3 kernel, the delay
     * will be
     * ((240*2) + 3)/2 = 241
     * So we wait for 241 ticks send the results than put more 241 zeros
     */

    // Put data on output stream (side-channel(tlast) way...)

    /*dataOutSideChannel.data = valOutput;
       dataOutSideChannel.keep = currPixelSideChannel.keep;
       dataOutSideChannel.strb = currPixelSideChannel.strb;
       dataOutSideChannel.user = currPixelSideChannel.user;
       dataOutSideChannel.last = currPixelSideChannel.last;
       dataOutSideChannel.id = currPixelSideChannel.id;
       dataOutSideChannel.dest = currPixelSideChannel.dest;

       // Send to the stream (Block if the FIFO receiver is full)
       outStream.write(dataOutSideChannel);*/
    countWait++;

    if (countWait > waitTicks)  {
      dataOutSideChannel.data = valOutput;
      dataOutSideChannel.keep = currPixelSideChannel.keep;
      dataOutSideChannel.strb = currPixelSideChannel.strb;
      dataOutSideChannel.user = currPixelSideChannel.user;
      dataOutSideChannel.last = 0;
      dataOutSideChannel.id   = currPixelSideChannel.id;
      dataOutSideChannel.dest = currPixelSideChannel.dest;

      // Send to the stream (Block if the FIFO receiver is full)
      outStream.write(dataOutSideChannel);
      sentPixels++;
    }
  }

  // Now send the remaining zeros (Just the (Number of delayed ticks)
  for (countWait = 0; countWait < waitTicks; countWait++) {
    dataOutSideChannel.data = 0;
    dataOutSideChannel.keep = currPixelSideChannel.keep;
    dataOutSideChannel.strb = currPixelSideChannel.strb;
    dataOutSideChannel.user = currPixelSideChannel.user;

    // Send last on the last item
    if (countWait < waitTicks - 1) dataOutSideChannel.last = 0;
    else dataOutSideChannel.last = 1;
    dataOutSideChannel.id   = currPixelSideChannel.id;
    dataOutSideChannel.dest = currPixelSideChannel.dest;

    // Send to the stream (Block if the FIFO receiver is full)
    outStream.write(dataOutSideChannel);
  }
}