c++qtopencvperspectiveaffinetransform

Image transformation in OpenCV and Qt C++


I have set of images taken from right side of object like image1. I need to rotate it about vertical axis and change it tobe like image2.

image1

Image2

Is that affine transformation useful to convert image1 to image2 ? I used affine transform and played with it, but didn't get desired results. What should I do? I used this part of code for image transformation.

    cv::Mat shearedImage;
cv::Point2f srcPoints[3] = {cv::Point2f(0, 0), cv::Point2f(resizedImage.cols, 0), cv::Point2f(0, resizedImage.rows)};
cv::Point2f dstPoints[3] = {cv::Point2f(0, 0), cv::Point2f(resizedImage.cols, 0), cv::Point2f(0, resizedImage.rows)};
cv::Mat transformMatrix = cv::getAffineTransform(srcPoints, dstPoints);
cv::warpAffine(resizedImage, shearedImage, transformMatrix, resizedImage.size());

Here is the complete code in Qt

    #include "mainwindow.h"
    #include <QApplication>
    #include <opencv2/opencv.hpp>
    #include <QDebug>
    #include <QLabel>
    int main(int argc, char* argv[])
    {
        QApplication a(argc, argv);

    // Load the original image
    cv::Mat originalImage = cv::imread("Pic1.jpg");

    // Crop the image
    cv::Rect roi(200, 300, 1350, 850);
    cv::Mat croppedImage = originalImage(roi);

    // Resize the cropped image
    cv::Mat resizedImage;
    cv::resize(croppedImage, resizedImage, cv::Size(), 0.4, 0.4);

    // Shear the resized image
    cv::Mat shearedImage;
    cv::Point2f srcPoints[3] = {cv::Point2f(0, 0), cv::Point2f(resizedImage.cols, 0), cv::Point2f(0, resizedImage.rows)};
    cv::Point2f dstPoints[3] = {cv::Point2f(0, 0), cv::Point2f(resizedImage.cols, 0), cv::Point2f(0, resizedImage.rows)};
    cv::Mat transformMatrix = cv::getAffineTransform(srcPoints, dstPoints);
    cv::warpAffine(resizedImage, shearedImage, transformMatrix, resizedImage.size());

           // Display the shear image
    cv::namedWindow("Transformed Image");
    cv::imshow("Transformed Image", shearedImage);

    MainWindow w;
    w.show();
    return a.exec();
}

Solution

  • I searched more and found more details, based on this Question, I should use cv::warpPerspective instead of affine transform to change the image perspective.

    enter image description here here is the output and code:

        #include "mainwindow.h"
        #include <QApplication>
        #include <opencv2/opencv.hpp>
        #include <QDebug>
        #include <QLabel>
        
        cv::Point2f srcPoints[4];
        int pointCounter = 0;
        
    /*using mouseCallback function to selecting 4 points by left click for changing image perspective.*/
        void mouseCallback(int event, int x, int y, int flags, void* userdata)
        {
            if (event == cv::EVENT_LBUTTONDOWN && pointCounter < 4)
            {
                srcPoints[pointCounter] = cv::Point2f(x, y);
                pointCounter++;
                qDebug() << "Selected point: (" << x << ", " << y << ")";
            }
        }
        
        int main(int argc, char* argv[])
        {
            QApplication a(argc, argv);
        
            // Load the original image
            cv::Mat Image = cv::imread("image1.jpg");
            if (Image.empty())
            {
                qDebug() << "Failed to load image";
                return -1;
            }
        
            // Resize the cropped image
            cv::Mat originalImage;
            cv::resize(Image, originalImage, cv::Size(), 0.9, 0.9);
        
            // Create a window to display the image
            cv::namedWindow("Original Image");
            cv::imshow("Original Image", originalImage);
        
            // Set mouse callback
            cv::setMouseCallback("Original Image", mouseCallback);
        // Display instructions to the user
    //    cv::putText(originalImage, "Select points from left to right and clockwise", cv::Point(10, 30),
    //                cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 0, 255), 2);
        cv::imshow("Original Image", originalImage);
        
            // Wait until 4 points are selected
            while (pointCounter < 4)
            {
                char key = cv::waitKey(10);
                if (key == 27)  // Esc key
                {
                    qDebug() << "Selection aborted";
                    return 0;
                }
            }
            cv::destroyWindow("Original Image");
        
            // Generate the perspective transform matrix
            cv::Point2f dstPoints[4] = {cv::Point2f(0, 0), cv::Point2f(originalImage.cols, 0), cv::Point2f(originalImage.cols, originalImage.rows), cv::Point2f(0, originalImage.rows)};
            cv::Mat perspectiveMatrix = cv::getPerspectiveTransform(srcPoints, dstPoints);
        
            // Apply the perspective transform
            cv::Mat transformedImage;
            cv::warpPerspective(originalImage, transformedImage, perspectiveMatrix,  originalImage.size());
        
            // Display the transformed image
            cv::namedWindow("Transformed Image");
            cv::imshow("Transformed Image", transformedImage);
        MainWindow w;
            w.show();
            return a.exec();
        }