Repository: opencv
Issue: cv::warpAffine function and cv::transform have different results
Labels: question (invalid tracker)

**Question resolved! The topic is closed!**
The code takes source and target points, calculates an affine transformation matrix, applies the matrix to transform an input image, visualizes the transformation by placing red circles on the transformed image, saves the resulting image, and displays it in a resizable window using the OpenCV library.

**cv::transform** calculates 4 points that should correspond to the 4 corners of the image. **cv::warpAffine** transforms the created white **InputImage** into a black **ResultImage** using the **affine_matrix** matrix. Then we place 4 red points, also calculated through the **affine_matrix** matrix, using **cv::transform**.

So, we get the transformed 4 red points and the white quadrilateral. The 4 points should precisely match the 4 corners of the white quadrilateral ( **cv::transform**). The issue is that the coordinates of the points are calculated correctly, as I've verified, but the white square is not correctly transformed using **cv::warpAffine**.

The code I've provided in both Python and C++ saves a file named **ResultImage.jpg** in the program's folder. The resulting image is large, but if you open it with a viewer and zoom in on the bottom corners of the white quadrilateral, you can see that the red points are shifted and do not correspond to the corners! **cv::warpAffine** is making a mistake! **cv::transform** finds the points correctly, I've verified this.

**Please help me resolve this issue!**
*"I think the issue might be in the cv::warpAffine algorithm. "*



**Here is the code in C++:**
```
// Constants from Axis
const cv::Point2f A_LB(5, 5);
const cv::Point2f A_RB(1871, 4);
const cv::Point2f A_LT(5, 831);

const cv::Point2f B_LB(0, 0);
const cv::Point2f B_RB(2231, -1145);
const cv::Point2f B_LT(50, 11178);

// Define source points for the least squares method (using only RB and LT points)
std::vector<cv::Point2f> source_points(3);
source_points[0] = A_RB;
source_points[1] = A_LT;
source_points[2] = A_LB;

// Define target points for the least squares method (using only RB and LT points)
std::vector<cv::Point2f> target_points(3);
target_points[0] = B_RB;
target_points[1] = B_LT;
target_points[2] = B_LB;

// Find the affine transformation matrix
cv::Mat affine_matrix = cv::getAffineTransform(source_points, target_points);

// Image dimensions
int height = 1876;
int width = 836;

// Create a blank white image
cv::Mat InputImage(height, width, CV_8UC3, cv::Scalar(255, 255, 255));

// Apply the affine transformation matrix to the corner points of the input image
std::vector<cv::Point2f> sourcePoints = {
    { 0.0f, 0.0f },
    { 0.0f, static_cast<float>(height) - 1 },
    { static_cast<float>(width) - 1, 0.0f },
    { static_cast<float>(width) - 1, static_cast<float>(height) - 1 }
};

std::vector<cv::Point2f> transformed_points;
cv::transform(sourcePoints, transformed_points, affine_matrix);

// Dimensions of the resulting image
int Result_height = 26320;
int Result_width = 1200;

// Create an image for the result
cv::Mat ResultImage(Result_height, Result_width, InputImage.type(), cv::Scalar(0));

// Apply the affine transformation to the input image
cv::warpAffine(InputImage, ResultImage, affine_matrix, cv::Size(Result_width, Result_height),
    cv::INTER_NEAREST,
    cv::BORDER_CONSTANT,
    cv::Scalar(0));

// Place 4 red points
for (const cv::Point2f& point : transformed_points) {
    cv::circle(ResultImage, point, 5, cv::Scalar(0, 0, 255), -1);
}

// Save ResultImage to a file
cv::imwrite("ResultImage.jpg", ResultImage);

// Create a window with a fixed size of 640x480
cv::namedWindow("Result Image", cv::WINDOW_NORMAL);
cv::resizeWindow("Result Image", 640, 480);
// Display the image with scaling
cv::imshow("Result Image", ResultImage);
// Wait for a key press
cv::waitKey(0);
```
--------------------------

**Here is the code in Python:**
```
import cv2
import numpy as np

# Constants from Axis
A_LB = (5, 5)
A_RB = (1871, 4)
A_LT = (5, 831)

B_LB = (0, 0)
B_RB = (2231, -1145)
B_LT = (50, 11178)

# Define source points for the least squares method (using only RB and LT points)
source_points = np.array([A_RB, A_LT, A_LB], np.float32)

# Define target points for the least squares method (using only RB and LT points)
target_points = np.array([B_RB, B_LT, B_LB], np.float32)

# Find the affine transformation matrix
affine_matrix = cv2.getAffineTransform(source_points, target_points)

# Image dimensions
height = 1876
width = 836

# Create a blank white image
InputImage = np.ones((height, width, 3), np.uint8) * 255

# Apply the affine transformation matrix to the corner points of the input image
sourcePoints = np.array([
    [0.0, 0.0],
    [0.0, height - 1],
    [width - 1, 0.0],
    [width - 1, height - 1]
], np.float32)

transformed_points = cv2.transform(np.array([sourcePoints]), affine_matrix)[0]

# Dimensions of the resulting image
Result_height = 26320
Result_width = 1200

# Create an image for the result
ResultImage = np.zeros((Result_height, Result_width, 3), np.uint8)

# Apply the affine transformation to the input image
ResultImage = cv2.warpAffine(InputImage, affine_matrix, (Result_width, Result_height),
    flags=cv2.INTER_NEAREST,
    borderMode=cv2.BORDER_CONSTANT,
    borderValue=(0, 0, 0))

# Place 4 red points
for point in transformed_points:
    cv2.circle(ResultImage, tuple(map(int, point)), 5, (0, 0, 255), -1)

# Save ResultImage to a file
cv2.imwrite("ResultImage.jpg", ResultImage)

# Create a window with a fixed size of 640x480
cv2.namedWindow("Result Image", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Result Image", 640, 480)
# Display the image with scaling
cv2.imshow("Result Image", ResultImage)
# Wait for a key press
cv2.waitKey(0)
cv2.destroyAllWindows()

```

[Here is the result of the enlarged image](https://i.stack.imgur.com/wUOv8.png)


**Question resolved! 
The topic is closed!**