# Spline Catmull-Rom for image zooming using C++ and opencv

**URL:** <https://forum.opencv.org/t/spline-catmull-rom-for-image-zooming-using-c-and-opencv/569>\
**Category:** Uncategorized\
**Created:** [December 28, 2020, 5:24pm UTC](https://forum.opencv.org/t/spline-catmull-rom-for-image-zooming-using-c-and-opencv/569 "2020-12-28T17:24:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![SalimElheni](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/salimelheni/32/374_2.png) [@SalimElheni](https://forum.opencv.org/u/SalimElheni)\
**Post date:** [December 28, 2020, 5:24pm UTC](https://forum.opencv.org/t/spline-catmull-rom-for-image-zooming-using-c-and-opencv/569/1 "2020-12-28T17:24:45Z")

</div>

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). 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)).

```
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;
}

```

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [December 29, 2020, 4:40am UTC](https://forum.opencv.org/t/spline-catmull-rom-for-image-zooming-using-c-and-opencv/569/2 "2020-12-29T04:40:10Z")

</div>

related

> <https://stackoverflow.com/questions/65448685/spline-catmull-rom-for-image-zooming-using-c-and-opencv>

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [December 29, 2020, 4:42am UTC](https://forum.opencv.org/t/spline-catmull-rom-for-image-zooming-using-c-and-opencv/569/3 "2020-12-29T04:42:33Z")

</div>

the issue you have is that interpolated values may exceed the range of 0…255, and since computers wrap integers around, you get those artefacts.

calculate with floats, **clip/saturate the final result before converting back to integers**.

---

<div class="post-metadata">

**Author:** ![SalimElheni](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/salimelheni/32/374_2.png) [@SalimElheni](https://forum.opencv.org/u/SalimElheni)\
**Post date:** [December 29, 2020, 3:15pm UTC](https://forum.opencv.org/t/spline-catmull-rom-for-image-zooming-using-c-and-opencv/569/4 "2020-12-29T15:15:21Z")

</div>

Thanks for your help @crackwitz

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [December 30, 2020, 4:02am UTC](https://forum.opencv.org/t/spline-catmull-rom-for-image-zooming-using-c-and-opencv/569/5 "2020-12-30T04:02:56Z")

</div>

as for why the “reconstructed” picture is blurred… you removed the information in the downsampling step. it is gone. it can’t be recreated by mere interpolation.
