Click here to Skip to main content
16,016,669 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
Hello,
I'm trying to implement spline Catmull-Rom for image zooming using C++ and OpenCV. I performed two tests, the first is image zooming (X2), and the second image reconstruction (zooming image decimated).

What I have tried:

I'm trying to implement spline Catmull-Rom for image zooming using C++ and OpenCV. I performed two tests, the first is image zooming (X2), and the second image reconstruction (zooming image decimated). My problem is that in the image interpolated appear some white and black pixel (image1: https://i.stack.imgur.com/68Dul.png[^] ) when I displayed the value of pixels I found that white pixels have a negative value and the black one has a value greater than 255, also the image reconstructed appear blurred (image2: https://i.stack.imgur.com/9WECM.png[^] and image: https://i.stack.imgur.com/uHrf1.png[^] ).

C++
float CalCurveInt(float t, float p0, float p1, float p2, float p3)
    {    
        float t2 = t * t;
        float t3 = t2 * t;
    
        float x = 0.5f * ((2.0f * p1) +
            (-p0 + p2) * t +
            (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 +
            (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
    return x;
    }

    Mat CalcCatmull(Mat &src, int zoom)
    {
        int v1, v2, v3, v4, Ptr, Xmax, Ymax;
        float Result, t, c1, c2, c3, c4;
        //------------------------------------------------------------
        Xmax = src.cols;
        Ymax = src.rows;
        Size srcSize(zoom*Xmax, Ymax);
        Mat dst(srcSize, CV_8UC1);
    
        for (int j = 0; j < Ymax; j++)
        {
            Ptr = 0;
            for (int i = 0; i < Xmax; i++)
            {
                v1 = i - 1; v2 = i; v3 = i + 1; v4 = i + 2;
    
                if (i - 1 < 0)      v1 = 0;
                if (Xmax <= i + 1)  v3 = Xmax - 1;
                if (Xmax <= i + 2)  v4 = Xmax - 1;
    
                for (double J = 1; J <= zoom; J++)
                {
                    t = J / zoom;
                    Result = 0.0;
    
                    c1 = src.at<uchar>(j, v1);
                    c2 = src.at<uchar>(j, v2);
                    c3 = src.at<uchar>(j, v3);
                    c4 = src.at<uchar>(j, v4);
    
                    Result = CalCurveInt(t, c1, c2, c3, c4);
                    dst.at<uchar>(j, Ptr) = abs(Result);
                    Ptr++;
                }
            }
        }

        //------------------------------------------------
        Xmax = dst.cols;
        Ymax = dst.rows;
    
        Size srcSize1(Xmax, zoom*Ymax);
        Mat dest(srcSize1, CV_8UC1);
    
        for (int i = 0; i < Xmax; i++)
        {
            Ptr = 0;
            for (int j = 0; j < Ymax; j++)
            {
    
                v1 = j - 1; v2 = j; v3 = j + 1; v4 = j + 2;
    
                if (j - 1 < 0)      v1 = 0;
                if (Ymax <= j + 1)  v3 = Ymax - 1;
                if (Ymax <= j + 2)  v4 = Ymax - 1;
    
                for (double J = 1; J <= zoom; J++)
                {
                    t = J / zoom;
                    Result = 0.0;
    
                    c1 = dst.at<uchar>(v1, i);
                    c2 = dst.at<uchar>(v2, i);
                    c3 = dst.at<uchar>(v3, i);
                    c4 = dst.at<uchar>(v4, i);
                    Result = CalCurveInt(t, c1, c2, c3, c4);           
                    dest.at<uchar>(Ptr, i) = Result;
                    Ptr++;
                }
            }
        }
    
        return dest;
    }
    
    float zoom = 2.0;

    
    int main()
    {
        Mat src = imread("fruits.png", CV_LOAD_IMAGE_GRAYSCALE);
        int width = src.cols;
        int hight = src.rows;
    
        /*Image Decimation*/
        Size srcdSize(int(width / zoom), int(hight / zoom));
        Mat srcd;
        pyrDown(src, srcd, srcdSize);
        imshow("decimation", srcd);
    
        Mat dst = CalcCatmull(srcd, zoom);
    
        imshow("Image Source", src);
        imshow("Image dest", dst);
        imwrite("Image dest.png", dst);
    
        waitKey(0);
        return 0;
    }
Posted
Updated 28-Dec-20 23:18pm
v2

1 solution

That is clearly a bug you must fix. I guess it is some overflow in your math. So check the code for overflows and fix them correctly.
My first candidate would be CalCurveInt.

tip: use some test data like input code or specail sample file to reproduce the errors simple and to concentrate on the code.
 
Share this answer
 
Comments
Member 11271608 29-Dec-20 10:18am    
Thanks for your response,
I converted the image to float and it's working fine

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900