Add mode 3: color negative. Convert image into CMY channels, invert them and then tint them as red, green and blue channels to target specific channels on color print stock
This commit is contained in:
parent
ca7d02a3a5
commit
38ec44ce79
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
29
src/main.cpp
29
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<string> image(parser, "image", "Image to manipulate");
|
||||
args::ValueFlag<int> mode(parser, "mode", "The mode flag (default: 0) 0=RGB,1=IRGB,2=Invert", {'m'});
|
||||
args::ValueFlag<int> mode(parser, "mode", "The mode flag (default: 0) 0=RGB,1=IRGB,2=Invert,3=ColorNeg", {'m'});
|
||||
args::ValueFlag<string> red(parser, "red", "Path of red channel file to write", {'r'});
|
||||
args::ValueFlag<string> green(parser, "green", "Path of green channel file to write", {'g'});
|
||||
args::ValueFlag<string> blue(parser, "blue", "Path of blue channel file to write", {'b'});
|
||||
args::ValueFlag<string> inverted(parser, "inverted", "Path of inverted image file to write", {'i'});
|
||||
|
||||
try
|
||||
{
|
||||
parser.ParseCLI(argc, argv);
|
||||
|
|
|
|||
Loading…
Reference in New Issue