I am writing up a detailed solution, but I want make sure I am solving the correct problem. The plan is to create a transformation that properly warps a version of the "roof tile" pattern (or any such pattern) such that when mapped to the quadrilateral in the image on the right is correctly perspectively warped? i.e, the quad ABCE is mapped to the quad A'B'C'E'?

The first step is to compute a homography that maps the quad ABCD to the quad A'B'C'D'. OpenCV provides methods for this, but lets do that math ourself. We are searching for a 3x3 matrix H that maps the points A,B,C,D to the points A',B',C',D' as follows (we'll actually do it the other way around):

Using 3D homogenous vectors (x,y,w) allows us to work in 3-D and the division by w provides the necessary perspective foreshortening (to make a long story short).
It turns out that any scale multiple of H works meaning that it only has 8 degrees of freedom (instead of the full 3*3 = 9). What this means is that we want HA' to be a scale multiple of A thus their cross product is zero:

If we perform the cross product we can rewrite this last equation as

The last equation above is actually a linear combination of the first two equations (multiply the first equation by x, multiply the second equation by y, add them and you arrive at the third equation). Since the third equation in linearly dependent we throw it out and only use the first two. After negating the second equation, swapping them, and then converting them to matrix form we get

Thus one point correspondence A' - A yields two equations.
If we have n point correspondences we get 2n equations:

We need n >= 4 to have at least 8 equations to arrive at a proper solution; i.e., we need at least 4 (non-collinear) points.
Thus we have a homogenous system of equations which
we solve using singular value decomposition:

Obviously the trivial solution h = 0 works but it not very useful.
Setting h to the last column of V leads to the least squared
error solution of our system where h has unit length.
Lets compute H for your specific example. Let's assume the source
image to transform is WxH = 500x300, thus A = (0,0), B = (W,0), C = (0,H), and D = (W,H). The destination image is 484x217 and I located
the corners of the roof as A' = (70.7, 41.3), B' = (278.8, 76.3),
C' = (136.4, 121,2), and D' = (345.1, 153,2). I'll use Eigen to
do the computation. So I'll load my source and destination
points into matrices:
#include <Eigen/Dense>
...
constexpr double W = 500;
constexpr double H = 300;
constexpr size_t N = 4;
Eigen::Matrix<double,2,N> SRC;
SRC <<
0, W, 0, W,
0, 0, H, H;
Eigen::Matrix<double,2,N> DST;
DST <<
70.7, 278.8, 136.4, 345.1,
41.3, 76.3, 121.2, 153.2;
I construct the 8x9 matrix A as described above
Eigen::Matrix<double,2*N,9> A;
A.setZero();
for (size_t i = 0; i < N; i++) {
const double x_ = DST(0,i), y_ = DST(1,i);
const double x = SRC(0,i), y = SRC(1,i);
A(2*i,0) = A(2*i+1,3) = x_;
A(2*i,1) = A(2*i+1,4) = y_;
A(2*i,2) = A(2*i+1,5) = 1;
A(2*i,6) = -x*x_;
A(2*i,7) = -x*y_;
A(2*i,8) = -x;
A(2*i+1,6) = -y*x_;
A(2*i+1,7) = -y*y_;
A(2*i+1,8) = -y;
}
I then compute the SVD, extract the solution from the
last column of V, and stored the result in a 3x3 matrix:
Eigen::JacobiSVD<Eigen::Matrix<double,2*N,9>> svd(A, Eigen::ComputeFullV);
Eigen::Matrix<double,9,1> h = svd.matrixV().col(8);
Eigen::Matrix3d Homography;
Homography <<
h(0), h(1), h(2),
h(3), h(4), h(5),
h(6), h(7), h(8);
yielding the desired 3x3 matrix H:
-0.016329 0.013427 0.599927
0.004571 -0.0271779 0.799277
1.78122e-06 -2.83812e-06 -0.00613631
We can take a look at a sample warped image using OpenCV.
I load my source texture and my homography H and use the OpenCV
warpPerspective function
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
int main() {
cv::Mat sourceImage = imread("texture.png", cv::IMREAD_COLOR);
cv::Matx33d H(-0.016329, 0.013427, 0.599927,
0.004571, -0.0271779, 0.799277,
1.78122e-06, -2.83812e-06, -0.00613631);
cv::Mat destImage;
cv::warpPerspective(sourceImage, destImage, H, cv::Size(487,217),
cv::INTER_LINEAR | cv::WARP_INVERSE_MAP);
cv::imwrite("warped.png", destImage);
return 0;
}
The result looks plausible:
