ImageTournament/main.cpp
Carl Philipp Klemm 0812c3cb97 inital commit
2023-01-17 14:01:49 +01:00

140 lines
3.6 KiB
C++

#include <iostream>
#include <filesystem>
#include <opencv2/highgui.hpp>
static constexpr char OUTPUT_DIR[] = "./out";
static bool extensionMatches(const std::filesystem::path& path)
{
std::string extension = path.extension();
if(extension == ".png")
return true;
if(extension == ".PNG")
return true;
if(extension == ".jpg")
return true;
if(extension == ".JPG")
return true;
if(extension == ".jpeg")
return true;
return false;
}
int main(int argc, char** argv)
{
if(argc < 2)
{
std::cout<<"a directory must be specified\n";
return 1;
}
std::cout<<"Using folder "<<argv[1]<<'\n';
std::vector<std::filesystem::path> images;
const std::filesystem::path directoryPath{argv[1]};
for(const std::filesystem::directory_entry& dirent : std::filesystem::directory_iterator{directoryPath})
{
std::string fileName = dirent.path().filename();
if(dirent.is_regular_file() && extensionMatches(dirent.path()))
{
std::cout<<"Found: "<<dirent.path().filename()<<'\n';
images.push_back(dirent.path());
}
}
if(images.empty())
{
std::cout<<"No images found\n";
return 1;
}
std::filesystem::path outDirPath(OUTPUT_DIR);
if(!std::filesystem::is_directory(outDirPath) && !std::filesystem::create_directory(outDirPath))
{
std::cout<<"Could not create or read "<<OUTPUT_DIR<<'\n';
return 1;
}
cv::namedWindow("Viewer", cv::WINDOW_NORMAL);
cv::setWindowTitle("Viewer", "Choose");
std::vector<std::vector<std::filesystem::path>> rounds;
while(images.size() > 1)
{
std::cout<<"New round "<<images.size()<<" images remaining\n";
rounds.push_back(std::vector<std::filesystem::path>());
std::vector<size_t> removeIndexies;
for(size_t i = 0; i < images.size()-1; i+=2)
{
cv::Mat imageA = cv::imread(images[i]);
cv::Mat imageB = cv::imread(images[i+1]);
if(!imageA.data || !imageB.data)
{
std::cout<<"Images: "<<images[i]<<' '<<images[i+1]<<" failed to read";
return 1;
}
cv::Size2i outSize(imageA.cols+imageB.cols, std::max(imageA.rows, imageB.rows));
cv::Mat image = cv::Mat::zeros(outSize, imageA.type());
cv::Rect roiA(cv::Point(0, 0), imageA.size());
cv::Rect roiB(cv::Point(imageA.cols, 0), imageB.size());
imageA.copyTo(image(roiA));
imageB.copyTo(image(roiB));
cv::imshow("Viewer", image);
while(true)
{
int keycode = cv::waitKey(0);
if(keycode == 49)
{
removeIndexies.push_back(i+1);
break;
}
else if(keycode == 50)
{
removeIndexies.push_back(i);
break;
}
}
}
for(ssize_t i = removeIndexies.size()-1; i >= 0; --i)
{
rounds.back().push_back(images[removeIndexies[i]]);
images.erase(images.begin()+removeIndexies[i]);
}
}
for(size_t round = 0; round < rounds.size(); ++round)
{
std::string roundDirName = std::string("round_") + std::to_string(round);
if(!std::filesystem::is_directory(outDirPath/roundDirName) && !std::filesystem::create_directory(outDirPath/roundDirName))
{
std::cout<<"Could not create or read "<<outDirPath/roundDirName<<'\n';
return 1;
}
for(const std::filesystem::path& path : rounds[round])
{
std::cout<<"Saveing "<<path<<std::endl; //flush
std::error_code ec;
std::filesystem::create_hard_link(path, outDirPath/roundDirName/(path.filename()), ec);
if(ec.value() != 0)
{
std::cout<<"Could not create hard link for "<<outDirPath/roundDirName/path.filename()<<'\n';
}
}
}
std::error_code ec;
std::filesystem::path winnerPath(outDirPath/(std::string("winner_") + std::string(images[0].filename())));
std::filesystem::create_hard_link(images[0], winnerPath, ec);
if(ec.value() != 0)
{
std::cout<<"Could not create hard link for "<<winnerPath<<'\n';
}
return 0;
}