Home > Software engineering >  Qt / OpenCV - Resizing an Image doesn't work with specific sizes
Qt / OpenCV - Resizing an Image doesn't work with specific sizes

Time:05-08

I made an Image Editor in Qt / OpenCV where you can load the Image from the File explorer and grayscale/adaptive threshold/resize it afterwards.

Bug 1: When I resize the Loaded Image to (for example) 600x600 Pixels using my ImageProcessor::Resize(int, int) method, it works fine. But when I change it to like 546x750 Pixels, the Image has a weird grayscale.

Bug 2: When I want to resize my Grayscaled/Thresholded Image, it always gets a weird grayscale similiar to Bug 1.

Codes:

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "resizer.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::Display(cv::Mat inputImage)
{
        QImage image = QImage(inputImage.data, inputImage.cols, inputImage.rows, QImage::Format_RGB888);
        scene->addPixmap(QPixmap::fromImage(image));
        ui->graphicsView->setScene(scene);
        ui->graphicsView->show();
}


void MainWindow::on_actionOpen_triggered()
{
    QString file = QFileDialog::getOpenFileName(this, "Open", "", "Images (*.jpg *.png)");
    std::string filename = file.toStdString();
    inputImage = cv::imread(filename);
    Display(inputImage);

    imgProc = new ImageProcessor(inputImage);
}


void MainWindow::on_pushButton_clicked() // Grayscale
{
    scene->clear();

    imgProc->mode = 1;
    inputImage = imgProc->Grayscale();

    QImage image = QImage(inputImage.data, inputImage.cols, inputImage.rows, QImage::Format_Grayscale8);
    scene->addPixmap(QPixmap::fromImage(image));
    ui->graphicsView->setScene(scene);
    ui->graphicsView->show();
}


void MainWindow::on_pushButton_2_clicked() // ADT
{
    scene->clear();

    imgProc->mode = 2;
    inputImage = imgProc->AdaptiveThreshold();

    QImage image = QImage(inputImage.data, inputImage.cols, inputImage.rows, QImage::Format_Grayscale8);
    scene->addPixmap(QPixmap::fromImage(image));
    ui->graphicsView->setScene(scene);
    ui->graphicsView->show();
}


void MainWindow::on_pushButton_3_clicked() // Resize
{
    scene->clear();

    Resizer resizer;
    resizer.exec();

    int newWidth = resizer.GetWidth();
    int newHeight = resizer.GetHeight();

    inputImage = imgProc->Resize(newWidth, newHeight);

    if(imgProc->mode == 1 || imgProc->mode == 2)
    {
        QImage image = QImage(inputImage.data, inputImage.cols, inputImage.rows, QImage::Format_Grayscale8);
        scene->addPixmap(QPixmap::fromImage(image));
        ui->graphicsView->setScene(scene);
        ui->graphicsView->show();
    }
    else
    {
        QImage image = QImage(inputImage.data, inputImage.cols, inputImage.rows, QImage::Format_RGB888);
        scene->addPixmap(QPixmap::fromImage(image));
        ui->graphicsView->setScene(scene);
        ui->graphicsView->show();
    }
}


imageprocessor.cpp

#include "imageprocessor.h"

ImageProcessor::ImageProcessor(cv::Mat inputImage)
{
    this->inputImage = inputImage;
}

cv::Mat ImageProcessor::Resize(int width, int height)
{
    cv::Mat resized;
    cv::resize(inputImage, resized, cv::Size(width, height), cv::INTER_LINEAR);
    return resized;
}

cv::Mat ImageProcessor::Grayscale()
{
    cv::Mat grayscaled;
    cv::cvtColor(inputImage, grayscaled, cv::COLOR_RGB2GRAY);
    return grayscaled;
}

cv::Mat ImageProcessor::AdaptiveThreshold()
{
    cv::Mat binarized, grayscaled;
    cv::cvtColor(inputImage, grayscaled, cv::COLOR_RGB2GRAY);
    cv::adaptiveThreshold(grayscaled, binarized, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 15, 11);
    return binarized;
}

CodePudding user response:

QImage::Format_RGB888 is the format type you defined means that:

The image is stored using a 24-bit RGB format (8-8-8).

If your image has 3 channels then your way is correct to continue, except adding this:

QImage image = QImage(inputImage.data, inputImage.cols, inputImage.rows, QImage::Format_RGB888).rgbSwapped();

You need to add at the end rgbSwapped() because Qt reads it in RGB order as OpenCV gives BGR.

If you want to send a gray scale image to GUI then you need to use QImage::Format_Grayscale8 format type, which means:

The image is stored using an 8-bit grayscale format.

Here is the clear cocumentation for the formats.

Note: How do you resize your image, by using OpenCV function ? Share resizer.h , I will update the answer accordingly.

CodePudding user response:

I added rgbSwapped(), but it still doesn't work. I resize the Image via Dialog (resizer.h/.cpp), in which I enter the new values usin lineEdits.

resizer.h:

#ifndef RESIZER_H
#define RESIZER_H

#include <QDialog>

namespace Ui {
class Resizer;
}

class Resizer : public QDialog
{
    Q_OBJECT

public:
    explicit Resizer(QWidget *parent = nullptr);
    ~Resizer();

    int GetWidth();
    int GetHeight();

private slots:
    void on_bt_Adapt_accepted();

private:
    Ui::Resizer *ui;
};

#endif // RESIZER_H

resizer.cpp:

#include "resizer.h"
#include "ui_resizer.h"

Resizer::Resizer(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Resizer)
{
    ui->setupUi(this);
}

Resizer::~Resizer()
{
    delete ui;
}

int Resizer::GetWidth()
{
    QString input = ui->lnWidth->text();
    int width = input.toInt();
    return width;
}

int Resizer::GetHeight()
{
    QString input = ui->lnHeight->text();
    int height = input.toInt();
    return height;
}

void Resizer::on_bt_Adapt_accepted()
{

}

  • Related