diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100755 index 7e20276..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -project(ContentAwareResize) -cmake_minimum_required(VERSION 3.5) - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -find_package(OpenCV REQUIRED) -find_package(Boost REQUIRED) - -enable_testing() -set(CMAKE_BUILD_TYPE Release) -set(CMAKE_CXX_STANDARD 14) -include_directories(include) - -add_subdirectory(src/filters) -add_subdirectory(src/utils) -add_subdirectory(src/core) -add_subdirectory(src/interface) -add_subdirectory(src/cui) -add_subdirectory(src/gui) - diff --git a/README b/README deleted file mode 100644 index aaa684a..0000000 --- a/README +++ /dev/null @@ -1,35 +0,0 @@ -XINAR (XINR is not another resizer) - -XINAR is an implementation of Content Aware Resize article. It has a huge -variety of setting to deal with. - - -Build. - -To build XINAR from source you need libboost-program-options, libboost-chrono, -libboost-system, libboost-date-time, libboost-atomic, OpenCV 2. It uses CMake -as building system. - - - -Usage. - -Once you built XINAR, you can use it in 2 ways: as a console application or -via GUI (indev). - -Console usage example: - -1) shrink image example.jpg to 600 by 600 pixels - -:~$ ./xinar -i example.jpg -w 600 -h 600 - -2) shrink image example.jpg to 600 by 600 pixels w/ decreasing quality - -:~$ ./xinar -i example.jpg -w 600 -h 600 -q 0.5 - -All commands are available via -? (--help) flag. - - - - -Copyright Andery Tkachev, Nikita Orlov, Dmitriy Malygin, 2017. \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index dbf2952..0000000 --- a/README.md +++ /dev/null @@ -1,43 +0,0 @@ -### About -This is an implementation of the [real time content aware resize](https://link.springer.com/article/10.1007/s11432-009-0041-9) algorithm. -Project consist from console and gui applications (xinar and uxinar respectively) which provide resize services. - -### Dependencies - -To build XINAR from source you need -* *libboost-program-options* -* *libboost-chrono* -* *libboost-system* -* *libboost-date-time* -* *libboost-atomic* -* *OpenCV 2* - -To build UXinar you also need QT5 *core* & *widgets* libs. -The project uses *CMake >= 3.5* as building system. - - -### Usage - -Once you built XINAR, you can use it in 2 ways: as a console application or -via GUI. - -Console usage example: - -To resize image example_640x540.jpg to 600 by 600 pixels -``` -:~$ ./xinar -i example_640x540.jpg -w 600 -h 600 -``` -All commands are available via ``` -? ``` (```--help```) flag. - - -GUI usage example: - -Just run *uxinar* as executable and choose file to resize in the file menu. - -### Structure - -* **Core** -- *part where resize algorithm is implemented* -* **CUI, GUI** -- *console and graphics applications implementation respectively* - -Copyright [Andery Tkachev](https://github.com/Andrey-Tkachev), [Nikita Orlov](https://github.com/acerikfy), Dmitriy Malygin, 2017. - diff --git a/include/core.h b/include/core.h deleted file mode 100755 index cd71743..0000000 --- a/include/core.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include -#include "matrixwrapper.h" -#include "types.h" - -namespace core { - - // Shrinks/expands width and height of the in image to сorrespond with desirable size - // image 640x640, new size 500x700 -> new image 500x700 - // image 640x640, new size 500x500 -> new image 500x500 etc. - template - void resize_to_fit(const cv::Mat& in, cv::Mat& out, const cv::Size& new_size, TFilter filter); - - Seams get_seams(const MatWrp& energy); - Seams get_seams(const MatWrp& energy, int k); - - void remove_seams(MatWrp& from, Seams seams); - void add_seams(MatWrp& from, Seams seams); - - void resize_with_seams(MatWrp& in, int delta, const Seams& seams); - - template - void resize_with_filter(MatWrp& in, int delta, const TFilter& filter) { - if (delta == 0) return; - MatWrp energy; - energy.set_orientation(in); - filter(in.mat, energy.mat); - auto seams = get_seams(energy, std::abs(delta)); - if (delta > 0) { - remove_seams(in, seams); - } else if (delta < 0) { - add_seams(in, seams); - } - for (auto seam : seams) { - delete seam; - } - } - - - - template - void resize_to_fit(const cv::Mat &in, cv::Mat &out, const cv::Size &new_size, TFilter filter) { - cv::Size in_size = in.size(); - MatWrp in_wrp(in.clone()); - - resize_with_filter(in_wrp, in_size.width - new_size.width, filter); - in_wrp.transpose(); - resize_with_filter(in_wrp, in_size.height - new_size.height, filter); - - out = in_wrp.mat; - } -} diff --git a/include/filters.h b/include/filters.h deleted file mode 100755 index 3d8c727..0000000 --- a/include/filters.h +++ /dev/null @@ -1,165 +0,0 @@ -#pragma once - -#include "opencv2/opencv.hpp" -#include "matrixwrapper.h" - -namespace filter { - class Filter { - public: - virtual void operator()(cv::Mat& src, cv::Mat &dst) const = 0; - - virtual ~Filter() {} - }; - - - class GausBlur : public Filter { - private: - cv::Size ksize; // only positive uneven - double sX = 0; // sigmaX - double sY = 0; // sigmaY - int bt = cv::BORDER_DEFAULT; // boarder type - - public: - GausBlur(cv::Size size, double X, double Y, int borT); - - void operator()(cv::Mat& src, cv::Mat &dst) const override; - - cv::Size getKsize(); - - double getSX(); - - double getSY(); - - int getBt(); - - void setKsize(cv::Size other); - - void setSX(double other); - - void setSY(double other); - - void setBt(int other); - }; - - - class Sobel : public Filter { - private: - int xord; // 0, 1 or 2 - int yord; // if one of them == 0, other != 0 - int ksize = 3; // aperture size - double scale = 1; // optional scale factor for the computed derivative values - double delta = 0; // optional delta value that is added to the results prior to storing them in dst. - int ddepth = IPL_DEPTH_16S; // output image depth - int bt = cv::BORDER_DEFAULT; // boarder type - - public: - Sobel(int x, int y, int size, double sc, double del, int ddepth, - int bT); - - void operator()(cv::Mat& src, cv::Mat &dst) const override; - - int getXord(); - - int getYord(); - - int getKsize(); - - double getScale(); - - double getDelta(); - - int getDdepth(); - - int getBt(); - - void setXord(int other); - - void setYord(int other); - - void setKsize(int other); - - void setScale(double other); - - void setDelta(double other); - - void setDdepth(int other); - - void setBt(int other); - }; - - class Canny : public Filter { - private: - int low_threshold = 30; - int ratio = 3; - int kernel_size = 3; - - - public: - Canny(int low_threshold, int ratio, int kernel_size); - - void operator()(cv::Mat& src, cv::Mat &dst) const override; - - int getLowThreshold(); - - int getRatio(); - - int getKernelSize(); - - void setLowThreshold(int other); - - void setRatio(int other); - - void setKernelSize(int other); - - }; - - class Blur : public Filter { - private: - int sigma; - - public: - Blur(int sigma); - - void operator()(cv::Mat& src, cv::Mat &dst) const override; - - int getSigma(); - - void setSigma(int other); - }; - - class GrayScale : public Filter { - public: - GrayScale(); - - void operator()(cv::Mat& src, cv::Mat &dst) const override; - }; - - class Compose { - private: - std::vector fil; // filtres - - public: - Compose() = default; - - explicit Compose(const std::vector &filters) - : fil(filters) { - } - - void operator()(cv::Mat& src, cv::Mat &dst) const { - dst = src.clone(); - for (auto filter : fil) { - (*filter)(dst, dst); - } - } - - void operator()(core::MatWrp src, core::MatWrp dst) const { - auto src_ = src.mat; - auto dst_ = src.mat.clone(); - for (auto filter : fil) { - (*filter)(dst_, dst_); - } - dst.mat = dst_; - } - - }; -} diff --git a/include/imageviewer.h b/include/imageviewer.h deleted file mode 100755 index 801d98a..0000000 --- a/include/imageviewer.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include - -#include "resizable_label.h" - -class QAction; -class QMenu; - -class ImageViewer : public QMainWindow { -public: - ImageViewer(); - bool loadFile(const QString &); - -private slots: - void open(); - void saveAs(); - void copy(); - void paste(); - - void about(); - -private: - void createActions(); - void createMenus(); - void updateActions(); - bool saveFile(const QString &fileName); - void setImage(const QImage &newImage); - - QImage image; - ResizableQLabel *imageLabel; - - QAction *saveAsAct; - QAction *copyAct; -}; diff --git a/include/interface.h b/include/interface.h deleted file mode 100755 index c31a3f4..0000000 --- a/include/interface.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include"io.h" -#include "matrixwrapper.h" -#include "types.h" -#include "filters.h" - -namespace interface { - /** - * Class Reize - * - * Holds an image and all seams that are precalculated in initialization. - * When a resize query is get deletes lowest-value seams. - */ - class Resize { - private: - core::MatWrp image; // original image - - filter::Compose filter; // filters - - Seams hseams; // horizontal seams - Seams vseams; // vertical seams - - public: - Resize(); - void init(cv::Mat&& in); - ~Resize(); - - bool is_init() const; - - void process(cv::Mat& result, cv::Size new_size); - }; - - filter::Compose build_filters(); - - /** - * Deprecated methiod - */ - - void process_image(io::Input in, io::Output out, cv::Size size, bool show_images); - - //Filter *build_filters(); - -} diff --git a/include/io.h b/include/io.h deleted file mode 100755 index bd32549..0000000 --- a/include/io.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include - -namespace io { - class IO { - protected: - std::string path; - - public: - IO(); - - IO(std::string path_); - - }; - - - class Input : protected IO { - public: - Input(); - - Input(std::string path_); - - cv::Mat read_image(); - - std::string get_path(); - }; - - - class Output : protected IO { - public: - Output(); - - Output(std::string path_); - - void write_image(cv::Mat &mat); - - std::string get_path(); - - - }; - - Input bind_input(const std::string &path); - - Output bind_output(const std::string &path); - - boost::program_options::variables_map parse_console_arguments(int ac, char **av); -} diff --git a/include/matrixwrapper.h b/include/matrixwrapper.h deleted file mode 100755 index c248b27..0000000 --- a/include/matrixwrapper.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include - -namespace core { - class MatWrp { - private: - bool transposed; - public: - cv::Mat mat; - - MatWrp(); - - MatWrp(const MatWrp &other); - - MatWrp(const cv::Mat &other); - - MatWrp(int h, int w, int type); - - MatWrp clone() const; - - - bool is_transposed() const; - - const int width() const; - - const int height() const; - - template - T &at(int i, int j); - - template - const T &at(int i, int j) const; - - void transpose(); - - void set_shape(const MatWrp &other); - - void set_shape(const MatWrp &other, int type); - - void set_orientation(const MatWrp &other); - - MatWrp operator()(cv::Range rowRange, cv::Range colRange) const; - - MatWrp &operator=(const MatWrp &other); - }; - - template - TData & - MatWrp::at(int i, int j) { - return ((this->transposed) ? - (this->mat).at(j, i) : - (this->mat).at(i, j)); // Hello, opencv index style - } - - template - const TData & - MatWrp::at(int i, int j) const { - return ((this->transposed) ? - (this->mat).at(j, i) : - (this->mat).at(i, j)); // Hello, opencv index style - } - -} diff --git a/include/resizable_label.h b/include/resizable_label.h deleted file mode 100644 index e10b921..0000000 --- a/include/resizable_label.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "interface.h" - -QImage Mat2QImage(cv::Mat const& src); -cv::Mat QImage2Mat(QImage const& src); - -class ResizableQLabel : public QLabel -{ -public: - interface::Resize resizer; - ResizableQLabel(); - void resizeEvent(QResizeEvent* event); - void setPixmap(const QPixmap &pixmap); -}; diff --git a/include/singleton.h b/include/singleton.h deleted file mode 100755 index b4a2254..0000000 --- a/include/singleton.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by nikita on 05.07.17. -// - -#ifndef CONTENTAWARERESIZE_SINGLETON_H -#define CONTENTAWARERESIZE_SINGLETON_H - -template -class Singleton { -public: - static T &Instance() { - static T instance; - return instance; - } - -protected: - Singleton() {}; - - ~Singleton() {}; - -public: - Singleton(Singleton const &) = delete; - - Singleton &operator=(Singleton const &) = delete; - -}; - -#endif //CONTENTAWARERESIZE_SINGLETON_H diff --git a/include/types.h b/include/types.h deleted file mode 100755 index 0bcf0dd..0000000 --- a/include/types.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -typedef long long WeightData; -typedef uchar EnergyData; -typedef std::vector seam; // Path to add/remove along - -typedef std::vector Seams; diff --git a/include/utils.h b/include/utils.h deleted file mode 100755 index f6d2d31..0000000 --- a/include/utils.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include - -using NUMBER = int; - -constexpr int NUMBER_BITS = std::numeric_limits::digits; - -namespace utils { - template - struct pair { - int first; - T* second; - }; - - template - void radix_sort(It begin, It end, F f) { - using DATA_TYPE = typeof(*begin); - - size_t data_size = end - begin; - - std::vector> data; - data.resize(data_size); - - auto at = [begin](int x) { return (begin + x); }; - - for (size_t i = 0; i != data_size; ++i) { - data[i].first = f(*at(i)); - data[i].second = *at(i); - } - - std::vector> tmp(data.begin(), data.end()); - - for (int shift = NUMBER_BITS; shift >= 0; --shift) { - int j = 0; - for (int i = 0; i != data_size; ++i) { - bool move = (data[i].first << shift) >= 0; - if (shift == 0 == !move) { - data[i - j] = data[i]; - } else { - tmp[j++] = data[i]; - } - } - std::copy(tmp.begin(), tmp.begin() + j, data.end() - j); - } - - for (int i = 0; i != data_size; ++i) { - *(begin + i) = data[i].second; - } - } - - - void radix_sort(std::vector& data) { - std::vector tmp(data.begin(), data.end()); - - for (int shift = NUMBER_BITS; shift >= 0; --shift) { - int j = 0; - for (int i = 0; i != data.size(); ++i) { - bool move = (data[i] << shift) >= 0; - if (shift == 0 == !move) { - data[i - j] = data[i]; - } else { - tmp[j++] = data[i]; - } - } - std::copy(tmp.begin(), tmp.begin() + j, data.end() - j); - } - } -} diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt deleted file mode 100755 index e4595ce..0000000 --- a/src/core/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -set(CORE_SOURCE core.cpp ../utils/matrixwrapper.cpp ../../include/core.h) -#add_library(CORE_LIB SHARED ${CORE_SOURCE}) diff --git a/src/core/core.cpp b/src/core/core.cpp deleted file mode 100755 index 26a6b81..0000000 --- a/src/core/core.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "core.h" -#include "matrixwrapper.h" -#include -#include - -namespace core { - - #define get_w( optimum_energy, seam_energy, i, j, row )\ - ( seam_energy.at(row, i) * optimum_energy.at(row + 1, j) ) - - void calc_optimum_dynamics(const MatWrp& in, MatWrp& dynamics) { - int h = in.height(), - w = in.width(); - for (int i = 0; i < in.width(); ++i) { - dynamics.at(h - 1, i) = in.at(h - 1, i); - } - WeightData val_to_exam; - for (int curr_row = in.height() - 2; curr_row >= 0; --curr_row) { - for (int curr_col = 0; curr_col < w; ++curr_col) { - WeightData curr_min = dynamics.at(curr_row + 1, curr_col) + - in.at(curr_row + 1, curr_col); - - for (int delta = -1; delta <= 1; delta += 2) { - if (delta + curr_col < w && delta + curr_col >= 0) { - val_to_exam = dynamics.at(curr_row + 1, curr_col + delta) + - in.at(curr_row, curr_col); - if (curr_min > val_to_exam) { - curr_min = val_to_exam; - } - } - } - dynamics.at(curr_row, curr_col) = curr_min; - } - } - } - - bool seam_comparator(std::pair& it1, std::pair& it2) { - return it1.first < it2.first; - } - - Seams - get_seams(const MatWrp& energy, int k) { - MatWrp seam_energy; - seam_energy.set_shape(energy); - MatWrp optimum_energy; - optimum_energy.set_shape(energy); - calc_optimum_dynamics(energy, optimum_energy); - - std::vector seams(energy.width()); - for (int i = 0; i < energy.width(); ++i) { - seam_energy.at(0, i) = energy.at(0, i); - seams[i] = new seam(); - seams[i]->reserve(energy.height()); - seams[i]->push_back(0); - } - - for (int row = 0; row < energy.height() - 1; ++row) { - std::vector matches(energy.width()); - matches[0] = get_w(optimum_energy, seam_energy, 0, 0, row); - matches[1] = std::max(matches[0] + get_w(optimum_energy, seam_energy, 1, 1, row), - get_w(optimum_energy, seam_energy, 0, 1, row) + - get_w(optimum_energy, seam_energy, 1, 0, row)); - for (int col = 2; col < energy.width(); ++col) { - WeightData w1 = matches[col - 1] + get_w(optimum_energy, seam_energy, col, col, row); - WeightData w2 = matches[col - 2] + get_w(optimum_energy, seam_energy, col, col - 1, row) + - + get_w(optimum_energy, seam_energy, col - 1, col, row); - matches[col] = std::max(w1, w2); - } - int x = energy.width() - 1; - while (x >= 0) { - WeightData last_match = (x == 0 ? 0 : matches[x - 1]); - if (matches[x] == last_match + get_w(optimum_energy, seam_energy, x, x, row)) { - seams[x]->push_back(x); - seam_energy.at(row + 1, x) = seam_energy.at(row, x) + - energy.at(row + 1, x); - --x; - } else { - seams[x - 1]->push_back(x); - seams[x]->push_back(x - 1); - std::swap(seams[x], seams[x - 1]); - seam_energy.at(row + 1, x - 1) = seam_energy.at(row, x) + - energy.at(row + 1, x - 1); - seam_energy.at(row + 1, x) = seam_energy.at(row, x - 1) + - energy.at(row + 1, x); - x -= 2; - } - } - } - - std::vector> weighted_seams; - weighted_seams.reserve(seams.size()); - for (int i = 0; i != seams.size(); ++i) { - weighted_seams.push_back(std::make_pair(seam_energy.at(energy.height() - 1, i), - seams[i])); - } - std::sort(weighted_seams.begin(), weighted_seams.end(), seam_comparator); - Seams res; - res.reserve(k); - for (int i = 0; i < k; ++i) { - res.push_back(weighted_seams[i].second); - } - - return res; - } - - Seams get_seams(const MatWrp& energy) { - return get_seams(energy, energy.width()); - } - - void add_seams(MatWrp& from, Seams seams) { - int w_delta = static_cast (seams.size()); - MatWrp out(from.mat.rows + (from.is_transposed() ? w_delta : 0), - from.mat.cols + (from.is_transposed() ? 0 : w_delta), from.mat.type()); - out.set_orientation(from); - for (int row = 0; row < from.height(); ++row) { - seam pool; - for (const auto& seam : seams) { - pool.push_back((*seam)[from.height() - row - 1]); - } - std::sort(pool.begin(), pool.end()); - int delta = 0; - int curr_pix = 0; - for (int col = 0; col < from.width(); ++col) { - out.at(row, col + delta) = from.at(row, col); - if (curr_pix < pool.size() && col == pool[curr_pix]) { - ++curr_pix; - delta += 1; - out.at(row, col + delta) = from.at(row, col); - continue; - } - } - } - from = out; - } - - void remove_seams(MatWrp& from, Seams seams) { - for (int row = 0; row < from.height(); ++row) { - seam pool; - for (const auto& seam : seams) { - pool.push_back((*seam)[row]); - } - std::sort(pool.begin(), pool.end()); - int delta = 0; - int curr_pix = 0; - for (register int col = pool[curr_pix]; col < from.width(); ++col) { - if (curr_pix < pool.size() && col == pool[curr_pix]) { - ++curr_pix; - delta -= 1; - continue; - } - from.at(row, col + delta) = from.at(row, col); - } - } - from = from(cv::Range(0, from.height()), cv::Range(0, from.width() - seams.size())).clone(); - } - - void resize_with_seams(MatWrp& in, int delta, const Seams& seams) { - Seams to_procces(seams.begin(), seams.begin() + std::abs(delta)); - if (delta > 0) { - remove_seams(in, to_procces); - } else if (delta < 0) { - add_seams(in, to_procces); - } - } -} \ No newline at end of file diff --git a/src/cui/CMakeLists.txt b/src/cui/CMakeLists.txt deleted file mode 100755 index 1f18a95..0000000 --- a/src/cui/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -#add_executable(xinar console.cpp ${INTERFACE_SOURCE} ${CORE_SOURCES} ${FILTERS_SOURCE} ${UTILS_SORUCE}) -set(CONSOLE_SOURCES - console.cpp - ../../include/core.h - ../core/core.cpp - ../../include/filters.h - ../filters/filters.cpp - ../../include/interface.h - ../interface/interface.cpp - ../../include/io.h - ../utils/io.cpp - ../../include/matrixwrapper.h - ../utils/matrixwrapper.cpp - #../utils/radix.cpp - ../utils/singleton.cpp - ) -add_executable(xinar ${CONSOLE_SOURCES}) - - -target_link_libraries(xinar boost_program_options) -target_link_libraries(xinar ${OpenCV_LIBS}) -#target_link_libraries(xinar INTERFACE_LIB) -#target_link_libraries(xinar SINGLETON_TEMPLATE) -#target_link_libraries(xinar IO_LIB) -#target_link_libraries(xinar FILTERS_LIB) -#target_link_libraries(xinar CORE_LIB) -#target_link_libraries(xinar UTILS_LIB) - - diff --git a/src/cui/console.cpp b/src/cui/console.cpp deleted file mode 100755 index c32b462..0000000 --- a/src/cui/console.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// -// Created by nikita on 05.07.17. -// -#include -#include -#include -#include -#include "io.h" -#include "interface.h" -#include -#include "utils.h" -#include "useful_funcitons_RENAME.cpp" - -namespace po = boost::program_options; - -int main(int argc, char **argv) { - po::variables_map vm; - try { - vm = process_arguments(argc, argv); - } catch (...) { - return 0; - } - - if (vm.count("DEBUG")) { - run_debug_code(); - return 0; - } - - io::Input in; - io::Output out; - - if (vm.count("input-file")) { - in = io::bind_input(vm["input-file"].as()); - } else { - std::cerr << "No input file providen!\n"; - return -1; - } - - auto image = in.read_image(); - if (image.empty()) { - std::cerr << "No image found! Passed: \"" << in.get_path() << "\"."; - return -1; - } - - - int height = 0, width = 0; - - if (vm.count("height")) { - height = vm["height"].as(); - } else { - std::cerr << "No height providen!\n"; - } - if (vm.count("width")) { - width = vm["width"].as(); - } else { - std::cerr << "No width providen!\n"; - } - - if (vm.count("output-file")) { - out = io::bind_output(vm["output-file"].as()); - } else { - out = io::bind_output(vm["input-file"].as() + ".out.jpg"); - } - - interface::Resize resize; - resize.init(in.read_image()); - cv::Mat out_matrix; - resize.process(out_matrix, cv::Size(width, height)); - out.write_image(out_matrix); - -// interface::process_image(in, out, cv::Size(width, height), -// false); - - return 0; -} diff --git a/src/cui/useful_funcitons_RENAME.cpp b/src/cui/useful_funcitons_RENAME.cpp deleted file mode 100755 index f83a6ac..0000000 --- a/src/cui/useful_funcitons_RENAME.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// Created by nikita on 08.07.17. -// - -#pragma once - -#include -#include "utils.h" -#include - -namespace po = boost::program_options; - -po::variables_map process_arguments(int argc, char **argv) { - po::options_description desc("Allowed options"); - desc.add_options() - ("help,?", "| prints help page") - ("input-file,i", po::value(), "| path to input image") - ("output-file,o", po::value(), "| path to output image") - ("width,w", po::value(), "| desirable width") - ("height,h", po::value(), "| desirable height") - ("DEBUG", "| DEBUG MODE") - //("show-images,s", po::value()->default_value(false)->implicit_value(true), - // "| show images windows while working {DEBUG}") - ; - - - po::variables_map vm; - po::store(po::command_line_parser(argc, argv).options(desc).run(), vm); - po::notify(vm); - - if (argc == 1 || vm.count("help")) { - std::cout << "XINAR Content Aware Resize. v.56\n" - << desc; - throw 0; - } - - - return vm; -} - - -void run_debug_code() { - std::vector a, b; - for (int i =0 ; i != 1000 * 1000; ++i) { - a.push_back(rand()); - } - b = a; - auto t0 = std::chrono::system_clock::now(); - //utils::radix_sort(a.begin(), a.end(), [](int a) { return a; }); - utils::radix_sort(a); - std::cout << "Radix sort 1.000.000 numbers: " << (std::chrono::system_clock::now() - t0).count() << '\n'; - auto t1 = std::chrono::system_clock::now(); - std::sort(b.begin(), b.end()); - std::cout << "QSort 1.000.000 numbers: " << (std::chrono::system_clock::now() - t1).count(); -} diff --git a/src/filters/CMakeLists.txt b/src/filters/CMakeLists.txt deleted file mode 100755 index 9287f7a..0000000 --- a/src/filters/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -set(FILTERS_SOURCE filters.cpp ../../include/filters.h) - -#add_library(FILTERS_LIB SHARED ${FILTERS_LIB_SOURCE}) \ No newline at end of file diff --git a/src/filters/filters.cpp b/src/filters/filters.cpp deleted file mode 100755 index e6c5b1b..0000000 --- a/src/filters/filters.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// -// Created by nikita on 07.07.17. -// - - -#include "filters.h" - -namespace filter { - - /*##################################*/ - /*###GAUSSIAN BLUR IMPLEMENTATION###*/ - /*##################################*/ - - GausBlur::GausBlur(cv::Size size, double X = 0, double Y = 0, int borT = cv::BORDER_DEFAULT) { - ksize = size; - sX = sX; - sY = sY; - bt = borT; - } - - void GausBlur::operator()(cv::Mat& src, cv::Mat &dst) const { - cv::GaussianBlur(src, dst, ksize, sX, sY, bt); - } - - cv::Size GausBlur::getKsize() { - return ksize; - } - - double GausBlur::getSX() { - return sX; - } - - double GausBlur::getSY() { - return sY; - } - - int GausBlur::getBt() { - return bt; - } - - void GausBlur::setKsize(cv::Size other) { - ksize = other; - } - - void GausBlur::setSX(double other) { - sX = other; - } - - void GausBlur::setSY(double other) { - sY = other; - } - - void GausBlur::setBt(int other) { - bt = other; - } - - - /*##################################*/ - /*###SOBEL FILTER IMPLEMENTATION####*/ - /*##################################*/ - - - Sobel::Sobel(int x, int y, int size = 3, double sc = 1, double del = 0, int ddepth = CV_16S, - int bT = cv::BORDER_DEFAULT) { - xord = x; - yord = y; - ksize = size; - scale = sc; - delta = del; - ddepth = CV_16S; - bt = bT; - } - - void Sobel::operator()(cv::Mat& src, cv::Mat &dst) const { - cv::Mat grad_x, grad_y; - cv::Sobel(src, grad_x, ddepth, 1, 0, ksize, scale, delta, cv::BORDER_DEFAULT); - cv::convertScaleAbs(grad_x, grad_x); - cv::Sobel(src, grad_y, ddepth, 0, 1, ksize, scale, delta, cv::BORDER_DEFAULT); - cv::convertScaleAbs(grad_y, grad_y); - addWeighted(grad_x, 0.5, grad_y, 0.5, 0, dst); - } - - int Sobel::getXord() { - return xord; - } - - int Sobel::getYord() { - return yord; - } - - int Sobel::getKsize() { - return ksize; - } - - double Sobel::getScale() { - return scale; - } - - double Sobel::getDelta() { - return delta; - } - - int Sobel::getDdepth() { - return ddepth; - } - - int Sobel::getBt() { - return bt; - } - - void Sobel::setXord(int other) { - xord = other; - } - - void Sobel::setYord(int other) { - yord = other; - } - - void Sobel::setKsize(int other) { - ksize = other; - } - - void Sobel::setScale(double other) { - scale = other; - } - - void Sobel::setDelta(double other) { - delta = other = other; - } - - void Sobel::setDdepth(int other) { - ddepth = other; - } - - void Sobel::setBt(int other) { - bt = other; - } - - /*##################################*/ - /*###CANNY FILTER IMPLEMENTATION####*/ - /*##################################*/ - - Canny::Canny(int low_threshold, int ratio_, int kernel_size_) { - low_threshold = low_threshold; - ratio = ratio_; - kernel_size = kernel_size_; - } - - void Canny::operator()(cv::Mat& src, cv::Mat &dst) const { - cv::Canny(src, dst, low_threshold, low_threshold * ratio, kernel_size); - } - - int Canny::getLowThreshold() { - return low_threshold; - } - - int Canny::getRatio() { - return ratio; - } - - int Canny::getKernelSize() { - return kernel_size; - } - - void Canny::setLowThreshold(int other) { - low_threshold = other; - } - - void Canny::setRatio(int other) { - ratio = other; - } - - void Canny::setKernelSize(int other) { - kernel_size = other; - } - - - /*##################################*/ - /*####BLUR FILTER IMPLEMENTATION####*/ - /*##################################*/ - - Blur::Blur(int sigma) { - this->sigma = sigma; - } - - void Blur::operator()(cv::Mat& src, cv::Mat &dst) const { - cv::blur(src, dst, cv::Size(sigma, sigma)); - } - - int Blur::getSigma() { - return sigma; - } - - void Blur::setSigma(int other) { - sigma = other; - } - - /*##################################*/ - /*##GRAYSCALE FILTER IMPLEMENTATION#*/ - /*##################################*/ - - GrayScale::GrayScale() {} - - void GrayScale::operator()(cv::Mat& src, cv::Mat &dst) const { - cvtColor(src, dst, CV_BGR2GRAY); - } -} diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt deleted file mode 100755 index 2b2da22..0000000 --- a/src/gui/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# Find the QtWidgets library -find_package(Qt5Widgets REQUIRED) -find_package(Qt5Core REQUIRED) - -set(CMAKE_AUTOMOC ON) - -set(GUI_SOURCES - uxinar.cpp - ../../include/core.h - ../core/core.cpp - ../../include/filters.h - ../filters/filters.cpp - ../../include/interface.h - ../interface/interface.cpp - ../../include/io.h - ../utils/io.cpp - ../../include/matrixwrapper.h - ../utils/matrixwrapper.cpp - #../utils/radix.cpp - ../utils/singleton.cpp - ../utils/ui_components.cpp - ) - -# Use the Widgets module from Qt 5. -add_executable(uxinar ${GUI_SOURCES}) -target_link_libraries(uxinar ${OpenCV_LIBS} - #IMVIEWER - #INTERFACE_LIB - #IO_LIB - #CORE_LIB - #FILTERS_LIB - Qt5::Widgets - Qt5::Core) diff --git a/src/gui/uxinar.cpp b/src/gui/uxinar.cpp deleted file mode 100755 index 26386cb..0000000 --- a/src/gui/uxinar.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -#include "imageviewer.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - QGuiApplication::setApplicationDisplayName(ImageViewer::tr("Image Viewer")); - QCommandLineParser commandLineParser; - commandLineParser.addHelpOption(); - commandLineParser.addPositionalArgument(ImageViewer::tr("[file]"), ImageViewer::tr("Image file to open.")); - commandLineParser.process(QCoreApplication::arguments()); - ImageViewer imageViewer; - if (!commandLineParser.positionalArguments().isEmpty() - && !imageViewer.loadFile(commandLineParser.positionalArguments().front())) { - return -1; - } - imageViewer.show(); - return app.exec(); -} \ No newline at end of file diff --git a/src/interface/CMakeLists.txt b/src/interface/CMakeLists.txt deleted file mode 100755 index 4e98b04..0000000 --- a/src/interface/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -set(INTERFACE_SOURCE interface.cpp ../../include/interface.h) -#add_library(INTERFACE_LIB SHARED ${INTERFACE_SOURCE}) \ No newline at end of file diff --git a/src/interface/interface.cpp b/src/interface/interface.cpp deleted file mode 100755 index 6bcec67..0000000 --- a/src/interface/interface.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// Created by nikita on 06.07.17. -// - -#include "interface.h" -#include "io.h" -#include "filters.h" -#include "core.h" - -namespace interface { - filter::Compose build_filters() { - filter::GrayScale *gs = new filter::GrayScale(); - filter::Blur *blur = new filter::Blur(/*sigma = */ 3); - filter::Canny *canny = new filter::Canny(/*low_threshold = */ 30, /*ratio = */ 3, /*kernel_size = */ 3); - filter::Sobel *sbl = new filter::Sobel(0, 0, 3, 1, 0, CV_16S, cv::BORDER_DEFAULT); - std::vector filters = {gs, blur, canny}; - filter::Compose compose(filters); - return compose; - } - - bool - Resize::is_init() const { - return vseams.size() != 0; - } - - Resize::Resize() { - filter = build_filters(); - } - - void - Resize::init(cv::Mat&& in) { - for (auto seam : vseams) delete seam; - image = core::MatWrp(in); - core::MatWrp energy(in); - filter(in, energy); - vseams = core::get_seams(energy); - hseams = core::get_seams(energy); - } - - Resize::~Resize() {} - - void - Resize::process(cv::Mat& result, cv::Size new_size) { - cv::Size in_size = image.mat.size(); - core::MatWrp in_wrp(image.clone()); - - core::resize_with_seams(in_wrp, in_size.width - new_size.width, vseams); - in_wrp.transpose(); -// core::resize_with_filter(in_wrp, in_size.height - new_size.height, filter); - core::resize_with_seams(in_wrp, in_size.height - new_size.height, hseams); - result = in_wrp.mat; - } - - - void process_image(io::Input in, io::Output out, cv::Size size, bool show_images) { - cv::Mat input_matrix = in.read_image(); - cv::Mat output_matrix = in.read_image(); - - auto filter = build_filters(); - - core::resize_to_fit(input_matrix, output_matrix, size, filter); - - out.write_image(output_matrix); - } - -} diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt deleted file mode 100755 index 8c03091..0000000 --- a/src/utils/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -find_package(Qt5Widgets REQUIRED) -find_package(Qt5Core REQUIRED) - -set(CMAKE_AUTOMOC ON) -set(UTILS_SOURCE radix.cpp ../../include/io.h io.cpp singleton.cpp ui_components.cpp) - -#add_library(SINGLETON_TEMPLATE SHARED radix.cpp) -#add_library(IO_LIB SHARED io.cpp ../../include/io.h) -#add_library(UTILS_LIB SHARED singleton.cpp) -#add_library(IMVIEWER SHARED ui_components.cpp) - -#target_link_libraries(IMVIEWER Qt5::Widgets -# Qt5::Core) \ No newline at end of file diff --git a/src/utils/io.cpp b/src/utils/io.cpp deleted file mode 100755 index 7c1bc92..0000000 --- a/src/utils/io.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// -// Created by nikita on 06.07.17. -// - -#include "io.h" -#include -#include - -namespace io { - // IO class implementation - IO::IO() {} - - IO::IO(std::string path_) : path(path_) {} - - - //Input class implementation - Input::Input(std::string path_) : IO(path_) {} - - Input::Input() {} - - cv::Mat Input::read_image() { - cv::Mat mat = cv::imread(path); - return mat; - } - - std::string Input::get_path() { - return path; - } - - //Output class implementation - Output::Output(std::string path_) : IO(path_) {} - - Output::Output() {} - - void Output::write_image(cv::Mat &mat) { - auto time = std::chrono::system_clock::now(); - cv::imwrite(path, mat); - } - - std::string Output::get_path() { - return path; - } - - Input bind_input(const std::string &path) { - return Input(path); - } - - Output bind_output(const std::string &path) { - return Output(path); - } -} diff --git a/src/utils/matrixwrapper.cpp b/src/utils/matrixwrapper.cpp deleted file mode 100755 index 8a6c30a..0000000 --- a/src/utils/matrixwrapper.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// -// Created by nikita on 15.07.17. -// -#include "matrixwrapper.h" - -namespace core { - MatWrp::MatWrp() { - this->mat = cv::Mat(); - this->transposed = false; - } - - MatWrp::MatWrp(const MatWrp &other) { - this->mat = other.mat; - this->transposed = other.transposed; - } - - MatWrp::MatWrp(const cv::Mat &other) { - this->mat = other; - this->transposed = false; - } - - MatWrp::MatWrp(int h, int w, int type = CV_64F) { - this->mat.create(h, w, type); - this->transposed = false; - } - - MatWrp - MatWrp::clone() const { - MatWrp cl((this->mat).clone()); - cl.transposed = this->transposed; - return cl; - } - - const - int MatWrp::width() const { - return ((this->transposed) ? this->mat.rows : - this->mat.cols); - } - - const - int MatWrp::height() const { - return ((this->transposed) ? this->mat.cols : - this->mat.rows); - } - - bool - MatWrp::is_transposed() const { - return transposed; - } - - void - MatWrp::transpose() { - this->transposed ^= 1; - } - - void - MatWrp::set_shape(const MatWrp &other) { - this->mat.create(other.mat.rows, other.mat.cols, CV_64F); - this->transposed = other.transposed; - } - - void - MatWrp::set_shape(const MatWrp &other, int type) { - this->mat.create(other.mat.rows, other.mat.cols, type); - this->transposed = other.transposed; - } - - void - MatWrp::set_orientation(const MatWrp &other) { - this->transposed = other.transposed; - } - - MatWrp - MatWrp::operator()(cv::Range rowRange, cv::Range colRange) const { - if (this->transposed) { - std::swap(rowRange, colRange); - } - MatWrp copy((this->mat)(rowRange, colRange)); - if (this->transposed) { - copy.transpose(); - } - return copy; - } - - MatWrp & - MatWrp::operator=(const MatWrp &other) { - this->mat = other.mat; - this->transposed = other.transposed; - return *this; - } -} \ No newline at end of file diff --git a/src/utils/radix.cpp b/src/utils/radix.cpp deleted file mode 100755 index 6260d42..0000000 --- a/src/utils/radix.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// Created by nikita on 18.07.17. -// - -#include -#include - -#include "utils.h" - -namespace utils { - -} \ No newline at end of file diff --git a/src/utils/singleton.cpp b/src/utils/singleton.cpp deleted file mode 100755 index 8afa5a6..0000000 --- a/src/utils/singleton.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// -// Created by nikita on 05.07.17. -// -/* -#include "singleton.h" - -template -T &Singleton::Instance() { - static T instance; - return instance; -} - - -*/ diff --git a/src/utils/ui_components.cpp b/src/utils/ui_components.cpp deleted file mode 100755 index 32ecbf8..0000000 --- a/src/utils/ui_components.cpp +++ /dev/null @@ -1,221 +0,0 @@ - -#include -#include -#include "resizable_label.h" -#include "imageviewer.h" - - -QImage Mat2QImage(cv::Mat const& src) { - auto temp = src; - QImage dest((const uchar *) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888); - dest.bits(); // enforce deep copy, see documentation - // of QImage::QImage ( const uchar * data, int width, int height, Format format ) - return dest; -} - -cv::Mat QImage2Mat(QImage const& src) { - cv::Mat tmp(src.height(),src.width(), CV_8UC3,(uchar*)src.bits(),src.bytesPerLine()); - cv::Mat result; // deep copy just in case (my lack of knowledge with open cv) - cvtColor(tmp, result, CV_RGB2BGR); - cvtColor(result, result, CV_BGR2RGB); - return result; -} - -ResizableQLabel::ResizableQLabel() {} - -void -ResizableQLabel::resizeEvent(QResizeEvent* event){ - if (!resizer.is_init()) { - return; - } - const QSize ns = event->size(); - cv::Mat out; - resizer.process(out, cv::Size(ns.width(), ns.height())); - QPixmap pmp = QPixmap::fromImage(Mat2QImage(out)); - QLabel::setPixmap(pmp); - QLabel::resizeEvent(event); -} - -void -ResizableQLabel::setPixmap(const QPixmap &pixmap) { - this->resizer.init(QImage2Mat(pixmap.toImage().convertToFormat(QImage::Format_RGB888))); - QLabel::setPixmap(pixmap); -} - - -ImageViewer::ImageViewer() - : imageLabel(new ResizableQLabel) -{ - imageLabel->setBackgroundRole(QPalette::Base); - imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - imageLabel->setScaledContents(false); - setCentralWidget(imageLabel); - - createActions(); - resize(QGuiApplication::primaryScreen()->availableSize() / 3); -} - - -bool ImageViewer::loadFile(const QString &fileName) -{ - QImageReader reader(fileName); - reader.setAutoTransform(true); - const QImage newImage = reader.read(); - if (newImage.isNull()) { - QMessageBox::information(this, QGuiApplication::applicationDisplayName(), - tr("Cannot load %1: %2") - .arg(QDir::toNativeSeparators(fileName), reader.errorString())); - return false; - } - - setImage(newImage); - setWindowFilePath(fileName); - - const QString message = tr("Opened \"%1\", %2x%3, Depth: %4") - .arg(QDir::toNativeSeparators(fileName)).arg(image.width()).arg(image.height()).arg(image.depth()); - statusBar()->showMessage(message); - return true; -} - -void ImageViewer::setImage(const QImage &newImage) -{ - image = newImage; - this->resize(QSize(newImage.width(), newImage.height() + this->menuBar()->height() + this->statusBar()->height())); - imageLabel->setPixmap(QPixmap::fromImage(image)); - updateActions(); -} - - -bool ImageViewer::saveFile(const QString &fileName) -{ - QImageWriter writer(fileName); - - if (!writer.write(image)) { - QMessageBox::information(this, QGuiApplication::applicationDisplayName(), - tr("Cannot write %1: %2") - .arg(QDir::toNativeSeparators(fileName)), writer.errorString()); - return false; - } - const QString message = tr("Wrote \"%1\"").arg(QDir::toNativeSeparators(fileName)); - statusBar()->showMessage(message); - return true; -} - - -static void initializeImageFileDialog(QFileDialog &dialog, QFileDialog::AcceptMode acceptMode) -{ - static bool firstDialog = true; - - if (firstDialog) { - firstDialog = false; - const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); - dialog.setDirectory(picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.last()); - } - - QStringList mimeTypeFilters; - const QByteArrayList supportedMimeTypes = acceptMode == QFileDialog::AcceptOpen - ? QImageReader::supportedMimeTypes() : QImageWriter::supportedMimeTypes(); - foreach (const QByteArray &mimeTypeName, supportedMimeTypes) - mimeTypeFilters.append(mimeTypeName); - mimeTypeFilters.sort(); - dialog.setMimeTypeFilters(mimeTypeFilters); - dialog.selectMimeTypeFilter("image/jpeg"); - if (acceptMode == QFileDialog::AcceptSave) - dialog.setDefaultSuffix("jpg"); -} - -void ImageViewer::open() -{ - QFileDialog dialog(this, tr("Open File")); - initializeImageFileDialog(dialog, QFileDialog::AcceptOpen); - - while (dialog.exec() == QDialog::Accepted && !loadFile(dialog.selectedFiles().first())) {} -} - -void ImageViewer::saveAs() -{ - QFileDialog dialog(this, tr("Save File As")); - initializeImageFileDialog(dialog, QFileDialog::AcceptSave); - - while (dialog.exec() == QDialog::Accepted && !saveFile(dialog.selectedFiles().first())) {} -} - -void ImageViewer::copy() -{ -#ifndef QT_NO_CLIPBOARD - QGuiApplication::clipboard()->setImage(image); -#endif // !QT_NO_CLIPBOARD -} - -#ifndef QT_NO_CLIPBOARD -static QImage clipboardImage() -{ - if (const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData()) { - if (mimeData->hasImage()) { - const QImage image = qvariant_cast(mimeData->imageData()); - if (!image.isNull()) - return image; - } - } - return QImage(); -} -#endif // !QT_NO_CLIPBOARD - -void ImageViewer::paste() -{ -#ifndef QT_NO_CLIPBOARD - const QImage newImage = clipboardImage(); - if (newImage.isNull()) { - statusBar()->showMessage(tr("No image in clipboard")); - } else { - setImage(newImage); - setWindowFilePath(QString()); - const QString message = tr("Obtained image from clipboard, %1x%2, Depth: %3") - .arg(newImage.width()).arg(newImage.height()).arg(newImage.depth()); - statusBar()->showMessage(message); - } -#endif // !QT_NO_CLIPBOARD -} - -void ImageViewer::about() -{ - QMessageBox::about(this, tr("About UXinar"), - tr("

