Как перевести / обрезать QImage с субпиксельной точностью? - PullRequest
0 голосов
/ 14 сентября 2018

Вариант использования - 2D-карта с автомобилем в начале координат.Карта также должна быть переведена, если транспортное средство движется, например, на 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();
}

Учитывая, что входное изображение имеет четкую границу (см. Ниже), я ожидаю, что выходное изображение будет иметь размытую границу.Это не тот случай:

enter image description here

Как это исправить?

1 Ответ

0 голосов
/ 17 сентября 2018

Я протестировал openCV и его функцию cv :: warpAffine, позволяющую переводить с точностью до субпикселя (см. MWE ниже).

После того, как на qtcentre.org были обнаружены некоторые старые неотвеченные темы, мне кажется, что Qtпросто не позволяет перевод с точностью до субпикселя.Пожалуйста, исправьте меня, если я ошибаюсь.

Для Qt я нашел только обходные пути, чтобы сначала масштабировать изображение, переводить с точностью до пикселя и снова уменьшать.К сожалению, этот подход слишком дорогой для моего случая использования.

MWE с opencv:

#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;
}
...