如何 translate/crop 具有亚像素精度的 QImage?
How to translate/crop a QImage with subpixel accuracy?
用例是一个二维地图,原点有车辆。地图也应翻译以防车辆移动,例如0.5 像素。我相信这应该是可行的使用双线性插值或类似的。
如果没有使用 Qt 的简单解决方案,我将不胜感激对非 Qt 解决方案的提示。
最小示例:
#include <QtWidgets/QApplication>
#include <QtGui/QImage>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// Parameters
QString PATH_IMG_IN = "../img_test_rect.jpg";
QString PATH_IMG_OUT = "../img_out.png";
float TRANSLATE_IN_PX = 0.5;
// load image
QImage img;
img.load(PATH_IMG_IN);
// rotate image.
QTransform trans;
trans.translate(0,TRANSLATE_IN_PX);
QImage img_new = img.transformed(trans, Qt::SmoothTransformation);
// save image
img_new.save(PATH_IMG_OUT, nullptr, 100);
// optional: Get info about true transformation matrix
QTransform trans_true = QImage::trueMatrix(trans, img.width(), img.height());
return app.exec();
}
给定一个边界清晰的输入图像(见下文),我希望输出图像具有模糊的边界。事实并非如此:
如何解决?
我测试了 openCV,它的功能 cv::warpAffine 允许以亚像素精度进行翻译(参见下面的 MWE)。
在 qtcentre.org 上发现一些旧的、未回答的线程后,在我看来 Qt 根本不允许以亚像素精度进行翻译。如有不妥请指正
对于 Qt,我只找到了先缩放图像、以像素精度转换并再次缩小的变通方法。不幸的是,这种方法对于我的用例来说计算成本太高。
带有 opencv 的 MWE:
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
int main(int argc, char** argv) {
// parameters
std::string PATH_IMG_IN = "../img_test_rect.jpg";
std::string PATH_IMG_OUT = "../img_out.jpg";
// load image
cv::Mat img = cv::imread(PATH_IMG_IN, CV_LOAD_IMAGE_GRAYSCALE);
if (!img.data) // Check for invalid input
{
std::cout << "Could not open or find the image" << std::endl;
return -1;
}
// rotate image
cv::Mat img_new = cv::Mat::ones(img.size(), img.type()) * 0.5; // another type = CV_8U
cv::Mat mat_transform = (cv::Mat_<float>(2, 3) << 1, 0, 0.5, 0, 1, 0);
cv::warpAffine(img, img_new, mat_transform, img_new.size());
// show image
cv::imshow("Display window", img_new);
// save image
cv::imwrite(PATH_IMG_OUT, img_new);
// wait for the user to press any key:
cv::waitKey(0);
return 0;
}
用例是一个二维地图,原点有车辆。地图也应翻译以防车辆移动,例如0.5 像素。我相信这应该是可行的使用双线性插值或类似的。
如果没有使用 Qt 的简单解决方案,我将不胜感激对非 Qt 解决方案的提示。
最小示例:
#include <QtWidgets/QApplication>
#include <QtGui/QImage>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// Parameters
QString PATH_IMG_IN = "../img_test_rect.jpg";
QString PATH_IMG_OUT = "../img_out.png";
float TRANSLATE_IN_PX = 0.5;
// load image
QImage img;
img.load(PATH_IMG_IN);
// rotate image.
QTransform trans;
trans.translate(0,TRANSLATE_IN_PX);
QImage img_new = img.transformed(trans, Qt::SmoothTransformation);
// save image
img_new.save(PATH_IMG_OUT, nullptr, 100);
// optional: Get info about true transformation matrix
QTransform trans_true = QImage::trueMatrix(trans, img.width(), img.height());
return app.exec();
}
给定一个边界清晰的输入图像(见下文),我希望输出图像具有模糊的边界。事实并非如此:
如何解决?
我测试了 openCV,它的功能 cv::warpAffine 允许以亚像素精度进行翻译(参见下面的 MWE)。
在 qtcentre.org 上发现一些旧的、未回答的线程后,在我看来 Qt 根本不允许以亚像素精度进行翻译。如有不妥请指正
对于 Qt,我只找到了先缩放图像、以像素精度转换并再次缩小的变通方法。不幸的是,这种方法对于我的用例来说计算成本太高。
带有 opencv 的 MWE:
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
int main(int argc, char** argv) {
// parameters
std::string PATH_IMG_IN = "../img_test_rect.jpg";
std::string PATH_IMG_OUT = "../img_out.jpg";
// load image
cv::Mat img = cv::imread(PATH_IMG_IN, CV_LOAD_IMAGE_GRAYSCALE);
if (!img.data) // Check for invalid input
{
std::cout << "Could not open or find the image" << std::endl;
return -1;
}
// rotate image
cv::Mat img_new = cv::Mat::ones(img.size(), img.type()) * 0.5; // another type = CV_8U
cv::Mat mat_transform = (cv::Mat_<float>(2, 3) << 1, 0, 0.5, 0, 1, 0);
cv::warpAffine(img, img_new, mat_transform, img_new.size());
// show image
cv::imshow("Display window", img_new);
// save image
cv::imwrite(PATH_IMG_OUT, img_new);
// wait for the user to press any key:
cv::waitKey(0);
return 0;
}