The UXinar is an implementation of realtime Content Aware Resize algorithm. " - "It has a huge variety of setting to deal with.

")); -} - -void ImageViewer::createActions() -{ - QMenu *fileMenu = menuBar()->addMenu(tr("&File")); - - QAction *openAct = fileMenu->addAction(tr("&Open..."), this, &ImageViewer::open); - openAct->setShortcut(QKeySequence::Open); - - saveAsAct = fileMenu->addAction(tr("&Save As..."), this, &ImageViewer::saveAs); - saveAsAct->setEnabled(false); - - fileMenu->addSeparator(); - - QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close); - exitAct->setShortcut(tr("Ctrl+Q")); - - QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); - - copyAct = editMenu->addAction(tr("&Copy"), this, &ImageViewer::copy); - copyAct->setShortcut(QKeySequence::Copy); - copyAct->setEnabled(false); - - QAction *pasteAct = editMenu->addAction(tr("&Paste"), this, &ImageViewer::paste); - pasteAct->setShortcut(QKeySequence::Paste); - - QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); - - helpMenu->addAction(tr("&About"), this, &ImageViewer::about); - helpMenu->addAction(tr("About &Qt"), &QApplication::aboutQt); -} - -void ImageViewer::updateActions() -{ - saveAsAct->setEnabled(!image.isNull()); - copyAct->setEnabled(!image.isNull()); -} diff --git a/tests/test_core b/tests/test_core deleted file mode 100755 index 3657abc..0000000 Binary files a/tests/test_core and /dev/null differ