Example #1
0
const std::vector<Lines<float> > Algorithms::normalizeLines(const std::vector<Lines<int> > lines, int &minX, int &maxX, int &minY, int &maxY){
  /*  // Set initial values to extremes of the opposites
    int minX = INT_MAX;
    int maxX = INT_MIN;
    int minY = INT_MAX;
    int maxY = INT_MIN;

    // Find the minimum and maximum x and y for the range of the map
    for(std::vector<Line<int> >::const_iterator it = lines.begin(); it != lines.end(); ++it) {
        if (minX > it->x1) {
            minX = it->x1;
        }
        if (minX > it->x2) {
            minX = it->x2;
        }
        if (maxX < it->x1) {
            maxX = it->x1;
        }
        if (maxX < it->x2) {
            maxX = it->x2;
        }

        if (minY > it->y1) {
            minY = it->y1;
        }
        if (minY > it->y2) {
            minY = it->y2;
        }
        if (maxY < it->y1) {
            maxY = it->y1;
        }
        if (maxY < it->y2) {
            maxY = it->y2;
        }
    }*/
    int difX = maxX - minX;
    int difY = maxY - minY;
  //  return const std::vector<Line> linesNormalized

    std::vector<Lines<float> > linesNormalized;
    for(std::vector<Lines<int> >::const_iterator it = lines.begin(); it != lines.end(); ++it) {
        // Normalize x and y between -1.0 and 1.0
        float x1 = ((float(it->x1 - minX) / difX) * DIF_X) + MIN_X;
        float y1 = ((float(it->y1 - minY) / difY) * DIF_Y) + MIN_Y;
        float x2 = ((float(it->x2 - minX) / difX) * DIF_X) + MIN_X;
        float y2 = ((float(it->y2 - minY) / difY) * DIF_Y) + MIN_Y;

        Lines<float> lineNormalized(x1, y1, x2, y2);
        linesNormalized.push_back(lineNormalized);
    }

    return linesNormalized;
}
Example #2
0
const std::vector<Lines<float> > Algorithms::getNormalizedLinesForPolygons(const std::vector<std::vector<points> >& polygons) {
    std::vector<std::vector<points> >::const_iterator it_polygons;
    std::vector<points>::const_iterator it;

    // Set initial values to extremes of the opposites
    int minX = INT_MAX;
    int maxX = INT_MIN;
    int minY = INT_MAX;
    int maxY = INT_MIN;

    // Find the minimum and maximum x and y for the range of the map
    for(it_polygons = polygons.begin(); it_polygons != polygons.end(); ++it_polygons) {
        for(it = (*it_polygons).begin(); it != (*it_polygons).end(); ++it) {
            if (minX > it->getX()) {
                minX = it->getX();
            }

            if (maxX < it->getX()) {
                maxX = it->getX();
            }

            if (minY > it->getY()) {
                minY = it->getY();
            }
            if (maxY < it->getY()) {
                maxY = it->getY();
            }
        }
    }
    int difX = maxX - minX;
    int difY = maxY - minY;

    std::vector<Lines<float> > linesNormalized;
    for(it_polygons = polygons.begin(); it_polygons != polygons.end(); ++it_polygons) {
        points *prev = NULL;
        for(it = (*it_polygons).begin(); it != (*it_polygons).end(); ++it) {
            if (prev != NULL) {
                // Normalize x and y between -1.0 and 1.0
                float x1 = ((float(prev->getX() - minX) / difX) * DIF_X) + MIN_X;
                float y1 = ((float(prev->getY() - minY) / difY) * DIF_Y) + MIN_Y;
                float x2 = ((float(it->getX() - minX) / difX) * DIF_X) + MIN_X;
                float y2 = ((float(it->getY() - minY) / difY) * DIF_Y) + MIN_Y;

                Lines<float> lineNormalized(x1, y1, x2, y2);
                linesNormalized.push_back(lineNormalized);
            }
            *prev = *it;
        }
    }

    return linesNormalized;
}
int main(int argc, char* argv[])
{
#if 1
	QApplication a(argc, argv);
	MainWindow w;
	w.show();


	// look for image file
	//std::string img_file("data/floor.jpg");
	//QFile file;
	//for (int i = 0; i < 5; ++i)
	//	if (!file.exists(img_file.c_str()))
	//		img_file.insert(0, "../");
	//w.getGLWidget()->setImage(img_file.c_str());

	

	GLLines* gllines = &w.getGLWidget()->glLines();

	
	//gllines->setVertexLine(0, 0, QVector3D(52.3467f, 125.102f, 1.0f));
	//gllines->setVertexLine(0, 1, QVector3D(340.253f, 130.147f, 1.0f));
	//gllines->setVertexLine(1, 0, QVector3D(193.28f, 126.111f, 1.0f));
	//gllines->setVertexLine(1, 1, QVector3D(225.493f, 360.173f, 1.0f));
	//gllines->setVertexLine(2, 0, QVector3D(42.28f, 263.32f, 1.0f));
	//gllines->setVertexLine(2, 1, QVector3D(296.967f, 397.502f, 1.0f));
	//gllines->setVertexLine(3, 0, QVector3D(212.407f, 269.373f, 1.0f));
	//gllines->setVertexLine(3, 1, QVector3D(34.2267f, 391.449f, 1.0f));
	//gllines->setVertexLine(4, 0, QVector3D(294.953f, 318.809f, 1.0f));
	//gllines->setVertexLine(4, 1, QVector3D(456.02f, 322.844f, 1.0f));
	//gllines->setVertexLine(5, 0, QVector3D(492.26f, 208.84f, 1.0f));
	//gllines->setVertexLine(5, 1, QVector3D(429.847f, 400.529f, 1.0f));
	//gllines->setVertexLine(6, 0, QVector3D(299.987f, 31.2756f, 1.0f));
	//gllines->setVertexLine(6, 1, QVector3D(555.68f, 273.409f, 1.0f));
	//gllines->setVertexLine(7, 0, QVector3D(545.613f, 39.3467f, 1.0f));
	//gllines->setVertexLine(7, 1, QVector3D(236.567f, 250.204f, 1.0f));
	//gllines->setVertexLine(8, 0, QVector3D(95.6333f, 264.329f, 1.0f));
	//gllines->setVertexLine(8, 1, QVector3D(501.32f, 273.409f, 1.0f));
	//gllines->setVertexLine(9, 0, QVector3D(302.00f, 29.2578f, 1.0f));
	//gllines->setVertexLine(9, 1, QVector3D(297.973f, 398.511f, 1.0f));
	gllines->computeCanonicalVertices(w.getGLWidget()->width(), w.getGLWidget()->height());
	gllines->onEnable(true);

	return a.exec();

#else
	std::vector<Eigen::Vector3f> vertices;
	vertices.push_back(Eigen::Vector3f(52.3467f, 125.102f, 1.0f));
	vertices.push_back(Eigen::Vector3f(340.253f, 130.147f, 1.0f));
	vertices.push_back(Eigen::Vector3f(193.28f, 126.111f, 1.0f));
	vertices.push_back(Eigen::Vector3f(225.493f, 360.173f, 1.0f));
	vertices.push_back(Eigen::Vector3f(42.28f, 263.32f, 1.0f));
	vertices.push_back(Eigen::Vector3f(296.967f, 397.502f, 1.0f));
	vertices.push_back(Eigen::Vector3f(212.407f, 269.373f, 1.0f));
	vertices.push_back(Eigen::Vector3f(34.2267f, 391.449f, 1.0f));
	vertices.push_back(Eigen::Vector3f(294.953f, 318.809f, 1.0f));
	vertices.push_back(Eigen::Vector3f(456.02f, 322.844f, 1.0f));
	vertices.push_back(Eigen::Vector3f(492.26f, 208.84f, 1.0f));
	vertices.push_back(Eigen::Vector3f(429.847f, 400.529f, 1.0f));
	vertices.push_back(Eigen::Vector3f(299.987f, 31.2756f, 1.0f));
	vertices.push_back(Eigen::Vector3f(555.68f, 273.409f, 1.0f));
	vertices.push_back(Eigen::Vector3f(545.613f, 39.3467f, 1.0f));
	vertices.push_back(Eigen::Vector3f(236.567f, 250.204f, 1.0f));
	vertices.push_back(Eigen::Vector3f(95.6333f, 264.329f, 1.0f));
	vertices.push_back(Eigen::Vector3f(501.32f, 273.409f, 1.0f));
	vertices.push_back(Eigen::Vector3f(302.00f, 29.2578f, 1.0f));
	vertices.push_back(Eigen::Vector3f(297.973f, 398.511f, 1.0f));


	std::cout << vertices.size() << std::endl;

	std::vector<Eigen::Vector3f> lines;
	for (int i = 0; i < vertices.size() - 1; i += 2)
		lines.push_back(lineNormalized(vertices[i], vertices[i + 1]));
	
	for (int i = 0; i < lines.size(); ++i)
		std::cout << "l" << i << " : " << lines[i].x() << ", " << lines[i].y() << ", " << lines[i].z() << std::endl;

	std::cout << std::endl << std::endl;

	//lines[0] = Eigen::Vector3f(-0.000141084, 0.00805224, -0.999968);
	//lines[1] = Eigen::Vector3f(-0.00568419, 0.000782299, 0.999984);
	//lines[2] = Eigen::Vector3f(-0.00218568, 0.00414856, -0.999989);
	//lines[3] = Eigen::Vector3f(-0.0016513, -0.00241022, 0.999996);
	//lines[4] = Eigen::Vector3f(-8.04546e-05, 0.00321109, -0.999995);
	//lines[5] = Eigen::Vector3f(-0.00178489, -0.000581155, 0.999998);
	//lines[6] = Eigen::Vector3f(-0.00374583, 0.0039556, 0.999985);
	//lines[7] = Eigen::Vector3f(-0.00165759, -0.00242947, 0.999996);
	//lines[8] = Eigen::Vector3f(-8.53647e-05, 0.00381402, -0.999993);
	//lines[9] = Eigen::Vector3f(-0.00330775, -3.60706e-05, 0.999995);


	Eigen::MatrixXf A(5, 5);
	Eigen::Vector3f l, m;
	Eigen::VectorXf b(5);

	for (int i = 0; i < 5; ++i)
	{
		l = lines[i * 2 + 0];
		m = lines[i * 2 + 1];

		A(i, 0) = l[0] * m[0];
		A(i, 1) = (l[0] * m[1] + l[1] * m[0]) / 2.0f;
		A(i, 2) = l[1] * m[1];
		A(i, 3) = (l[0] * m[2] + l[2] * m[0]) / 2.0f;
		A(i, 4) = (l[1] * m[2] + l[2] * m[1]) / 2.0f;
		A(i, 5) = l[2] * m[2];

		b[i] = -l[2] * m[2];
	}

	std::cout << "A: \n" << A << std::endl << std::endl;
	std::cout << "b: \n" << b << std::endl << std::endl;

	Eigen::MatrixXf x = A.colPivHouseholderQr().solve(b);
	std::cout << std::fixed << "x: \n" << x << std::endl << std::endl;


	Eigen::MatrixXf conic(3, 3);
	conic(0, 0) = x(0);
	conic(0, 1) = x(1) / 2.0f;
	conic(0, 2) = x(3) / 2.0f;
	conic(1, 0) = x(1) / 2.0f;
	conic(1, 1) = x(2);
	conic(1, 2) = x(4) / 2.0f;
	conic(2, 0) = x(3) / 2.0f;
	conic(2, 1) = x(4) / 2.0f;
	conic(2, 2) = 1.0f;
	std::cout << "Conic : " << std::endl << conic << std::endl << std::endl;

	Eigen::JacobiSVD<Eigen::MatrixXf> svd(conic, Eigen::ComputeFullU);
	Eigen::MatrixXf H = svd.matrixU();
	
	std::cout << "H matrix: " << std::endl 
		<< H << std::endl << std::endl 
		<< "Singular values: " << svd.singularValues()
		<< std::endl << std::endl;

	std::cout << "Rectification transformation: " << std::endl << H.inverse() << std::endl << std::endl;





	QImage input("floor-persp.jpg");
	Eigen::Vector3f img(input.width(), input.height(), 1.0f);

	float xmin = 0;
	float xmax = 0;
	float ymin = 0;
	float ymax = 0;
	computImageSize(H.inverse(), 0, 0, input.width(), input.height(), xmin, xmax, ymin, ymax);


	float aspect = (xmax - xmin) / (ymax - ymin);
	QImage output(input.width(), input.width() / aspect, input.format());
	output.fill(qRgb(0, 0, 0));

	std::cout << "Output size: " << output.width() << ", " << output.height() << std::endl;

	float dx = (xmax - xmin) / float(output.width());
	float dy = (ymax - ymin) / float(output.height());

	std::cout << std::fixed << "dx, dy: " << dx << ", " << dy << std::endl;

	for (int x = 0; x < output.width(); ++x)
	{
		for (int y = 0; y < output.height(); ++y)
		{
			Eigen::Vector3f px(x, y, 1);

			float tx = 0.0f;
			float ty = 0.0f;
			Eigen::Vector2f t = multiplyPointMatrix(H, xmin + x * dx, ymin + y * dy);

			if (t.x() > -1 && t.y() > -1
				&& t.x() < input.width()
				&& t.y() < input.height())
			{
				//if (interpolate)
				//{
				//	QRgb rgb = bilinearInterpol(input, t.x(), t.y(), dx / 2.0, dy / 2.0);
				//	output.setPixel(x, y, rgb);
				//}
				//else
				{
					output.setPixel(x, y, input.pixel(t.x(), t.y()));
				}
			}
		}
	}


	output.save("output_5_floor.jpg");
	
	return EXIT_SUCCESS;
#endif
}