How to rotate an image without using OpenCV functions? (using Linear, Qubic interpolation)

I am trying to rotate an image without using the OpenCV function.

enter image description here

I want to do it pixel by pixel with interpolation (nearest neighbors & linear & cubic) and later I would like to do it with a rotation matrix.

Problems:

  1. Can't understand how to implement the interpolations. Even one example with the Qubic will help me.

  2. for some reason the left pixels in the original image are sent to the right side in the rotated image and it seems not right for the rotation (should be black pixels).

  3. Add an extra option (but not a must) to rotate the image from the center of the image. (and not from (0,0) which is the top left of the image by default)

The original image:

enter image description here

My code: (AFTER UPDATE 1)

#include <iostream>
#include <math.h>
#include "opencv2/opencv.hpp"

using namespace std;

enum interpolation_type{
    INTERPOLATION_CUBIC,
    INTERPOLATION_LINEAR,
    INTERPOLATION_NEAREST_NEIGHBOR
};


void Interpolation_Calculator(const cv::Point& srcPixel,cv::Point2i& dstPixel, interpolation_type type){
    // The origin pixels for the currPixel in the newImage depends on the interpolation type
    int originX = 0;
    int originY = 0;

    if(type == INTERPOLATION_NEAREST_NEIGHBOR)
    {
        originX = (int)round(srcPixel.x);
        originY = (int)round(srcPixel.y);
    }
    else if(type == INTERPOLATION_LINEAR){

    }
    else if (type == INTERPOLATION_CUBIC){

    }

    dstPixel.x = originX;
    dstPixel.y = originY;
}

void RotationFunction(const cv::Mat& src,cv::Mat& dst, int angle, interpolation_type type){
    // The pixels in the new image we want to find right origin pixel for his value.
    double rotatedX;
    double rotatedY;

    double toRadian = 3.141592653589/180;

    for(int r=0;r<dst.rows;r++)
     {
      for(int c=0;c<dst.cols;c++)
      {
          rotatedX = r*cos(angle * toRadian) - c*sin(angle * toRadian);
          rotatedY = r*sin(angle * toRadian) + c*cos(angle * toRadian);
          
          cv::Point rotatedPixel(rotatedX,rotatedY);
          cv::Point2i originPixel;
          Interpolation_Calculator(rotatedPixel,originPixel,type);
          //cv::Vec3b vector(0,0,0);

          // Checking if the Interpolation calculations crossed the boundaries
          if(originPixel.x < 0 || originPixel.x > src.cols - 1 || originPixel.y < 0 || originPixel.y > src.rows - 1)
              dst.at<cv::Vec3b>(cv::Point(r, c)) = 0;
          else { // In case everything is good
              cv::Vec3b currPixel = src.at<cv::Vec3b>(originPixel);
              dst.at<cv::Vec3b>(cv::Point(r, c)) = currPixel;
          }

      }
    }
}

int main() {
    cv::Mat img = cv::imread("../lion.jpeg");
    cv::Mat rotatedImage(img.rows,img.cols,CV_8UC3);
    // Rotating
    RotationFunction(img,rotatedImage,25,INTERPOLATION_NEAREST_NEIGHBOR);
    // End of Rotating

    // Show the images
    cv::imshow("window1",img);
    cv::imshow("window2",rotatedImage);
    cv::waitKey(0);
    // End of Show the images

    return 0;
}

Bad Output:

enter image description here

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum