//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; }
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; }
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; }