MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connect(ui->openButton, SIGNAL(clicked()), this, SLOT(Open())); connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(SaveImage())); connect(ui->SSDButton, SIGNAL(clicked()), this, SLOT(SSD())); connect(ui->SADButton, SIGNAL(clicked()), this, SLOT(SAD())); connect(ui->NCCButton, SIGNAL(clicked()), this, SLOT(NCC())); connect(ui->GTCheckBox, SIGNAL(clicked()), this, SLOT(GTOnOff())); connect(ui->gaussianButton, SIGNAL(clicked()), this, SLOT(Gaussian())); connect(ui->maxButton, SIGNAL(clicked()), this, SLOT(FindBestDisparity())); connect(ui->bilateralButton, SIGNAL(clicked()), this, SLOT(Bilateral())); connect(ui->segmentButton, SIGNAL(clicked()), this, SLOT(Segment())); connect(ui->renderButton, SIGNAL(clicked()), this, SLOT(Render())); connect(ui->renderSlider, SIGNAL(valueChanged(int)), this, SLOT(RenderSlider(int))); connect(ui->magicButton, SIGNAL(clicked()), this, SLOT(MagicStereo(int))); ui->GTCheckBox->setChecked(true); ui->pixelErrorLabel->setText(""); ui->gaussianSigmaSpinBox->setValue(1.0); ui->biSigmaSSpinBox->setValue(1.0); ui->biSigmaISpinBox->setValue(20.0); ui->renderSlider->setValue(100); ui->SADOffsetBox->setValue(2); ui->SSDOffsetBox->setValue(2); ui->NCCOffsetBox->setValue(2); ui->segmentGridBox->setValue(20); ui->segmentColorSpinBox->setValue(20.0); ui->segmentSpatialSpinBox->setValue(6.0); ui->segmentIterBox->setValue(4); m_Image1Display.setParent(ui->tab); m_Image2Display.setParent(ui->tab_2); m_GTDisplay.setParent(ui->tab_4); m_DisparityDisplay.setParent(ui->tab_3); m_ErrorDisplay.setParent(ui->tab_5); m_RenderDisplay.setParent(ui->tab_6); m_SegmentDisplay.setParent(ui->tab_7); m_Image1Display.window = this; m_Image2Display.window = this; m_GTDisplay.window = this; m_DisparityDisplay.window = this; m_ErrorDisplay.window = this; m_RenderDisplay.window = this; m_SegmentDisplay.window = this; ui->tabWidget->setCurrentIndex(0); m_LastRow = 0; m_SegmentIteration = 0; m_MatchCost = NULL; }
/*! * \brief updates the disparity space which contains matching correlation values for each possible disparity * \param img_left colour data for the left image2 * \param img_right colour data for the right image * \param img_width width of the image * \param img_height height of the image * \param offset_x calibration offset x * \param offset_y calibration offset y * \param vertical_sampling vertical sampling rate - we don't need every row * \param max_disparity_percent maximum disparity as a percentage of image width * \param correlation_radius radius in pixels used for patch matching * \param smoothing_radius radius in pixels used for smoothing of the disparity space * \param disparity_step step size for sampling different disparities * \param disparity_space_width width of the disparity space * \param disparity_space_height height of the disparity space * \param disparity_space array used for the disparity space */ void stereodense::update_disparity_space( unsigned char* img_left, unsigned char* img_right, int img_width, int img_height, int offset_x, int offset_y, int vertical_sampling, int max_disparity_percent, int correlation_radius, int smoothing_radius, int disparity_step, int disparity_space_width, int disparity_space_height, unsigned int *disparity_space) { int patch_pixels = correlation_radius*2+1; patch_pixels *= patch_pixels; unsigned int max_patch_value = (unsigned int)(3*255*patch_pixels); int max_disparity = max_disparity_percent * img_width / 100; int img_height2 = img_height / vertical_sampling; int width2 = img_width / smoothing_radius; int height2 = img_height2 / STEREO_DENSE_SMOOTH_VERTICAL; int width3 = img_width / (smoothing_radius*STEREO_DENSE_OUTER_DIVISOR); int ty = 0; int by = img_height; if (offset_y >= 0) by = img_height - offset_y; else ty = -offset_y; int disparity_space_pixels = disparity_space_width*disparity_space_height; int no_of_disparities = max_disparity / disparity_step; // clear disparity space memset((void*)disparity_space,'\0', no_of_disparities*disparity_space_pixels*2*sizeof(unsigned int)); // test a number of possible disparities in parallel #pragma omp parallel for for (int disparity_index = 0; disparity_index < no_of_disparities; disparity_index++) { // disparity in pixels int disparity = disparity_index * disparity_step; // offset within the disparity space array int disparity_space_offset = disparity_index*disparity_space_pixels*2; // insert correlation values into the disparity space #pragma omp parallel for for (int y2 = 0; y2 < by/vertical_sampling; y2++) { int y = y2*vertical_sampling; int yy = y2 / STEREO_DENSE_SMOOTH_VERTICAL; if ((y >= ty) && (yy > 1) && (yy < height2-2)) { int yy2 = yy/STEREO_DENSE_OUTER_DIVISOR; int x_right = -offset_x - disparity + correlation_radius; int offsetx0 = x_right - correlation_radius; if (offsetx0 < 0) { offsetx0 = correlation_radius - offsetx0; } else { offsetx0 = correlation_radius; } int offsetx1 = img_width - offset_x - correlation_radius; if (offsetx1 >= img_width-correlation_radius) { offsetx1 = img_width-correlation_radius-1; } // for all pixels along the row for (int x_left = offsetx0; x_left < offsetx1; x_left++, x_right++) { int xx_inner = x_left / smoothing_radius; if ((xx_inner > 1) && (xx_inner < width2-2)) { int sad = SAD( img_left,img_right,img_width,img_height, x_left, y, x_right, y - offset_y, correlation_radius); if (sad != BAD_MATCH) { unsigned int v = max_patch_value - (unsigned int)sad; int n_inner = (yy*width2 + xx_inner) + disparity_space_offset; disparity_space[n_inner] += v; int n_outer = (yy2*width3 + (x_left / (smoothing_radius*STEREO_DENSE_OUTER_DIVISOR))) + disparity_space_offset + disparity_space_pixels; disparity_space[n_outer] += v; } } } } } } }
int main() { //initiation const char* imgname[4]={"Tsukuba","Venus","Teddy","Cones"}; int MAX_Disp[4]={16,20,60,60}; int scale[4]={16,8,4,4}; char imL[30],imR[30],imDisp[30],truedisp[30],non_occ[30]; IplImage *pImgl,*pImgr,*pDisp,*pTruedisp,*pNon_occ; int w,h,step; //width,height,widthStep unsigned char *left,*right,*disp,*groundtruth,*nonocc; float time,err_nonocc; for(int i=0;i<4;i++) { sprintf(imL,"img/%s/imL.png",imgname[i]); sprintf(imR,"img/%s/imR.png",imgname[i]); sprintf(truedisp,"img/%s/groundtruth.png",imgname[i]); sprintf(non_occ,"img/%s/nonocc.png",imgname[i]); printf("loading %s\n",imgname[i]); pImgl = cvLoadImage(imL,0); if(pImgl == NULL) printf("cannot open imgl!\n"); pImgr = cvLoadImage(imR,0); if(pImgr == NULL) printf("cannot open imgr!\n"); pTruedisp = cvLoadImage(truedisp,0); if(pTruedisp == NULL) printf("cannot open truedisp!\n"); pNon_occ = cvLoadImage(non_occ,0); if(pNon_occ == NULL) printf("cannot open non_occ!\n"); pDisp = cvCreateImage(cvGetSize(pImgl),pImgl->depth,pImgl->nChannels); w=pImgl->width; h=pImgl->height; step=pImgl->widthStep; left = new unsigned char[w*h]; right = new unsigned char[w*h]; disp = new unsigned char[w*h]; groundtruth = new unsigned char[w*h]; nonocc = new unsigned char[w*h]; for(int y=0;y<h;y++) for(int x=0;x<w;x++) { left[y*w+x] =(unsigned char) pImgl->imageData[y*step+x]; right[y*w+x] =(unsigned char) pImgr->imageData[y*step+x]; groundtruth[y*w+x] =(unsigned char) pTruedisp->imageData[y*step+x]; nonocc[y*w+x] =(unsigned char) pNon_occ->imageData[y*step+x]; } //SAD time=SAD(left,right,disp,w,h,MAX_Disp[i],scale[i]); err_nonocc = eval_nonocc(groundtruth,disp,nonocc,w,h,scale[i]); for(int y=0;y<h;y++) for(int x=0;x<w;x++) pDisp->imageData[y*step+x] = (char)disp[y*w+x]; sprintf(imDisp,"img/%s/disp_SAD.png",imgname[i]); cvSaveImage(imDisp,pDisp); printf("SAD algorithm\n"); printf("proccessing time:\t%6.3fms\n",time); printf("Percentage of Bad Matching pixels:\t%6.3f%%\n",err_nonocc*100); //SSD time=SSD(left,right,disp,w,h,MAX_Disp[i],scale[i]); err_nonocc = eval_nonocc(groundtruth,disp,nonocc,w,h,scale[i]); for(int y=0;y<h;y++) for(int x=0;x<w;x++) pDisp->imageData[y*step+x] = (char)disp[y*w+x]; sprintf(imDisp,"img/%s/disp_SSD.png",imgname[i]); cvSaveImage(imDisp,pDisp); printf("SSD algorithm\n"); printf("proccessing time:\t%6.3fms\n",time); printf("Percentage of Bad Matching pixels:\t%6.3f%%\n",err_nonocc*100); //cudaSSD time = cudaSSD(left,right,disp,w,h,MAX_Disp[i],scale[i]); err_nonocc = eval_nonocc(groundtruth,disp,nonocc,w,h,scale[i]); for(int y=0;y<h;y++) for(int x=0;x<w;x++) pDisp->imageData[y*step+x] = (char)disp[y*w+x]; sprintf(imDisp,"img/%s/disp_cudaSSD.png",imgname[i]); cvSaveImage(imDisp,pDisp); printf("cudaSSD algorithm\n"); printf("proccessing time:\t%6.3fms\n",time); printf("Percentage of Bad Matching pixels:\t%6.3f%%\n",err_nonocc*100); /* //cudaSAD time = cudaSAD(left,right,disp,w,h,MAX_Disp[i],scale[i]); err_nonocc = eval_nonocc(groundtruth,disp,nonocc,w,h,scale[i]); for(int y=0;y<h;y++) for(int x=0;x<w;x++) pDisp->imageData[y*step+x] = (char)disp[y*w+x]; sprintf(imDisp,"img/%s/disp_cudaSAD.png",imgname[i]); cvSaveImage(imDisp,pDisp); printf("cudaSAD algorithm\n"); printf("proccessing time:\t%6.3fms\n",time); printf("Percentage of Bad Matching pixels:\t%6.3f%%\n",err_nonocc*100); */ printf("\n"); delete []left; delete []right; delete []disp; } return 0; }
//full Search algorithm - comparing one actual block to the reference frame void fullSearch(int width, int height, int blockSize,IN int *blockIndex,IN unsigned char *input,IN unsigned char *reference,OUT int *output_x,OUT int *output_y) { int i,j; unsigned long sad; unsigned long pre = ULONG_MAX; int position[2]={0,0}; int mv[2]={0,0}; int nblockH = (height + blockSize - height%blockSize)/blockSize; int nblockW = (width + blockSize - width%blockSize)/blockSize; int currentIndex = *blockIndex; // should apply only to first frame with no reference on input if(*reference == '\0' || reference == NULL) { memset(output_x,0,1); memset(output_y,0,1); return; } //search only neighbour area - set loop variables int iMax,jMax; int search = 3*blockSize; iMax = (currentIndex/nblockW)*blockSize + search; jMax = (currentIndex%nblockW)*blockSize + search; i = (currentIndex/nblockW)*blockSize - search; j = (currentIndex%nblockW)*blockSize - search; i= i<0 ? 0 : i; j= j<0 ? 0 : j; iMax = iMax>(height-blockSize)? (height - blockSize):iMax; jMax = jMax>(width-blockSize)? (width - blockSize):jMax; //start loop for(i;i<iMax;i++){ for(j;j<jMax;j++){ sad = SAD(reference+j+i*width,input,blockSize,width); if (pre>sad){ pre=sad; position[0]=j; position[1]=i;// we get position of the best corresponding block } } } mv[0]=(currentIndex%nblockW)*blockSize - (position[0]); mv[1]=(currentIndex/nblockW)*blockSize - (position[1]);// calculate the movement vector, integer division // // memset(output_x+currentIndex,mv[0],1); // memset(output_y+currentIndex,mv[1],1); *output_x = mv[0]; *output_y = mv[1]; //printf("PRE: %lu \n", pre); //printf("pos_x: %d \t pos_y: %d \n", position[0],position[1]); //printf("index: %d \t x: %d \t y: %d \n", currentIndex, mv[0], mv[1]); return; }