diff --git a/include/FilmoutImage.hpp b/include/FilmoutImage.hpp index bc00b9c..508d2c9 100644 --- a/include/FilmoutImage.hpp +++ b/include/FilmoutImage.hpp @@ -24,6 +24,9 @@ class FilmoutImage { Mat red; Mat green; Mat blue; + Mat cyan; + Mat magenta; + Mat yellow; Mat inverted; Mat combineChannel(Mat& data, Mat& empty, uint8_t i); String getExtLower (const string& path); @@ -31,6 +34,7 @@ class FilmoutImage { public: void loadChannels(const string& path, bool invert); + void loadColorNegative(const string& path); void writeChannels(const string& red_path, const string& green_path, const string& blue_path); void invertMode(const string& path, const string& inverted_path); void releaseChannels(); diff --git a/src/FilmoutImage.cpp b/src/FilmoutImage.cpp index 8571f1b..9be5cce 100644 --- a/src/FilmoutImage.cpp +++ b/src/FilmoutImage.cpp @@ -17,18 +17,14 @@ void FilmoutImage::loadChannels (const string& path, bool invert) { empty = Mat::zeros(Size(loaded.cols, loaded.rows), CV_8UC1); single = Mat::zeros(Size(loaded.cols, loaded.rows), CV_8UC1); sub_channels = { empty, empty, empty }; - //red = Mat::zeros(Size(loaded.cols, loaded.rows), CV_8UC3); - //green = Mat::zeros(Size(loaded.cols, loaded.rows), CV_8UC3); - //blue = Mat::zeros(Size(loaded.cols, loaded.rows), CV_8UC3); - - //cout << "{ \"empty\" : \"true\" }" << endl; split(loaded, channels); + //cout << "{ \"split\" : \"true\" }" << endl; if (invert) { - bitwise_not(channels[0], single); + bitwise_not(channels[2], single); } else { - single = channels[0]; + single = channels[2]; } combined = combineChannel(single, empty, 0); combined.copyTo(red); @@ -47,9 +43,9 @@ void FilmoutImage::loadChannels (const string& path, bool invert) { //cout << "{ \"green\" : \"true\" }" << endl; if (invert) { - bitwise_not(channels[2], single); + bitwise_not(channels[0], single); } else { - single = channels[2]; + single = channels[0]; } combined = combineChannel(single, empty, 2); @@ -84,6 +80,90 @@ void FilmoutImage::loadChannels (const string& path, bool invert) { } } +// red = cyan inverted +// green = magenta inverted +// blue = yellow inverted + +void FilmoutImage::loadColorNegative (const string& path) { + string located_path = samples::findFile(path); + string ext = getExtLower(located_path); + + if (ext == "dpx") { + //NOT WORKING + cout << "{ \"dpx\" : \"" << path << "\" }" << endl; + } else { + loaded = imread(located_path, IMREAD_COLOR); + //cout << "{ \"loaded\" : \"" << located_path << "\" }" << endl; + } + + if (loaded.empty()) { + cerr << "{ \"error\" : \"" << path << " empty\" }" << endl; + } else { + //bitwise_not(loaded, inverted); + + empty = Mat::zeros(Size(loaded.cols, loaded.rows), CV_8UC1); + single = Mat::zeros(Size(loaded.cols, loaded.rows), CV_8UC1); + sub_channels = { empty, empty, empty }; + + split(loaded, channels); + + blue = channels[0]; + green = channels[1]; + red = channels[2]; + + add(blue, green, single); + combined = combineChannel(single, empty, 2); + combined.copyTo(cyan); + cout << "{ \"cyan\" : \"true\" }" << endl; + + add(blue, red, single); + combined = combineChannel(single, empty, 1); + combined.copyTo(magenta); + cout << "{ \"magenta\" : \"true\" }" << endl; + + add(green, red, single); + combined = combineChannel(single, empty, 0); + combined.copyTo(yellow); + cout << "{ \"yellow\" : \"true\" }" << endl; + + bitwise_not(cyan, red); + bitwise_not(magenta, green); + bitwise_not(yellow, blue); + + +#if (CV_VERSION_MAJOR >= 4) + cvtColor(red, red, cv::COLOR_BGR2RGB); + cvtColor(green, green, cv::COLOR_BGR2RGB); + cvtColor(blue, blue, cv::COLOR_BGR2RGB); +#else + cvtColor(red, red, CV_BGR2RGB); + cvtColor(green, green, CV_BGR2RGB); + cvtColor(blue, blue, CV_BGR2RGB); +#endif + + cout << "{ \"converted\" : \"true\" }" << endl; + //UPDATE TO RGB channel loading message + //cout << "{ \"loaded\" : \"" << path << "\", "; + //cout << "\"original\" : { \"w\" : " << loaded.cols << ", \"h\" : " << loaded.rows << " }"; + //cout << "}" << endl; + + loaded.release(); + inverted.release(); + empty.release(); + combined.release(); + single.release(); + + cyan.release(); + magenta.release(); + yellow.release(); + + for (uint8_t i = 0; i < 3; i++) { + channels[i].release(); + sub_channels[i].release(); + } + } +} + Mat FilmoutImage::combineChannel(Mat& data, Mat& empty, uint8_t i) { //BGR sub_channels[0] = i == 0 ? data : empty; diff --git a/src/main.cpp b/src/main.cpp index 4790a9f..6dfbf71 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,6 +41,28 @@ int rgbMode (const string& path, string red, string green, string blue, bool inv return 0; } +// red = cyan inverted +// green = magenta inverted +// blue = yellow inverted +int colorNegativeMode (const string& path, string red, string green, string blue) { + fi.loadColorNegative(path); + + if (red.compare("") == 0) { + red = generatePath(path, "red"); + } + if (green.compare("") == 0) { + green = generatePath(path, "green"); + } + if (blue.compare("") == 0) { + blue = generatePath(path, "blue"); + } + + fi.writeChannels(red, green, blue); + fi.releaseChannels(); + + return 0; +} + int invertMode (const string& path, string inverted) { if (inverted.compare("") == 0) { inverted = generatePath(path, "inverted"); @@ -63,6 +85,8 @@ int processImage (string path, int mode, string red, string green, string blue, return rgbMode(path, red, green, blue, true); case 2 : return invertMode(path, inverted); + case 3 : + return colorNegativeMode(path, red, green, blue); break; default : cerr << "{\"error\" : \"Nothing to process\" }" << endl; @@ -75,14 +99,15 @@ int main (int argc, char** argv) { args::ArgumentParser parser("filmout_image", "Manipulates images for filmout"); - args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"});; + args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); args::Positional image(parser, "image", "Image to manipulate"); - args::ValueFlag mode(parser, "mode", "The mode flag (default: 0) 0=RGB,1=IRGB,2=Invert", {'m'}); + args::ValueFlag mode(parser, "mode", "The mode flag (default: 0) 0=RGB,1=IRGB,2=Invert,3=ColorNeg", {'m'}); args::ValueFlag red(parser, "red", "Path of red channel file to write", {'r'}); args::ValueFlag green(parser, "green", "Path of green channel file to write", {'g'}); args::ValueFlag blue(parser, "blue", "Path of blue channel file to write", {'b'}); args::ValueFlag inverted(parser, "inverted", "Path of inverted image file to write", {'i'}); + try { parser.ParseCLI(argc, argv);