c++opencvimage-processingpolar-coordinatescartesian

Converting Cartesian Coordinates To Polar Coordinates


I'm trying to covert an image from Polar Coordinates to Cartesian Coordinates but after applying the formulas I get float coordinates (r and teta) and I don't know how to represent the points in space using floats for x and y. There might be a way of transforming them in int numbers and still preserving the distribution but I don't see how. I know that there are functions in OpenCV like warpPolar that to the work but I would like to implement it by myself. Any ideas would help :)

This is my code:

struct Value
{
    double r;
    double teta;
    int value;  // pixel intensity
};
void irisNormalization(Mat img, Circle pupilCircle, Circle irisCircle, int &matrixWidth, int &matrixHeight)
{
    int w = img.size().width;
    int h = img.size().height;
    int X, Y;
    double r, teta;
    int rayOfIris = irisCircle.getRay();
    std::vector<Value> polar;
    // consider the rectangle the iris circle is confined in
    int xstart = irisCircle.getA() - rayOfIris;
    int ystart = irisCircle.getB() - rayOfIris;
    int xfinish = irisCircle.getA() + rayOfIris;
    int yfinish = irisCircle.getB() + rayOfIris;
    for (int x = xstart; x < xfinish; x++)
        for (int y = ystart; y < yfinish; y++)
        {
            X = x - xstart - rayOfIris;
            Y = y - ystart - rayOfIris;
            r = sqrt(X * X + Y * Y);
            if (X != 0)
            {
                teta = (atan(abs(Y / X)) * double(180 / M_PI));
                if (X > 0 && Y > 0) // quadrant 1
                    teta = teta;
                if (X > 0 && Y < 0)
                    teta = 360 - teta; // quadrant 4
                if (X < 0 && Y > 0) // quadrant 2
                    teta = 180 - teta;
                if (X < 0 && Y < 0) // quadrant 3
                    teta = 180 + teta;
                if (r < rayOfIris)
                {
                    polar.push_back({ r, teta, int(((Scalar)(img.at<uchar>(Point(x, y)))).val[0]) });
                }
            }
        }
    std::sort(polar.begin(), polar.end(), [](const Value &left, const Value &right) {
        return left.r < right.r && left.teta < right.teta;
    });
    for (std::vector<Value>::const_iterator i = polar.begin(); i != polar.end(); ++i)
        std::cout << i->r << ' ' << i->teta << endl;

Solution

  • Your implementation attempts to express every integer-coordinate point inside a given circle in polar-coordinates. In this way, however, you terminate with an array of coordinates toghether with a value.

    If instead you want to geometrically transform your image, you should:

    For interpolating the values different methods are available. A non-exhaustive list includes: