我有一组从物体右侧拍摄的图像,例如图像1。我需要绕垂直轴旋转它并将其更改为像 image2 那样。
仿射变换对于将 image1 转换为 image2 有用吗? 我使用仿射变换并使用它,但没有得到想要的结果。我应该怎么办? 我用这部分代码进行图像转换。
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());
这是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());
// Find contours and draw rectangles
cv::Mat binaryImage;
cv::cvtColor(shearedImage, binaryImage, cv::COLOR_BGR2GRAY);
cv::threshold(binaryImage, binaryImage, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
std::vector<std::vector<cv::Point>> contours;
cv::findContours(binaryImage, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
cv::Mat imageWithRectangles = shearedImage.clone();
int rectangleCount = 0;
for (const auto& contour : contours) {
cv::Rect boundingRect = cv::boundingRect(contour);
if (boundingRect.width > 50 && boundingRect.height > 50 /*&& boundingRect.width < 150 && boundingRect.height < 150*/) // Ignore small rectangles
{
rectangleCount++;
cv::rectangle(imageWithRectangles, boundingRect, cv::Scalar(0, 255, 0), 2);
}
}
// Display the resized image, sheared image, and image with rectangles
cv::Mat mergedImage;
cv::vconcat(imageWithRectangles, shearedImage, mergedImage);
cv::vconcat(mergedImage,resizedImage , mergedImage);
cv::namedWindow("Resized Image, Sheared Image, and Rectangles");
cv::imshow("Resized Image, Sheared Image, and Rectangles", mergedImage);
cv::waitKey(0);
qDebug() << "Number of Rectangles: " << rectangleCount;
MainWindow w;
w.show();
return a.exec();
}
我搜索了更多并找到了更多细节,基于这个问题,我应该使用
cv::warpPerspective
而不是仿射变换(它有效吗?)。
这是输出和代码:
#include "mainwindow.h"
#include <QApplication>
#include <opencv2/opencv.hpp>
#include <QDebug>
#include <QLabel>
cv::Point2f srcPoints[4];
int pointCounter = 0;
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("D:\\JTI_Images\\Pic1\\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();
}