//disparity map checking various disparites for a given pixel
ImgFloat disparity_map(ImgGray left, ImgGray right)
{
    ImgFloat disparity;
    disparity.Reset(left.Width(),left.Height());
    vector<ImgFloat> dbar;
    dbar=imagedisp(left, right);
    for(int y=0; y<left.Height(); y++)
        for(int x=0; x<left.Width(); x++)
        {
            int min=9999;
            for(int d=0; d<max_disp; d++)
                if(dbar[d](x,y)<min)
                {
                    min=dbar[d](x,y);
                    disparity(x,y)=d;
                }
        }
    return disparity;
}
//dissimilarity using absolute difference + convolution
vector<ImgFloat> imagedisp(ImgGray left, ImgGray right)
{
    std::vector<ImgFloat> disp(max_disp);
    int i,j;
    int kernal[7];
    for(int i=0; i<7; i++)
        kernal[i]=1;
    int window=7;
    int halfwindow=(window+1)/2;
    ImgFloat temp(left.Width(),left.Height());
    Set(&temp,0);
    for(int d=0; d<max_disp; d++)
    {
        disp[d].Reset(left.Width(),left.Height());
        Set(&disp[d],0);
        for(j=0; j<right.Height()-1; j++)
            for(i=0; i<right.Width()-1; i++)
                if(!(i-d<0))
                    disp[d](i,j)=abs(left(i,j)-right(i-d,j));
        for(int y=0; y<left.Height(); y++)
            for(int x=halfwindow; x<left.Width()-halfwindow; x++)
            {
                int val=0;
                for(int i=0; i<window; i++)
                    val+=kernal[i]*disp[d](x+halfwindow-i,y);
                temp(x,y)=val;
            }
        for(int y=halfwindow; y<left.Height()-halfwindow; y++)
            for(int x=0; x<left.Width(); x++)
            {
                int val1=0;
                for(int i=0; i<window; i++)
                    val1+=kernal[i]*temp(x,y+halfwindow-i);
                disp[d](x,y)=val1;
            }
    }
    return disp;
}
//Left Right Consistency Check using efficient block matching
ImgFloat efficientblockmatch(ImgGray left, ImgGray right)
{
    vector<ImgFloat> dbar;
    dbar=imagedisp(left, right);
    ImgFloat final(left.Width(),left.Height());
    Set(&final,0);
    ImgFloat final1(left.Width(),left.Height());
    Set(&final1,0);
    for(int y=0; y<left.Height(); y++)
        for(int x=0; x<left.Width(); x++)
        {
            int min=9999;
            for(int d=0; d<max_disp; d++)
                if(dbar[d](x,y)<min)
                {
                    min=dbar[d](x,y);
                    final(x,y)=d;
                }
Example #4
0
//Function to compute texture from sample 
void SynthesizeTextureEfrosLeung(const ImgGray& texture, const ImgBinary &mask, int window_width, int window_height,int out_width, int out_height, ImgGray* out)
{
  int height=texture.Height();
  int width=texture.Width();
  bool img_filled=false;
  int win_wid_c=static_cast<int>(blepo_ex::Ceil(window_width/2.0f));
  int win_wid_f=static_cast<int>(blepo_ex::Floor(window_width/2.0f));
  int win_ht_c=static_cast<int>(blepo_ex::Ceil(window_height/2.0f));
  int win_ht_f=static_cast<int>(blepo_ex::Floor(window_height/2.0f));
  int i,j,m,n,k;
  static bool hasnbr=false;
  static int nbr=0;
  ImgGray templates;
  templates.Reset(window_width,window_height);
  ImgBinary img_bin;
  img_bin = mask;

  //Find neighbors
  while(1)
  {
    for(i=win_wid_c;i<(out_width-win_wid_c);i++)
    {
      for(j=win_ht_c;j<(out_height-win_ht_c);j++)
      {
        hasnbr=false;
        nbr=0;
        if(img_bin(i,j)==false)
        {
          for (m=-win_wid_f;m<win_wid_c;m++)
          {
            for (n=-win_ht_f;n<win_ht_c;n++)
            {
              if(img_bin(i+m,j+n)==true)
              {
                nbr=nbr+1;
                hasnbr=true;
              }
            }
          }
        }
        if(hasnbr==true)
        {
          struct PixelInfo pix;
          pix.xc=i;
          pix.yc=j;
          pix.totalnbr=nbr;
          g_pixel.push_back(pix);
        }
      }
    }

    if(g_pixel.size()==0)
    {
      break;
    }
    //Sort list of neighbors
    qsort(&g_pixel[0],g_pixel.size(),sizeof(g_pixel[0]),Compare);


    //Compute best match for window around given pixel
    while(g_pixel.size()!=0)
    {
      struct PixelInfo temp;
      temp=g_pixel.back();  
      g_pixel.pop_back();
      for (i=0;i<window_width;i++)
        for(j=0;j<window_height;j++)
          templates(i,j)=(*out)(temp.xc+i-win_wid_f,temp.yc+j-win_ht_f);
      k=BestMatch(texture,&templates,window_width,window_height,temp.xc,temp.yc,img_bin);
      (*out)(temp.xc,temp.yc)=k;
      img_bin(temp.xc,temp.yc)=true;
    }
  }
}
void GetGradient(ImgGray img, int width, int halfwidth, ImgFloat *outx, ImgFloat *outy, double dervkern[], double kern[])
{
    double sum = 0;
    int x, y, i, j;
    double *temp;
    temp = (double *)calloc(img.Height()*img.Width(), sizeof(double));
    for (y = 0; y < img.Height(); y++)
    {
        for (x = halfwidth; x < img.Width() - halfwidth - 1; x++)
        {
            sum = 0;
            for (i = 0; i < width; i++)
            {
                sum += ((img(x + halfwidth - i, y))*(dervkern[i]));
            }
            temp[y*img.Width() + x] = sum;
        }
    }
    for (y = halfwidth; y < img.Height() - halfwidth - 1; y++)
    {
        for (x = 0; x < img.Width(); x++)
        {
            sum = 0;
            for (i = 0; i < width; i++)
            {
                sum += ((temp[(y + halfwidth - i)* img.Width() + x])*(kern[i]));
            }
            (*outx)(x, y) = sum;
        }
    }

    for (y = 0; y < img.Height(); y++)
    {
        for (x = halfwidth; x < img.Width() - halfwidth - 1; x++)
        {
            sum = 0;
            for (i = 0; i < width; i++)
            {
                sum += ((img(x + halfwidth - i, y))*(kern[i]));
            }
            temp[y*img.Width() + x] = sum;
        }
    }
    for (y = halfwidth; y < img.Height() - halfwidth - 1; y++)
    {
        for (x = 0; x < img.Width(); x++)
        {
            sum = 0;
            for (i = 0; i < width; i++)
            {
                sum += ((temp[(y + halfwidth - i)*img.Width() + x])*(dervkern[i]));
            }
            (*outy)(x, y) = sum;
        }
    }

}
int main(int argc, const char* argv[], const char* envp[])
{
    // Initialize MFC and return if failure
    HMODULE hModule = ::GetModuleHandle(NULL);
    if (hModule == NULL || !AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
    {
        printf("Fatal Error: MFC initialization failed (hModule = %x)\n", hModule);
        return 1;
    }


    try
    {
        //Read sigma value
        float sigma = atof(argv[1]);

        //Read first image name
        string argument2 = argv[2];
        string path = "../../images/";
        string filename1 = path + argument2;
        const char *file1 = filename1.c_str();

        ImgGray inputImage;
        Load(file1, &inputImage);

        ImgBgr finalImage;
        Load(file1, &finalImage);

        Figure fig1;
        fig1.SetTitle("Original Image");
        fig1.Draw(inputImage);

        //If third argument exists

        ImgGray templateImage;
        ImgBinary temphysteresisImage;


        //calculate width
        int mu = (int)(2.5*sigma - 0.5);
        int w = 2 * mu + 1;
        double *gauss;
        double *gaussDeriv;
        double sumGauss = 0;
        double sumGaussDeriv = 0;

        gauss = (double*)calloc(w, sizeof(double));
        gaussDeriv = (double*)calloc(w, sizeof(double));

        printf("width = %d\n", w);
        printf("mu = %d\n", mu);

        //create gaussian kernel
        for (int i = 0; i < w; i++)
        {
            gauss[i] = exp((-(i - mu)*(i - mu)) / (2 * sigma*sigma));
            sumGauss += gauss[i];

            gaussDeriv[i] = (i - mu)*gauss[i];
            sumGaussDeriv += gaussDeriv[i] * i;
        }

        for (int j = 0; j < w; j++)
        {
            gauss[j] = gauss[j] / sumGauss;
            gaussDeriv[j] = gaussDeriv[j] / sumGaussDeriv;
        }

        //Print Gaussian Kernel
        printf("Gaussian Kernel = [");
        for (int i = 0; i < w; i++)
        {
            printf("%f ", gauss[i]);
        }
        printf("]\n");

        //Print Gaussian Derivative kernel
        printf("Gaussian Derivative = [");
        for (int i = 0; i < w; i++)
        {
            printf("%f ", gaussDeriv[i]);
        }
        printf("]\n");

        //Compute gradient of the image
        ImgFloat grad_x, grad_y;

        grad_x.Reset(inputImage.Width(), inputImage.Height());
        grad_y.Reset(inputImage.Width(), inputImage.Height());

        Set(&grad_x, 0);
        Set(&grad_y, 0);

        // Calculate Gradient
        GetGradient(inputImage, w, mu, &grad_x, &grad_y, gaussDeriv, gauss);

        Figure fig2, fig3;
        fig2.SetTitle("X-Gradient");
        fig2.Draw(grad_x);
        fig3.SetTitle("Y-Gradient");
        fig3.Draw(grad_y);

        //Calculate gradient magnitude and phase
        ImgFloat gradMagnitude, gradPhase, outputGrad;

        outputGrad.Reset(inputImage.Width(), inputImage.Height());
        gradMagnitude.Reset(inputImage.Width(), inputImage.Height());
        gradPhase.Reset(inputImage.Width(), inputImage.Height());

        Set(&gradMagnitude, 0);
        Set(&gradPhase, 0);
        Set(&outputGrad, 0);

        //Compute Gradient magnitude for input
        for (int y = mu; y < inputImage.Height() - mu; y++)
        {
            for (int x = mu; x < inputImage.Width() - mu; x++)
            {
                gradMagnitude(x, y) = max(abs(grad_x(x, y)), abs(grad_y(x, y)));
            }

        }

        //Compute Gradient phase for input
        for (int y = mu; y < inputImage.Height() - mu; y++)
        {
            for (int x = mu; x < inputImage.Width() - mu; x++)
            {
                float theta = atan2(grad_y(x, y), grad_x(x, y));
                gradPhase(x, y) = theta*180/PI;

                while (theta > 157.5)
                {
                    theta -= 180;
                }

                if (theta >= -22.5 && theta < 22.5)
                {
                    if (gradMagnitude(x, y) < gradMagnitude(x - 1, y) || (gradMagnitude(x, y) < gradMagnitude(x + 1, y)))
                    {
                        outputGrad(x, y) = 0;
                    }
                    else
                    {
                        outputGrad(x, y) = gradMagnitude(x, y);
                    }
                }
                else if (theta >= 22.5 && theta < 67.5)
                {
                    if (gradMagnitude(x, y) < gradMagnitude(x - 1, y - 1) || (gradMagnitude(x, y) < gradMagnitude(x + 1, y + 1)))
                    {
                        outputGrad(x, y) = 0;
                    }
                    else
                    {
                        outputGrad(x, y) = gradMagnitude(x, y);
                    }
                }
                else if (theta >= 67.5 && theta < 112.5)
                {
                    if (gradMagnitude(x, y) < gradMagnitude(x, y - 1) || (gradMagnitude(x, y) < gradMagnitude(x, y + 1)))
                    {
                        outputGrad(x, y) = 0;
                    }
                    else
                    {
                        outputGrad(x, y) = gradMagnitude(x, y);
                    }
                }
                else if (theta >= 112.5 && theta < 157.5)
                {
                    if (gradMagnitude(x, y) < gradMagnitude(x - 1, y + 1) || (gradMagnitude(x, y) < gradMagnitude(x + 1, y - 1)))
                    {
                        outputGrad(x, y) = 0;
                    }
                    else
                    {
                        outputGrad(x, y) = gradMagnitude(x, y) ;
                    }
                }
            }
        }


        //Find threshold for input image
        int highThreshold = 0, lowThreshold = 0;

        double *temporaryArray;
        temporaryArray = (double*)calloc(inputImage.Height()*inputImage.Width(), sizeof(double));
        for (int y = 0; y < (inputImage.Height()); y++)
        {
            for (int x = 0; x < inputImage.Width(); x++)
            {
                temporaryArray[y*inputImage.Width() + x] = gradMagnitude(x, y);
            }
        }

        std::vector<double> sortedmagArray(temporaryArray, temporaryArray + (inputImage.Height()*inputImage.Width()));
        std::sort(sortedmagArray.begin(), sortedmagArray.end());

        highThreshold = sortedmagArray[0.9*(inputImage.Height()*inputImage.Width())];

        lowThreshold = highThreshold / 5;

        ImgBinary highImage, lowImage, hysteresisImage;
        highImage.Reset(inputImage.Width(), inputImage.Height());
        lowImage.Reset(inputImage.Width(), inputImage.Height());
        hysteresisImage.Reset(inputImage.Width(), inputImage.Height());

        Set(&highImage, 0);
        Set(&lowImage, 0);
        Set(&hysteresisImage, 0);


        DoubleThresholding(&inputImage, &highImage, &lowImage, &hysteresisImage, &outputGrad, highThreshold, lowThreshold);

        ImgInt chamferImage;
        chamferImage.Reset(inputImage.Width(), inputImage.Height());
        Set(&chamferImage, 100);
        GetChamferDistance(hysteresisImage, &chamferImage);

        //Edge template matching
        ImgFloat probabilityMap;
        probabilityMap.Reset(inputImage.Width(), inputImage.Height());
        Set(&probabilityMap, 255);



        if (argc == 4)
        {
            string argument3 = argv[3];
            string filename2 = path + argument3;
            const char *file2 = filename2.c_str();

            Load(file2, &templateImage);

            Figure fig8;
            fig8.SetTitle("Template Image");
            fig8.Draw(templateImage);

            ImgFloat tmplate_x, tmplate_y;
            tmplate_x.Reset(templateImage.Width(), templateImage.Height());
            tmplate_y.Reset(templateImage.Width(), templateImage.Height());

            Set(&tmplate_x, 0);
            Set(&tmplate_y, 0);

            GetGradient(templateImage, w, mu, &tmplate_x, &tmplate_y, gaussDeriv, gauss);

            ImgFloat templateMagnitude, templatePhase, templateOutputGrad;

            templateMagnitude.Reset(templateImage.Width(), templateImage.Height());
            templatePhase.Reset(templateImage.Width(), templateImage.Height());
            templateOutputGrad.Reset(templateImage.Width(), templateImage.Height());

            Set(&templateMagnitude, 0);
            Set(&templatePhase, 0);
            Set(&templateOutputGrad, 0);

            //Compute Gradient magnitude for template
            for (int y = mu; y < templateImage.Height() - mu; y++)
            {
                for (int x = mu; x < templateImage.Width() - mu; x++)
                {
                    templateMagnitude(x, y) = max(abs(tmplate_x(x, y)), abs(tmplate_y(x, y)));
                }
            }

            //Compute Gradient phase for template
            for (int y = mu; y < templateImage.Height() - mu; y++)
            {
                for (int x = mu; x < templateImage.Width() - mu; x++)
                {
                    float theta = atan2(tmplate_y(x, y), tmplate_x(x, y));
                    templatePhase(x, y) = theta * 180 / PI;

                    while (theta > 157.5)
                    {
                        theta -= 180;
                    }

                    if (theta >= -22.5 && theta < 22.5)
                    {
                        if (templateMagnitude(x, y) < templateMagnitude(x - 1, y) || (templateMagnitude(x, y) < templateMagnitude(x + 1, y)))
                        {
                            templateOutputGrad(x, y) = 0;
                        }
                        else
                        {
                            templateOutputGrad(x, y) = templateMagnitude(x, y);
                        }
                    }
                    else if (theta >= 22.5 && theta < 67.5)
                    {
                        if (templateMagnitude(x, y) < templateMagnitude(x - 1, y - 1) || (templateMagnitude(x, y) < templateMagnitude(x + 1, y + 1)))
                        {
                            templateOutputGrad(x, y) = 0;
                        }
                        else
                        {
                            templateOutputGrad(x, y) = templateMagnitude(x, y);
                        }
                    }
                    else if (theta >= 67.5 && theta < 112.5)
                    {
                        if (templateMagnitude(x, y) < templateMagnitude(x, y - 1) || (templateMagnitude(x, y) < templateMagnitude(x, y + 1)))
                        {
                            templateOutputGrad(x, y) = 0;
                        }
                        else
                        {
                            templateOutputGrad(x, y) = templateMagnitude(x, y);
                        }
                    }
                    else if (theta >= 112.5 && theta < 157.5)
                    {
                        if (templateMagnitude(x, y) < templateMagnitude(x - 1, y + 1) || (templateMagnitude(x, y) < templateMagnitude(x + 1, y - 1)))
                        {
                            templateOutputGrad(x, y) = 0;
                        }
                        else
                        {
                            templateOutputGrad(x, y) = templateMagnitude(x, y);
                        }
                    }
                }
            }

            //Find threshold for template image
            int tempHighThreshold = 0, tempLowThreshold = 0;
            double *tempArray;
            tempArray = (double*)calloc(templateImage.Height()*templateImage.Width(), sizeof(double));
            for (int y = 0; y < (templateImage.Height()); y++)
            {
                for (int x = 0; x < templateImage.Width(); x++)
                {
                    tempArray[y*templateImage.Width() + x] = templateMagnitude(x, y);
                }
            }

            std::vector<double> sortedtempArray(tempArray, tempArray + (templateImage.Height()*templateImage.Width()));
            std::sort(sortedtempArray.begin(), sortedtempArray.end());

            tempHighThreshold = sortedtempArray[0.9*(templateImage.Height()*templateImage.Width())];
            tempLowThreshold = tempHighThreshold / 5;

            ImgBinary temphighImage, templowImage;
            temphighImage.Reset(templateImage.Width(), templateImage.Height());
            templowImage.Reset(templateImage.Width(), templateImage.Height());
            temphysteresisImage.Reset(templateImage.Width(), templateImage.Height());

            Set(&temphighImage, 0);
            Set(&templowImage, 0);
            Set(&temphysteresisImage, 0);

            DoubleThresholding(&templateImage, &temphighImage, &templowImage, &temphysteresisImage, &templateOutputGrad, tempHighThreshold, tempLowThreshold);

        }


        //Create Inverse probability map
        for (int y = 0; y < (inputImage.Height() - templateImage.Height()); y++)
        {
            for (int x = 0; x < (inputImage.Width() - templateImage.Width()); x++)
            {
                int matchSum = 0;
                for (int j = 0; j < templateImage.Height(); j++)
                {
                    for (int i = 0; i < templateImage.Width(); i++)
                    {
                        matchSum += temphysteresisImage(i, j)*hysteresisImage(x + i, y + j);
                    }
                }
                probabilityMap(x, y) = 255-matchSum;
            }
        }

        //Find match in inverse probability map
        int probability = probabilityMap(0, 0);
        int col = 0, row = 0;

        for (int y = 0; y < inputImage.Height(); y++)
        {
            for (int x = 1; x < inputImage.Width(); x++)
            {
                if (probabilityMap(x, y) < probability)
                {
                    probability = probabilityMap(x, y);
                    col = x;
                    row = y;
                }
            }
        }

        //Draw a rectangle around detected object
        Rect objectFound(col, row, col + templateImage.Width(), row + templateImage.Height());
        DrawRect(objectFound, &finalImage, Bgr(0,255,0));

        //Output Images
        Figure fig4, fig5, fig6, fig7, fig9;
        fig4.SetTitle("Magnitude of Gradient");
        fig4.Draw(gradMagnitude);
        fig5.SetTitle("Phase of Gradient");
        fig5.Draw(gradPhase);
        fig9.SetTitle("Non-maximal suppression image");
        fig9.Draw(outputGrad);
        fig6.SetTitle("Canny edge detection of input image");
        fig6.Draw(hysteresisImage);
        fig7.SetTitle("Chamfer distance image");
        fig7.Draw(chamferImage);

        if (argc == 4)
        {
            Figure  fig10, fig11, fig12;
            fig10.SetTitle("Canny edge detection of template image");
            fig10.Draw(temphysteresisImage);
            fig12.SetTitle("Inverse Probability Map");
            fig12.Draw(probabilityMap);
            fig11.SetTitle("Final image - Object found!");
            fig11.Draw(finalImage);
        }
        EventLoop();
    }
    catch (const Exception& e)
    {
        e.Display();    // display exception to user in a popup window
    }
    return 0;
}