bool imageCompareBase::filterKeyEvent(QKeyEvent* event) {

  if (event->key() == Qt::Key_Left &&
      (event->modifiers() & Qt::ShiftModifier) && leftImage() &&
      leftScroll_->isVisible() && curImage() != leftImage()) {
    setCur(leftImage());
    return true;
  }
  else if (event->key() == Qt::Key_Right &&
           (event->modifiers() & Qt::ShiftModifier) && rightImage() &&
           rightScroll_->isVisible() && curImage() != rightImage()) {
    setCur(rightImage());
    return true;
  }
  else if ((event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)
           && (event->modifiers() & Qt::ShiftModifier)
           && (leftScroll_->isVisible() || rightScroll_->isVisible())) {
    comboBox* curBox =
      (leftImage() == curImage()) ? leftImageListBox_ : rightImageListBox_;
    if (event->key() == Qt::Key_Up) {
      curBox->moveToPreviousItem();
    }
    else {
      curBox->moveToNextItem();
    }
    return true;
  }
  return false;
}
void ComputationDataCPU::updateLeftMonitor( Monitor &mon )
{
    if( rightImage() )
    {
        mon.updateWithImageBuffer( (unsigned char*)leftImage()->imageData, leftImage()->width, leftImage()->height, 1 );
    }
}
void imageCompareBase::centerSplitter() {

  // [inexplicably, qsplitter doesn't honor small sizes, like 7,7, by which
  // I mean the actual splitter sizes set by those inputs are not equal -
  // I'm ignoring that case]
  QList<int> splitterWidths;
  splitterWidths << (leftImage() ? leftImage()->scaledWidth() : 0)
                 << (rightImage() ? rightImage()->scaledWidth() : 0);
  splitter_->setSizes(splitterWidths);
}
void imageCompareBase::updateScrollValues() {

  if (dualScrollingAction_->isChecked() && leftImage() && rightImage()) {
    if (curImage() == leftImage()) {
      processLHSBsliderMoved(leftScroll_->horizontalScrollBar()->value());
      processLVSBsliderMoved(leftScroll_->verticalScrollBar()->value());
    }
    else {
      processRHSBsliderMoved(rightScroll_->horizontalScrollBar()->value());
      processRVSBsliderMoved(rightScroll_->verticalScrollBar()->value());
    }
  }
}
bool imageCompareBase::eventFilter(QObject* watched, QEvent* event) {

  // make sure we setCur on an image click
  if (event->type() == QEvent::FocusIn) {
    if (watched == leftScroll_) {
      setCur(leftImage());
    }
    else {
      setCur(rightImage());
    }
  }
  else if (event->type() == QEvent::KeyPress) {
    QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
    return filterKeyEvent(keyEvent);
  }
  else if (event->type() == QEvent::Wheel) {
    QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
    // shift scroll should give a horizontal scroll
    if (wheelEvent->modifiers() == Qt::ShiftModifier) {
      // must check both the scroll and its viewport
      if (watched == rightScroll_ || watched == rightScroll_->viewport()) {
        rightScroll_->horizontalScrollBar()->event(event);
        return true;
      }
      else if (watched == leftScroll_ || watched == leftScroll_->viewport()) {
        leftScroll_->horizontalScrollBar()->event(event);
        return true;
      }
    }
  }
  return imageSaverWindow::eventFilter(watched, event);
}
int main(int argc, char* argv[]) {
	if (argc < 5) {
		std::cerr << "usage: sgmstereo left right leftOut rightOut" << std::endl;
		exit(1);
	}
    
    std::string leftImageFilename = argv[1];
    std::string rightImageFilename = argv[2];
    
    png::image<png::rgb_pixel> leftImage(leftImageFilename);
	png::image<png::rgb_pixel> rightImage(rightImageFilename);

	SPSStereo sps;
    sps.setIterationTotal(outerIterationTotal, innerIterationTotal);
    sps.setWeightParameter(lambda_pos, lambda_depth, lambda_bou, lambda_smo);
    sps.setInlierThreshold(lambda_d);
    sps.setPenaltyParameter(lambda_hinge, lambda_occ, lambda_pen);
    
	png::image<png::gray_pixel_16> segmentImage;
	png::image<png::gray_pixel_16> disparityImage;
	png::image<png::gray_pixel_16> disparityImageRight;
	std::vector< std::vector<double> > disparityPlaneParameters;
	std::vector< std::vector<int> > boundaryLabels;
	sps.compute(superpixelTotal, leftImage, rightImage, segmentImage, disparityImage, disparityImageRight, disparityPlaneParameters, boundaryLabels);


	

#if 1
	std::string outputDisparityImageFilename = argv[3];
	disparityImage.write(outputDisparityImageFilename);

	outputDisparityImageFilename = argv[4];
	disparityImageRight.write(outputDisparityImageFilename);
#else
	png::image<png::rgb_pixel> segmentBoundaryImage;
	makeSegmentBoundaryImage(leftImage, segmentImage, boundaryLabels, segmentBoundaryImage);

	//std::string outputBaseFilename = leftImageFilename;
	std::string outputBaseFilename = argv[3];
	size_t slashPosition = outputBaseFilename.rfind('/');
	if (slashPosition != std::string::npos) outputBaseFilename.erase(0, slashPosition+1);
	size_t dotPosition = outputBaseFilename.rfind('.');
	if (dotPosition != std::string::npos) outputBaseFilename.erase(dotPosition);
	//std::string outputDisparityImageFilename = outputBaseFilename + "_left_disparity.png";
	std::string outputDisparityImageFilename = argv[3];
	std::string outputSegmentImageFilename = outputBaseFilename + "_segment.png";
	std::string outputBoundaryImageFilename = outputBaseFilename + "_boundary.png";
	std::string outputDisparityPlaneFilename = outputBaseFilename + "_plane.txt";
	std::string outputBoundaryLabelFilename = outputBaseFilename + "_label.txt";

	std::cout << outputBoundaryImageFilename << "\n";

	disparityImage.write(outputDisparityImageFilename);
	segmentImage.write(outputSegmentImageFilename);
	segmentBoundaryImage.write(outputBoundaryImageFilename);
	writeDisparityPlaneFile(disparityPlaneParameters, outputDisparityPlaneFilename);
	writeBoundaryLabelFile(boundaryLabels, outputBoundaryLabelFilename);
#endif
}
void imageCompareBase::processDualScrollingChange(bool dualScrollingOn) {

  setScrollingConnections(dualScrollingOn);

  if (dualScrollingOn) {
    if (leftImage() && rightImage()) {
      if (curImage() == leftImage()) {
        processLHSBsliderMoved(leftScroll_->horizontalScrollBar()->value());
        processLVSBsliderMoved(leftScroll_->verticalScrollBar()->value());
      }
      else {
        processRHSBsliderMoved(rightScroll_->horizontalScrollBar()->value());
        processRVSBsliderMoved(rightScroll_->verticalScrollBar()->value());
      }
    }
  }
}
void imageCompareBase::
processImageMenuTriggerLR(QAction* action, const leftRightAccessor& lra) {

  if (!action->data().isNull()) {
    imagePtr container = action->data().value<imagePtr>();
    if (lra.image() == leftImage()) {
      setLeftImage(container);
    }
    else if (lra.image() == rightImage()) {
      setRightImage(container);
    }
    else {
      qWarning() << "Left/right mismatch:" << lra.image() <<
        leftImage() << rightImage();
      return;
    }
    setCur(container);
  }
}
void imageCompareBase::switchSides() {

  if (leftScroll_->isVisible() && rightScroll_->isVisible()) {
    imagePtr tmpContainer;

    tmpContainer = rightImage();
    setRightImage(leftImage());
    setLeftImage(tmpContainer);

    // setCur on both sides to make sure they're both updated
    if (curImage() == leftImage()) {
      setCur(rightImage());
      setCur(leftImage());
    }
    else {
      setCur(leftImage());
      setCur(rightImage());
    }
  }
}
Exemple #10
0
QSize imageCompareBase::curImageViewSize() const {

  imageLabelBase* curLabel = NULL;
  if (curImage() == leftImage()) {
    curLabel = leftLabel();
  }
  else if (curImage() == rightImage()) {
    curLabel = rightLabel();
  }

  return curLabel ? QSize(curLabel->width(), curLabel->height()) : QSize();
}
Exemple #11
0
void imageCompareBase::deleteLR(const leftRightAccessor& lra) {

  // don't delete original
  const QString imageName = lra.image()->name();
  if (!lra.image()->isOriginal()) {
    deleteImageActions(imageName);
    // determine the replacement image
    comboBox* box = lra.imageListBox();
    box->removeItem(box->findText(imageName));
    QString replacement;
    if (box->findText(Original()) != -1) {
      replacement = Original();
    }
    else if (box->count() > 0) {
      // the most recent image
      replacement = box->itemText(box->count() - 1);
    }
    if (!replacement.isNull()) {
      if (leftImage() && leftImage()->name() == imageName) {
        setLeftImage(getImageFromName(replacement));
        setCur(leftImage());
      }
      else if (rightImage() && rightImage()->name() == imageName) {
        setRightImage(getImageFromName(replacement));
        setCur(rightImage());
      }
      else {
        qWarning() << "Deleting an image not shown:" << imageName;
      }
    }
    else {
      imageListEmpty();
      return;
    }
  }
}
Exemple #12
0
cv::Mat DestinNetworkAlt::convertCentroidImageToMatImage(int layer, int centroid, bool toByteType){
    uint width = Cig_GetCentroidImageWidth(destin, layer);

    int height = width;

    if(imageMode == DST_IMG_MODE_GRAYSCALE_STEREO){
        width = width * 2;
    }

    cv::Mat centroidImage(height, width, getCvFloatImageType());

    cv::Mat toShow;
    if(imageMode == DST_IMG_MODE_GRAYSCALE){
        float * data = (float *)centroidImage.data;
        // Copy generated centroid image to the Opencv mat.
        memcpy(data, getCentroidImages()[0][layer][centroid], width*width*sizeof(float));
    } else if(imageMode == DST_IMG_MODE_RGB){
        // Copy  generated centroid to the color OpenCV mat.
        for(int channel = 0 ; channel < 3 ; channel++){ // iterate over R, G, B
            float * centroid_image = getCentroidImages()[channel][layer][centroid];
            cv::Point p;
            int pixel = 0;
            for(p.y = 0 ; p.y < centroidImage.rows ; p.y++){
                for(p.x = 0 ; p.x < centroidImage.cols; p.x++){
                    centroidImage.at<cv::Vec3f>(p)[channel] = centroid_image[pixel];
                    pixel++;
                }
            }
        }
    } else if(imageMode == DST_IMG_MODE_GRAYSCALE_STEREO){

        // This section copies left and right pair of stereo images into a rectangle shapped image.

        cv::Rect left_region_rect(cv::Point(0, 0), cv::Size(width, width));
        cv::Rect right_region_rect(cv::Point(width, 0), cv::Size(width, width));

        cv::Mat left_region = centroidImage(left_region_rect);
        cv::Mat right_region = centroidImage(right_region_rect);

        cv::Mat leftImage (width, width, getCvFloatImageType());
        memcpy(leftImage.data,  getCentroidImages()[0][layer][centroid], width*width*sizeof(float));

        cv::Mat rightImage(width, width, getCvFloatImageType());
        memcpy(rightImage.data, getCentroidImages()[1][layer][centroid], width*width*sizeof(float));

        leftImage.copyTo(left_region);   // copy left centroid image to left side of the bigger image
        rightImage.copyTo(right_region); // copy right centroid image to right side of the bigger image

        //TODO: test this section and remove the throw
        throw std::runtime_error("convertCentroidImageToMatImage: TODO: need to test the code for DST_IMG_MODE_GRAYSCALE_STEREO");
    } else {
        throw std::runtime_error("fillMatWithCentroidImage: unsupported image mode.\n");
    }
    // make it suitable for equalizeHist
    if(toByteType){
        centroidImage.convertTo(toShow, getCvByteImageType(), 255);
    } else {
        toShow  = centroidImage;
    }

    return toShow;
}
Exemple #13
0
int main(int argc, char* argv[])
{
	QApplication app(argc, argv);

	// Parse arguments
	QString leftPath= "Rotunda_0.png";
	QString rightPath= "Rotunda_1.png";
	QString outputPath= "disparity.png";
	bool gui= true;
	bool proposedAlg= false;
	bool saveImages= false;
	bool censusCorrelation= false;

	// ./grow left.png right.png output.png [options]
	if(argc >= 4) {
		leftPath= QString(argv[1]);
		rightPath= QString(argv[2]);
		outputPath= QString(argv[3]);
	}
	for(int i=4; i<argc; i++) {
		QString param(argv[i]);
		if(param == "-gui") gui= true; else
		if(param == "-nogui") gui= false; else
		if(param == "-proposed") proposedAlg= true; else
		if(param == "-baseline") proposedAlg= false; else
		if(param == "-saveimages") saveImages= true; else
		if(param == "-census") censusCorrelation= true; else
		if(param == "-ncc") censusCorrelation= false;
	}

	qDebug() << "Loading images...";
	QImage leftImage(leftPath);
	QImage rightImage(rightPath);

	if(leftImage.isNull() or rightImage.isNull()) {
		qDebug() << "Couldn't open" << leftPath << "or" << rightPath;
		return EXIT_FAILURE;
	}

	qDebug() << "Matching images...";
	HarrisMatcher matcher;
	matcher.setImages(leftImage, rightImage);
	matcher.saveImages= saveImages;
	matcher.maxDisparity= 100;
	QList<QVector3D> seeds= matcher.getMatches();
	qDebug() << " - Found" << seeds.count() << "matches in" << matcher.getLastTime() << "ms.";

	qDebug() << "Initializing the" << QString(censusCorrelation ? "Census" : "NCC") << "correlator...";
	const int cRadius= 2;
	Correlation* correlator;
	if(censusCorrelation)
		correlator= new CorrelationCensus(cRadius, cRadius);
	else
		correlator= new CorrelationNCC(cRadius);
	correlator->setThreshold(censusCorrelation ? 0.005 : 0.6);
	int initTime= correlator->init(leftImage, rightImage);
	qDebug() << " - Done in" << initTime << "ms.";

	qDebug() << "Stereo matching using the" << QString(proposedAlg ? "Proposed" : "Baseline") << "algorithm...";
	StereoMatching stereoMatcher(leftImage, rightImage, seeds, correlator);
	//stereoMatcher.loadSeedsFromFile("Rotunda_seeds.txt");
	stereoMatcher.setUsingProposedAlg(proposedAlg);

	int elapsedTime;
	if(gui) {

		qDebug() << "Starting the GUI...";
		Gui gui(&stereoMatcher);
		gui.show();
		elapsedTime= gui.do_stuff();
		gui.close();

	} else {

		stereoMatcher.run();
		elapsedTime= stereoMatcher.getLastTime();
	}

	qDebug() << "Finishing...";
	stereoMatcher.disparityImage(true).save(outputPath);

	qDebug() << "--";
	qDebug() << "Disparity map calculated in" << elapsedTime << "ms.";
	qDebug() << correlator->numCorrelations()/1000 << "K correlations.";


	delete correlator;

	QTimer::singleShot(100, &app, SLOT(quit()));
	return app.exec();
}
void TestProjectWindow::selectImage(int i) {
  if (i != selected) {
    positions.clear();
  }
  StandardImageViewerWindow::selectImage(i);

  vector<RealObjectInformations> imageSecondaryInfos = secondaryInfos.find(this->filesList.at(i / 2))->second;
  QPixmap leftImage(imagePath);
  vector<int> imageVector = Utility::loadImage(imagePath);
  Image<float> * image = RobonautEye::convertVectorToImage(imageVector);
  //QPixmap rightImage(folderPath + "RightImage_" + imageFilename);
  int fromWidth = leftImage.width();

  leftImage = leftImage.scaledToWidth(1024, Qt::SmoothTransformation);
  //rightImage = rightImage.scaledToWidth(512, Qt::SmoothTransformation);

  this->scale = leftImage.width() * 1.0 / fromWidth;

  QPainter p(&leftImage);
  p.setPen(QColor(255, 255, 255));

  vector <Point> primaryPositions = this->getPrimaryObjectsPositions();
  vector<RealObjectInformations> primaryObjectsRealInformations = this->getPrimaryObjectsRealInformations();
  primaryPositions.erase(primaryPositions.begin() + 1);
  primaryObjectsRealInformations.erase(primaryObjectsRealInformations.begin() + 1);
  Utility::drawPositionsWithIndex(p, primaryPositions, scale);

  p.setPen(QColor(0, 255, 0));
  Utility::drawPositions(p, positions, scale);



  vector <Point> primaryFilteredPositionsFrom;
  vector <Point> primaryFilteredPositionsTo;
  for (size_t j = 0; j < TASKBOARD_PRIMARY_OBJECTS_NB_POSITIONS; j++) {
    Point pointTo = primaryPositions.at(j);
    if (pointTo.x < 0 || pointTo.y < 0) {
      continue;
    }

    primaryFilteredPositionsFrom.push_back(TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].position);
    primaryFilteredPositionsTo.push_back(primaryPositions.at(j));
  }

  if (primaryFilteredPositionsFrom.size() > 3) {

    Array2D<double> * H = Geometry::getPerspectiveProjectionHomography(
      &primaryFilteredPositionsFrom[0],
      &primaryFilteredPositionsTo[0],
      primaryFilteredPositionsFrom.size()
    );

    Point borders[4] = {
      Point(20, 19),
      Point(537, 19),
      Point(537, 770),
      Point(20, 770)
    };

    Point * projectedBorders = Geometry::getPerspectiveProjectionPoints(H, &borders[0], 4);

    p.setPen(QColor(255, 255, 255));
    Utility::drawPolygon(p, projectedBorders, 4, scale);

    delete projectedBorders;

    Point * projectionsRaw = Geometry::getPerspectiveProjectionPoints(H, RobonautEye().getSecondaryPoints(), 20);

    vector < Point > projections;
    for (size_t i = 0; i < TASKBOARD_SECONDARY_OBJECTS_NB_POSITIONS; i++) {
      projections.push_back(projectionsRaw[i]);
    }

    p.setPen(QColor(255, 0, 0));
    vector <Point> assignments = Utility::assignSecondaryInformations(imageSecondaryInfos, projections, i % 2 == 0);
    Utility::drawPositions(p, assignments, scale);



    p.setPen(QColor(0, 255, 255));

    Utility::drawPositions(p, projections, scale);
    RobonautEye eye;

    for (size_t j = 0; j < TASKBOARD_PRIMARY_OBJECTS_NB_POSITIONS; j++) {
      /*Point objectBorders[4] = {
        Point(
          TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].position.x - TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].size / 2,
          TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].position.y - TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].size / 2
        ),
        Point(
          TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].position.x + TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].size / 2,
          TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].position.y - TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].size / 2
        ),
        Point(
          TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].position.x + TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].size / 2,
          TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].position.y + TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].size / 2
        ),
        Point(
          TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].position.x - TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].size / 2,
          TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].position.y + TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j].size / 2
        )
      };

      Point * projectedObjectBorders = Geometry::getPerspectiveProjectionPoints(H, &objectBorders[0], 4);
      Utility::drawPolygon(p, projectedObjectBorders, 4, scale);
      delete projectedObjectBorders;
*/
/*primaryObjectsRealInformations.at(j).state == "HIDDEN"*/


      PrimaryObject primaryObjectProjection = RobonautEye::getPerspectiveProjection(H, TASKBOARD_PRIMARY_OBJECTS_POSITIONS[j]);

      eye.computePrimaryObjectState(image, primaryObjectProjection);
      if (primaryObjectProjection.stateScores[0] > 0.5) {
        p.setPen(QColor(255, 0, 0));
      } else if (primaryObjectProjection.stateScores[1] > 0.5) {
        p.setPen(QColor(0, 255, 0));
      } else {
        p.setPen(QColor(255, 255, 0));
      }

      Utility::drawPrimaryObject(p, primaryObjectProjection, scale);
    }



  }
  delete image;

  /*
  if (positions.size() == 3) {
    OrthographicProjectionEquation eq = Geometry::getOrthographicProjectionEquation(
      TASKBOARD_SECONDARY_OBJECTS_POSITIONS[0],
      TASKBOARD_SECONDARY_OBJECTS_POSITIONS[4],
      TASKBOARD_SECONDARY_OBJECTS_POSITIONS[9],
      positions.at(0),
      positions.at(1),
      positions.at(2)
    );

    qDebug() << eq.xEq.a << eq.xEq.b << eq.xEq.c;
    qDebug() << eq.yEq.a << eq.yEq.b << eq.yEq.c;

    Point * projectionsRaw = Geometry::getOrthographicProjectionPoints(eq, &TASKBOARD_SECONDARY_OBJECTS_POSITIONS[0], TASKBOARD_SECONDARY_OBJECTS_NB_POSITIONS);

    vector < Point > projections;
    for (size_t i = 0; i < TASKBOARD_SECONDARY_OBJECTS_NB_POSITIONS; i++) {
      projections.push_back(projectionsRaw[i]);
    }

    p.setPen(QColor(255, 255, 0));

    Utility::drawPositions(p, projections, scale);
  }
  */

  if (positions.size() > 3) {
    size_t nb = positions.size();
    Point * pointsTo = new Point[nb];
    for (size_t i = 0; i < nb; i++) {
      pointsTo[i] = positions.at(i);
    }

    Array2D<double> * H = Geometry::getPerspectiveProjectionHomography(
      RobonautEye().getSecondaryPoints(),
      pointsTo,
      nb
    );

    Point * projectionsRaw = Geometry::getPerspectiveProjectionPoints(H, RobonautEye().getSecondaryPoints(), 20);

    vector < Point > projections;
    for (size_t i = 0; i < TASKBOARD_SECONDARY_OBJECTS_NB_POSITIONS; i++) {
      projections.push_back(projectionsRaw[i]);
    }

    p.setPen(QColor(255, 255, 0));

    Utility::drawPositions(p, projections, scale);
    delete pointsTo;
  }

  this->ui->image->setPixmap(leftImage);
  //this->ui->rightImage->setPixmap(rightImage);

}
Exemple #15
0
void MainWindow::createMainMenuWidget() {
    // Sets up each menu button along with their styleSheet
    QPushButton *start = new QPushButton(tr("Start"));
    start->setFixedSize(172,48);
    start->setFont(QFont("MS Shell Dlg 2", 11, QFont::Bold));
    start->setStyleSheet("QPushButton{background-image:url(:/program/images/Default.png); color: white; border-width: 3px; border-color: #181D1F; border-style: outset; border-radius: 7;}"
                         "QPushButton:hover{background-image:url(:/program/images/Hover.png);}"
                         "QPushButton:pressed{background-image:url(:/program/images/Clicked.png);}");
    connect(start, SIGNAL(clicked()), this, SLOT(startButtonClicked()));

    QPushButton *howToPlay = new QPushButton(tr("How to Play"));
    howToPlay->setFixedSize(172,48);
    howToPlay->setFont(QFont("MS Shell Dlg 2", 11, QFont::Bold));
    howToPlay->setStyleSheet("QPushButton{background-image:url(:/program/images/About.png); color: white; border-width: 3px; border-color: #181D1F; border-style: outset; border-radius: 7;}"
                             "QPushButton:hover{background-image:url(:/program/images/About-Hover.png);}"
                             "QPushButton:pressed{background-image:url(:/program/images/About-Clicked.png);}"
                             "QPushButton:disabled{background-image:url(:/program/images/Quit.png);};");
    connect(howToPlay, SIGNAL(clicked()), this, SLOT(howToPlayButtonClicked()));

    QPushButton *about = new QPushButton(tr("About Guess Who"));
    about->setFixedSize(172,48);
    about->setFont(QFont("MS Shell Dlg 2", 11, QFont::Bold));
    about->setStyleSheet("QPushButton{background-image:url(:/program/images/About.png); color: white; border-width: 3px; border-color: #181D1F; border-style: outset; border-radius: 7;}"
                         "QPushButton:hover{background-image:url(:/program/images/About-Hover.png);}"
                         "QPushButton:pressed{background-image:url(:/program/images/About-Clicked.png);}");
    connect(about, SIGNAL(clicked()), this, SLOT(aboutButtonClicked()));

    QPushButton *quit = new QPushButton(tr("Quit"));
    quit->setFixedSize(172,48);
    quit->setFont(QFont("MS Shell Dlg 2", 11, QFont::Bold));
    quit->setStyleSheet("QPushButton{background-image:url(:/program/images/Quit.png); color: white; border-width: 3px; border-color: #181D1F; border-style: outset; border-radius: 7;}"
                        "QPushButton:hover{background-image:url(:/program/images/Quit-Hover.png);}"
                        "QPushButton:pressed{background-image:url(:/program/images/Quit-Clicked.png);}");
    connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));

    // Creates the layout for the buttons
    QVBoxLayout *buttonLayout = new QVBoxLayout;
    buttonLayout->addSpacing(20);
    buttonLayout->addWidget(start, 0, Qt::AlignHCenter);
    buttonLayout->addSpacing(15);
    buttonLayout->addWidget(howToPlay, 0, Qt::AlignHCenter);
    buttonLayout->addSpacing(15);
    buttonLayout->addWidget(about, 0, Qt::AlignHCenter);
    buttonLayout->addSpacing(15);
    buttonLayout->addWidget(quit, 0, Qt::AlignHCenter);
    buttonLayout->addSpacing(20);

    QGroupBox *choiceGroupBox = new QGroupBox(tr(""));
    choiceGroupBox->setStyleSheet("QGroupBox{color:white}");
    choiceGroupBox->setLayout(buttonLayout);
    choiceGroupBox->setFixedSize(260, 400);

    // Creates 2 labels that will hold images for the menu screen
    QLabel *leftLabel = new QLabel(tr(""));
    QPixmap leftImage(":/program/images/Left.png");
    leftLabel->setPixmap(leftImage);
    leftLabel->setFixedSize(480,570);

    QLabel *rightLabel = new QLabel(tr(""));
    QPixmap rightImage(":/program/images/Right.png");
    rightLabel->setPixmap(rightImage);
    rightLabel->setFixedSize(480,570);

    // Creates the bottom layout for the page
    QHBoxLayout *bottomLayout = new QHBoxLayout;
    bottomLayout->addWidget(leftLabel, 0, Qt::AlignHCenter);
    bottomLayout->addWidget(choiceGroupBox);
    bottomLayout->addWidget(rightLabel, 0, Qt::AlignHCenter);

    // Creates the main layout for the page
    QVBoxLayout *mainLayout = new QVBoxLayout;

    QPixmap titleImage(":/program/images/Title.png");
    QLabel *titleName = new QLabel(tr(""));
    titleName->setPixmap(titleImage);
    titleName->setFixedSize(980,300);

    mainLayout->addSpacing(100);
    mainLayout->addWidget(titleName, 0, Qt::AlignHCenter);
    mainLayout->addLayout(bottomLayout);

    mainMenuWidget = new QWidget;
    mainMenuWidget->setLayout(mainLayout);
}