Filmout image generates different channels

This commit is contained in:
mattmcw 2026-01-01 00:29:02 -05:00
parent 714c65d5c4
commit d624f1ef97
4 changed files with 163 additions and 27 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
build
notes/env
*.DS_Store

View File

@ -20,15 +20,18 @@ class FilmoutImage {
Mat loaded;
Mat combined;
Mat empty;
Mat single;
Mat red;
Mat green;
Mat blue;
Mat combineChannel(Mat data, Mat empty, uint8_t i);
Mat combineChannel(Mat& data, Mat& empty, uint8_t i);
String getExtLower (const string& path);
void writeChannel(const string& path, Mat& channel);
public:
void loadChannels(string image_path);
void loadChannels(const string& path, bool invert);
void writeChannels(const string& red_path, const string& green_path, const string& blue_path);
void releaseChannels();
};
#endif

View File

@ -1,33 +1,61 @@
#include "FilmoutImage.hpp"
void FilmoutImage::loadChannels (string image_path) {
string located_path = samples::findFile(image_path);
void FilmoutImage::loadChannels (const string& path, bool invert) {
string located_path = samples::findFile(path);
string ext = getExtLower(located_path);
if (ext == "dpx") {
//NOT WORKING
cout << "{ \"dpx\" : \"" << image_path << "\" }" << endl;
cout << "{ \"dpx\" : \"" << path << "\" }" << endl;
} else {
loaded = imread(located_path, IMREAD_COLOR);
//cout << "{ \"loaded\" : \"" << located_path << "\" }" << endl;
}
if (loaded.empty()) {
cerr << "{ \"error\" : \"" << image_path << " empty\" }" << endl;
cerr << "{ \"error\" : \"" << path << " empty\" }" << endl;
} else {
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);
} else {
single = channels[0];
}
combined = combineChannel(single, empty, 0);
combined.copyTo(red);
//flip(red, red, 0);
//cout << "{ \"red\" : \"true\" }" << endl;
combined = combineChannel(blue, empty, 0);
combined.copyTo(red(Rect(0, 0, loaded.cols, loaded.rows)));
flip(red, red, 0);
if (invert) {
bitwise_not(channels[1], single);
} else {
single = channels[1];
}
combined = combineChannel(green, empty, 1);
combined.copyTo(green(Rect(0, 0, loaded.cols, loaded.rows)));
flip(green, green, 0);
combined = combineChannel(single, empty, 1);
combined.copyTo(green);
//flip(green, green, 0);
//cout << "{ \"green\" : \"true\" }" << endl;
combined = combineChannel(red, empty, 2);
combined.copyTo(red(Rect(0, 0, loaded.cols, loaded.rows)));
flip(red, red, 0);
if (invert) {
bitwise_not(channels[2], single);
} else {
single = channels[2];
}
combined = combineChannel(single, empty, 2);
combined.copyTo(blue);
//flip(blue, blue, 0);
//cout << "{ \"blue\" : \"true\" }" << endl;
#if (CV_VERSION_MAJOR >= 4)
cvtColor(red, red, cv::COLOR_BGR2RGB);
@ -38,22 +66,25 @@ void FilmoutImage::loadChannels (string image_path) {
cvtColor(green, green, CV_BGR2RGB);
cvtColor(blue, blue, CV_BGR2RGB);
#endif
//UPDATE TO RGB channel loading message
//cout << "{ \"loaded\" : \"" << path << "\", ";
//cout << "\"original\" : { \"w\" : " << loaded.cols << ", \"h\" : " << loaded.rows << " }";
//cout << "}" << endl;
loaded.release();
empty.release();
combined.release();
single.release();
for (uint8_t i = 0; i < 3; i++) {
channels[i].release();
sub_channels[i].release();
}
//UPDATE TO RGB channel loading message
cout << "{ \"loaded\" : \"" << image_path << "\", ";
cout << "\"original\" : { \"w\" : " << loaded.cols << ", \"h\" : " << loaded.rows << " }}" << endl;
}
}
Mat FilmoutImage::combineChannel(Mat data, Mat empty, uint8_t i) {
Mat FilmoutImage::combineChannel(Mat& data, Mat& empty, uint8_t i) {
//BGR
sub_channels[0] = i == 0 ? data : empty;
sub_channels[1] = i == 1 ? data : empty;
@ -64,6 +95,28 @@ Mat FilmoutImage::combineChannel(Mat data, Mat empty, uint8_t i) {
return combined;
}
void FilmoutImage::writeChannel (const string& path, Mat& channel) {
//cout << path << endl;
imwrite(path, channel);
}
void FilmoutImage::writeChannels (const string& red_path, const string& green_path, const string& blue_path) {
writeChannel(red_path, red);
writeChannel(green_path, green);
writeChannel(blue_path, blue);
cout << "{ \"red\" : \"" << red_path << "\",";
cout << " \"green\" : \"" << green_path << "\",";
cout << " \"blue\" : \"" << blue_path << "\"";
cout << "}" << endl;
}
void FilmoutImage::releaseChannels() {
red.release();
green.release();
blue.release();
}
string FilmoutImage::getExtLower (const string& path) {
size_t pos = path.find_last_of('.');
if (pos != string::npos) {

View File

@ -1,14 +1,78 @@
#include "FilmoutImage.hpp"
#include "args/args.hxx"
#include <iostream>
#include <filesystem>
#include <string>
using namespace std;
namespace fs = std::filesystem;
FilmoutImage fi;
fs::path replaceSuffixExtension (const fs::path& input_path, const string& suffix) {
fs::path new_path = input_path.parent_path();
new_path /= input_path.stem().string() + suffix;
return new_path;
}
string generatePath (const string& path, const string& channel) {
fs::path image_path = path;
string suffix = "_" + channel + ".tif";
fs::path result = replaceSuffixExtension(image_path, suffix);
return result.string();
}
int rgbMode (const string& path, string red, string green, string blue, bool invert) {
fi.loadChannels(path, invert);
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 processImage (string path, int mode, string red, string green, string blue) {
if (!fs::exists(path)) {
cerr << "{ \"error\" : \"File " << path << " does not exist.\" }" << endl;
return 3;
}
//cout << "Current value: " << static_cast<int>(mode) << endl;
switch (mode) {
case 0 :
return rgbMode(path, red, green, blue, false);
case 1 :
return rgbMode(path, red, green, blue, true);
break;
default :
cerr << "{\"error\" : \"Nothing to process\" }" << endl;
return 0;
}
return 4;
}
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::Positional<std::string> image(parser, "image", "Image to manipulate");
args::ValueFlag<std::string> mode(parser, "mode", "The mode flag (default: 0) 0=RGB,1=", {'i'});
args::Positional<string> image(parser, "image", "Image to manipulate");
args::ValueFlag<int> mode(parser, "mode", "The mode flag (default: 0) 0=RGB,1=", {'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'});
try
{
parser.ParseCLI(argc, argv);
@ -20,23 +84,38 @@ int main (int argc, char** argv) {
}
catch (args::ParseError e)
{
cerr << e.what() << std::endl;
cerr << e.what() << endl;
cerr << parser;
return 1;
}
catch (args::ValidationError e)
{
cerr << e.what() << std::endl;
cerr << e.what() << endl;
cerr << parser;
return 1;
}
if (image) {
cout << "{ \"image\" : " << args::get(image) << endl;
cout << "{ \"image\" : \"" << args::get(image) << "\" }" << endl;
} else {
cerr << "{ \"error\" : \"Argument required for image\" }" << endl;
return 1;
}
if (mode) {
cout << "{ \"mode\" : " << args::get(mode) << " }" << endl;
}
try {
return processImage(args::get(image),
mode ? args::get(mode) : 0,
red ? args::get(red) : "",
green ? args::get(green) : "",
blue ? args::get(blue) : "");
} catch (const exception &e) {
cerr << "Caught " << e.what() << endl;
return 2;
}
return 0;
}