Per ridurre il rumore, come si fa in astrofotografia, un sistema semplice per fare stacking
g++ stack_images.cpp -o stack_images `pkg-config --cflags --libs opencv4` -std=c++17
stack_images.cpp
#include <opencv2/opencv.hpp>
#include <filesystem>
#include <vector>
#include <iostream>
namespace fs = std::filesystem;
int main() {
std::string folder = "images"; // Folder containing your PNGs
std::vector<cv::Mat> images;
// Load all PNGs from folder
for (const auto& entry : fs::directory_iterator(folder)) {
if (entry.path().extension() == ".png") {
cv::Mat img = cv::imread(entry.path().string(), cv::IMREAD_UNCHANGED);
if (!img.empty()) {
images.push_back(img);
std::cout << "Loaded: " << entry.path() << std::endl;
}
}
}
if (images.empty()) {
std::cerr << "No images loaded!" << std::endl;
return 1;
}
// Use first image size/type as reference
cv::Size imgSize = images[0].size();
int imgType = images[0].type();
// Convert all to CV_32F or CV_32FCn for precision
cv::Mat accumulator = cv::Mat::zeros(imgSize, CV_MAKETYPE(CV_32F, images[0].channels()));
for (const auto& img : images) {
cv::Mat imgFloat;
img.convertTo(imgFloat, CV_32F);
accumulator += imgFloat;
}
// Compute average
accumulator /= static_cast<float>(images.size());
// Convert back to original depth
cv::Mat result;
accumulator.convertTo(result, images[0].type());
// Save result
cv::imwrite("stacked_avg.png", result);
std::cout << "Saved stacked image as stacked_avg.png" << std::endl;
cv::Mat claheResult;
if (result.channels() == 3) {
// Convert to Lab color space
cv::Mat lab;
cv::cvtColor(result, lab, cv::COLOR_BGR2Lab);
std::vector<cv::Mat> lab_planes;
cv::split(lab, lab_planes);
// CLAHE on L channel
cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE();
clahe->setClipLimit(2.0);
clahe->apply(lab_planes[0], lab_planes[0]);
// Merge and convert back
cv::merge(lab_planes, lab);
cv::cvtColor(lab, claheResult, cv::COLOR_Lab2BGR);
} else {
// Grayscale CLAHE
cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE();
clahe->setClipLimit(2.0);
clahe->apply(result, claheResult);
}
cv::imwrite("stacked_avg_clahe.png", claheResult);
return 0;
}
Nessun commento:
Posta un commento