Switch qt to gtk

This commit is contained in:
2023-06-25 18:15:25 +02:00
parent 7c2cd2fff0
commit 82b6094c1e
2 changed files with 215 additions and 177 deletions

View File

@@ -1,14 +1,22 @@
cmake_minimum_required(VERSION 3.18)
project(TV_Denoising_CUDA)
# Find CUDA
enable_language(CUDA)
# Set tool chain
set(VCPKG_DIR "E:/programming/vcpkg")
set(VCPKG_INSTALLED_DIR "${VCPKG_DIR}/installed")
set(CMAKE_TOOLCHAIN_FILE "${VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "Vcpkg toolchain file")
# Find GTK3
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
# Find OpenCV
set(VCPKG_INSTALLED_DIR "E:/programming/vcpkg/installed")
set(OpenCV_DIR "${VCPKG_INSTALLED_DIR}/x64-windows/share/opencv2")
find_package(OpenCV REQUIRED)
# Find CUDA
enable_language(CUDA)
# Set CUDA flags and properties
set(CUDA_SEPARABLE_COMPILATION ON)
set(CUDA_PROPAGATE_HOST_FLAGS OFF)
@@ -21,10 +29,12 @@ set_source_files_properties(${CUDA_SOURCE_FILES} PROPERTIES CUDA_SOURCE_PROPERTY
file(GLOB CPP_SOURCE_FILES "src/*.cpp")
# Set the include directories
include_directories(${OpenCV_DIR} ${CUDA_INCLUDE_DIRS} "include")
include_directories(${OpenCV_DIR} ${CUDA_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} "include")
# Create the executable
add_executable(TV_Denoising_CUDA ${CPP_SOURCE_FILES} ${CUDA_SOURCE_FILES})
# Link CUDA libraries
target_link_libraries(TV_Denoising_CUDA ${CUDA_LIBRARIES})
target_link_libraries(TV_Denoising_CUDA ${CUDA_LIBRARIES} ${GTK3_LIBRARIES})
target_compile_options(TV_Denoising_CUDA PUBLIC ${GTK3_CFLAGS_OTHER})

View File

@@ -15,33 +15,24 @@ Description:
- <iterations> is the number of iterations for TV denoising (optional, default: 10).
*/
#include <iostream>
#include <gtk/gtk.h>
#include <opencv2/opencv.hpp>
#include <QApplication>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QSlider>
#include <QFileDialog>
#include <QMessageBox>
#include <QImage>
#include "tv_denoising.hpp"
// Global variables for GUI elements
QLabel* originalImageLabel;
QLabel* resultImageLabel;
QLineEdit* inputImagePathEdit;
QLineEdit* outputImagePathEdit;
QSlider* lambdaSlider;
QSlider* iterationsSlider;
GtkLabel* originalImageLabel;
GtkLabel* resultImageLabel;
GtkEntry* inputImagePathEntry;
GtkEntry* outputImagePathEntry;
GtkScale* lambdaScale;
GtkScale* iterationsScale;
void updateDenoisedImage()
static void updateDenoisedImage(GtkWidget* widget, gpointer data)
{
std::string inputImagePath = inputImagePathEdit->text().toStdString();
std::string outputImagePath = outputImagePathEdit->text().toStdString();
float lambda = lambdaSlider->value() / 100.0;
int iterations = iterationsSlider->value();
std::string inputImagePath = gtk_entry_get_text(inputImagePathEntry);
std::string outputImagePath = gtk_entry_get_text(outputImagePathEntry);
float lambda = gtk_range_get_value(GTK_RANGE(lambdaScale)) / 100.0;
int iterations = gtk_range_get_value(GTK_RANGE(iterationsScale));
// Read the input image
cv::Mat image = cv::imread(inputImagePath, cv::IMREAD_GRAYSCALE);
@@ -49,7 +40,10 @@ void updateDenoisedImage()
// Check if the image was successfully loaded
if (image.empty())
{
QMessageBox::critical(nullptr, "Error", "Failed to read the input image.");
GtkWidget* dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
"Failed to read the input image.");
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
return;
}
@@ -57,92 +51,126 @@ void updateDenoisedImage()
TVDenoising(image, lambda, iterations);
// Display the denoised image
QImage resultImage(image.data, image.cols, image.rows, QImage::Format_Grayscale8);
resultImageLabel->setPixmap(QPixmap::fromImage(resultImage));
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(image.data, GDK_COLORSPACE_RGB, FALSE, 8, image.cols, image.rows,
image.step, NULL, NULL);
gtk_image_set_from_pixbuf(GTK_IMAGE(resultImageLabel), pixbuf);
g_object_unref(pixbuf);
// Save the denoised image
cv::imwrite(outputImagePath, image);
}
void openInputImage()
static void openInputImage(GtkWidget* widget, gpointer data)
{
QString filePath = QFileDialog::getOpenFileName(nullptr, "Select Input Image");
if (!filePath.isEmpty())
inputImagePathEdit->setText(filePath);
GtkWidget* dialog = gtk_file_chooser_dialog_new("Select Input Image", GTK_WINDOW(data), GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel", GTK_RESPONSE_CANCEL, "Open", GTK_RESPONSE_ACCEPT, NULL);
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
{
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
gtk_entry_set_text(inputImagePathEntry, filename);
g_free(filename);
}
gtk_widget_destroy(dialog);
}
void openOutputImage()
static void openOutputImage(GtkWidget* widget, gpointer data)
{
QString filePath = QFileDialog::getSaveFileName(nullptr, "Select Output Image");
if (!filePath.isEmpty())
outputImagePathEdit->setText(filePath);
GtkWidget* dialog = gtk_file_chooser_dialog_new("Select Output Image", GTK_WINDOW(data), GTK_FILE_CHOOSER_ACTION_SAVE,
"Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL);
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
{
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
gtk_entry_set_text(outputImagePathEntry, filename);
g_free(filename);
}
gtk_widget_destroy(dialog);
}
int main(int argc, char** argv)
{
QApplication app(argc, argv);
// Initialize GTK
gtk_init(&argc, &argv);
// Create the main window
QWidget window;
window.setWindowTitle("TV Image Denoising");
window.resize(800, 600);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "TV Image Denoising");
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
// Create the layout
QVBoxLayout* layout = new QVBoxLayout(&window);
// Create the main vertical box layout
GtkWidget* vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add(GTK_CONTAINER(window), vbox);
// Create the original image label
originalImageLabel = new QLabel("Original Image");
layout->addWidget(originalImageLabel);
originalImageLabel = GTK_LABEL(gtk_label_new("Original Image"));
gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(originalImageLabel), FALSE, FALSE, 0);
// Create the result image label
resultImageLabel = new QLabel("Result Image");
layout->addWidget(resultImageLabel);
resultImageLabel = GTK_LABEL(gtk_label_new("Result Image"));
gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(resultImageLabel), FALSE, FALSE, 0);
// Create the input image path input field
QHBoxLayout* inputLayout = new QHBoxLayout;
QLabel* inputLabel = new QLabel("Input Image:");
inputImagePathEdit = new QLineEdit;
QPushButton* inputBrowseButton = new QPushButton("Browse");
QObject::connect(inputBrowseButton, &QPushButton::clicked, openInputImage);
inputLayout->addWidget(inputLabel);
inputLayout->addWidget(inputImagePathEdit);
inputLayout->addWidget(inputBrowseButton);
layout->addLayout(inputLayout);
GtkWidget* inputImageHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start(GTK_BOX(vbox), inputImageHBox, FALSE, FALSE, 0);
GtkWidget* inputImageLabel = gtk_label_new("Input Image:");
gtk_box_pack_start(GTK_BOX(inputImageHBox), inputImageLabel, FALSE, FALSE, 0);
inputImagePathEntry = GTK_ENTRY(gtk_entry_new());
gtk_box_pack_start(GTK_BOX(inputImageHBox), GTK_WIDGET(inputImagePathEntry), TRUE, TRUE, 0);
GtkWidget* inputBrowseButton = gtk_button_new_with_label("Browse");
g_signal_connect(inputBrowseButton, "clicked", G_CALLBACK(openInputImage), window);
gtk_box_pack_start(GTK_BOX(inputImageHBox), inputBrowseButton, FALSE, FALSE, 0);
// Create the output image path input field
QHBoxLayout* outputLayout = new QHBoxLayout;
QLabel* outputLabel = new QLabel("Output Image:");
outputImagePathEdit = new QLineEdit;
QPushButton* outputBrowseButton = new QPushButton("Browse");
QObject::connect(outputBrowseButton, &QPushButton::clicked, openOutputImage);
outputLayout->addWidget(outputLabel);
outputLayout->addWidget(outputImagePathEdit);
outputLayout->addWidget(outputBrowseButton);
layout->addLayout(outputLayout);
GtkWidget* outputImageHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start(GTK_BOX(vbox), outputImageHBox, FALSE, FALSE, 0);
// Create the lambda slider
QLabel* lambdaLabel = new QLabel("Lambda:");
lambdaSlider = new QSlider(Qt::Horizontal);
lambdaSlider->setMinimum(0);
lambdaSlider->setMaximum(100);
layout->addWidget(lambdaLabel);
layout->addWidget(lambdaSlider);
GtkWidget* outputImageLabel = gtk_label_new("Output Image:");
gtk_box_pack_start(GTK_BOX(outputImageHBox), outputImageLabel, FALSE, FALSE, 0);
// Create the iterations slider
QLabel* iterationsLabel = new QLabel("Iterations:");
iterationsSlider = new QSlider(Qt::Horizontal);
iterationsSlider->setMinimum(1);
iterationsSlider->setMaximum(100);
layout->addWidget(iterationsLabel);
layout->addWidget(iterationsSlider);
outputImagePathEntry = GTK_ENTRY(gtk_entry_new());
gtk_box_pack_start(GTK_BOX(outputImageHBox), GTK_WIDGET(outputImagePathEntry), TRUE, TRUE, 0);
GtkWidget* outputBrowseButton = gtk_button_new_with_label("Browse");
g_signal_connect(outputBrowseButton, "clicked", G_CALLBACK(openOutputImage), window);
gtk_box_pack_start(GTK_BOX(outputImageHBox), outputBrowseButton, FALSE, FALSE, 0);
// Create the lambda scale
GtkWidget* lambdaHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start(GTK_BOX(vbox), lambdaHBox, FALSE, FALSE, 0);
GtkWidget* lambdaLabel = gtk_label_new("Lambda:");
gtk_box_pack_start(GTK_BOX(lambdaHBox), lambdaLabel, FALSE, FALSE, 0);
lambdaScale = GTK_SCALE(gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 100, 1));
gtk_scale_set_value_pos(lambdaScale, GTK_POS_RIGHT);
gtk_scale_set_digits(lambdaScale, 2);
gtk_box_pack_start(GTK_BOX(lambdaHBox), GTK_WIDGET(lambdaScale), TRUE, TRUE, 0);
// Create the iterations scale
GtkWidget* iterationsHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start(GTK_BOX(vbox), iterationsHBox, FALSE, FALSE, 0);
GtkWidget* iterationsLabel = gtk_label_new("Iterations:");
gtk_box_pack_start(GTK_BOX(iterationsHBox), iterationsLabel, FALSE, FALSE, 0);
iterationsScale = GTK_SCALE(gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 1, 100, 1));
gtk_scale_set_value_pos(iterationsScale, GTK_POS_RIGHT);
gtk_scale_set_digits(iterationsScale, 0);
gtk_box_pack_start(GTK_BOX(iterationsHBox), GTK_WIDGET(iterationsScale), TRUE, TRUE, 0);
// Create the denoise button
QPushButton* denoiseButton = new QPushButton("Denoise");
QObject::connect(denoiseButton, &QPushButton::clicked, updateDenoisedImage);
layout->addWidget(denoiseButton);
GtkWidget* denoiseButton = gtk_button_new_with_label("Denoise");
g_signal_connect(denoiseButton, "clicked", G_CALLBACK(updateDenoisedImage), NULL);
gtk_box_pack_start(GTK_BOX(vbox), denoiseButton, FALSE, FALSE, 0);
// Show the main window
window.show();
// Show all widgets
gtk_widget_show_all(window);
return app.exec();
// Run the GTK main loop
gtk_main();
return 0;
}