//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;
}
예제 #2
0
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;
}
예제 #3
0
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;
	}

	if (argc >=3){
		cout<<"Programme is working"<<endl;
	}
	else{
		cout<<"Wrong number of arguments"<<endl;
	}


	try
	{

		double maxdisparity;										//User defined sigma value
		CString lfilename;										//Entered image by the user
		CString rfilename;										//Entered image by the user
		lfilename=argv[1];										//Reading the name of the image to be loaded
		rfilename=argv[2];										//Reading the name of the image to be loaded
		maxdisparity=atof(argv[3]);									//Reading sigma from the provided arguments

		//Loading original image
		ImgBgr img1b; 											//Declaring BGR image
		ImgGray img1;											//Declaring a grayscale image
		Load(lfilename, &img1b);									//Loading the BGR image
		Convert(img1b, &img1);										//Loading the BGR image into img1 as a grayscale image

		ImgFloat dmap;
		dmap.Reset(img1.Width(),img1.Height());
		Set(&dmap,0);

		ImgFloat dmaplrf;
		dmaplrf.Reset(img1.Width(),img1.Height());
		Set(&dmaplrf,0);

		ImgFloat dmaplr;
		dmaplr.Reset(img1.Width(),img1.Height());
		Set(&dmaplr,0);

		ImgFloat dmaplr1;
		dmaplr1.Reset(img1.Width(),img1.Height());
		Set(&dmaplr1,0);

		ImgFloat dmaplr2;
		dmaplr1.Reset(img1.Width(),img1.Height());
		Set(&dmaplr1,0);

		ImgBgr img2b; 											//Declaring BGR image
		ImgGray img2b;											//Declaring a grayscale image
		Load(rfilename, &img2b);									//Loading the BGR image
		Convert(img2b, &img2);										//Loading the BGR image into img1 as a grayscale image

		Figure fig1("Left image BGR");									//Displaying original image 
		fig1.Draw(img1b);							 
		Figure fig2("Right image BGR");									//Displaying BGR image
		fig2.Draw(img2b);
		Figure fig3("Left image");									//Displaying original image 
		fig3.Draw(img1);		 
		Figure fig4("Right image");									//Displaying BGR image
		fig4.Draw(img2);

		
		ImgFloat tmp;											//Intermediate image in convolution
		tmp.Reset(img1.Width(),img1.Height());
		Set(&tmp,0);

		ImgFloat cnvout;										//Intermediate image in convolution
		cnvout.Reset(img1.Width(),img1.Height());
		Set(&cnvout,0);

		ImgFloat depth;											//Intermediate image in convolution
		depth.Reset(img1.Width(),img1.Height());
		Set(&depth,0);

		int k=1315;

		std::vector<ImgFloat> a(maxdisparity);								//Vector of images to be stored according to order of disparity
		ImgFloat ds;											//Intermediate image in convolution
		ds.Reset(img1.Width(),img1.Height());
		Set(&cnvout,0);

		for(int d=0;d<maxdisparity;d++)
		{
			a[d].Reset(img1.Width(),img1.Height());
			Set(&a[d],0);
			for(int y=0;y<img1.Height()-1;y++)
			{
				for(int x=0;x<img1.Width()-1;x++)
				{
					if((x-d)>=0)
					{
						a[d](x,y)=abs(img1(x,y)-img2(x-d,y));
					}
				}
			}
		}
		float val;
		int x;
		int y;
		int i;

		int ar[7]={1,1,1,1,1,1,1};

		for(int d=0;d<maxdisparity;d++)
		{								//computing disparity map
			for(y=0;y<img1.Height();y++){
				for(x=3;x<(img1.Width()-3);x++){
					val=0;
					for(i=0;i<7;i++){
						val=val+ar[i]*a[d](x+3-i,y);
					}
					tmp(x,y)=val;					
				}
			}
			for(y=3;y<(img1.Height()-3);y++)
			{
				for(x=0;x<img1.Width();x++)
				{
					val=0;
					for(i=0;i<7;i++)
					{
						val=val+ar[i]*tmp(x,y+3-i);
					}
				    a[d](x,y)=val;
				}
			}			
		} 	
		
		for(y=0;y<img1.Height();y++)
		{
				for(x=0;x<img1.Width();x++)
				{
					int gc=999999;
					for(int d=0;d<maxdisparity;d++)
					{
						if(a[d](x,y)<gc)
						{
							gc=a[d](x,y);
							dmap(x,y)=d;
						}
					}
				}
		}
		Figure fig5("Disparity map");									//Displaying disparity map image
		fig5.Draw(dmap);

		for(y=0;y<img1.Height();y++){							
				for(x=0;x<img1.Width();x++)
				{
					int gc=999999;
					for(int d=0;d<maxdisparity;d++)
					{
						if(a[d](x,y)<gc)
						{
							gc=a[d](x,y);
							dmaplr(x,y)=d;
						}
					}
				}
		}

		for(y=0;y<img1.Height();y++)
		{
			for(x=0;x<img1.Width();x++)
			{
				int gc=999999;
				for(int d=0;d<maxdisparity;d++)
				{
					if((x-dmaplr(x,y)+d)>0 && (x-dmaplr(x,y)+d)<img1.Width())
					{
						if(a[d](x-dmaplr(x,y)+d,y)<gc)
						{
							gc=a[d](x-dmaplr(x,y)+d,y);
							dmaplr1(x,y)=d;
						}							
					}
				}
			}
		}

		for(y=0;y<img1.Height();y++)
		{
			for(x=0;x<img1.Width();x++)
			{
				if(dmaplr(x,y)==dmaplr1(x,y))
				{
					dmaplrf(x,y)=dmaplr(x,y);
				}
				else
				{
					dmaplrf(x,y)=0;
				}
			}
		}

		Figure fig6("Disparity map with left right consistency check");					//Displaying disparity map with left right consistency check
		fig6.Draw(dmaplrf);

		for(y=0;y<img1.Height();y++)
		{
			for(x=0;x<img1.Width();x++)
			{
				if(dmaplrf(x,y)!=0)
				{
					depth(x,y)=k/dmaplrf(x,y);
				}
			}
		}

		Figure fig7("Depth image");									//Displaying depth image
		fig7.Draw(depth);

		int vertices=0;

		for(y=0;y<img1.Height();y++)
		{
			for(x=0;x<img1.Width();x++)
			{
				if(dmaplrf(x,y)!=0)
				{
					vertices++;
				}
			}
		}
		cout<<endl<<"Vertices="<<vertices<<endl;

		//Writing out 3-D image into .ply format that can be viewed in Meshlab
		ofstream myply; 
		myply.open("myply.ply");
		myply<<"ply"<<endl<<"format ascii 1.0"<<endl<<"element vertex "<<vertices<<endl<<"property float x"<<endl<<"property float y"<<endl<<"property float z"<<endl<<"property uchar diffuse_red"<<endl<<"property uchar diffuse_green"<<endl<<"property uchar diffuse_blue"<<endl<<"end_header"<<endl;

		for(y=0;y<img1.Height();y++)
		{
			for(x=0;x<img1.Width();x++)
			{
				if(depth(x,y)>0)
				{
					myply<<x<<" "<<-y<<" "<<-depth(x,y)<<" "<<(int)img1b(x,y).r<<" "<<(int)img1b(x,y).g<<" "<<(int)img1b(x,y).b<<endl;
				}
			}
		}
		EventLoop();
	}
	

	catch (const Exception& e)
	{
		e.Display();    										// display exception to user in a popup window 
	}
	return 0;
}