diff --git a/src/Image.cpp b/src/Image.cpp index 4b1df64..838071b 100644 --- a/src/Image.cpp +++ b/src/Image.cpp @@ -44,16 +44,19 @@ void Image::buildImage(uint16_t * rawImage, const RawParameters & params) { size_t size = width*height; brightness = 0.0; max = 0; + min = params.black * 100; // some inital big value for (size_t y = 0, ry = params.topMargin; y < height; ++y, ++ry) { for (size_t x = 0, rx = params.leftMargin; x < width; ++x, ++rx) { uint16_t v = rawImage[ry*params.rawWidth + rx]; (*this)(x, y) = v; brightness += v; if (v > max) max = v; + if (v < min) min = v; } } brightness /= size; - response.setLinear(params.max == 0 ? 1.0 : 65535.0 / params.max); + // response.setLinear(params.max == 0 ? 1.0 : 65535.0 / params.max); + response.setLinear(1.0); subtractBlack(params); } @@ -165,9 +168,11 @@ void Image::computeResponseFunction(const Image & r) { int pos = y * width + x; double v = usePixels[pos]; double nv = rUsePixels[pos]; - if (v >= nv && v < satThreshold) { - numerator += v * r.response(nv); - denom += v * v; + if (v <= nv && nv < satThreshold) { + if ((nv - (double)r.min) / ((double)r.max - (double)r.min) > 0.1) { + numerator += v * r.response(nv); + denom += v * v; + } } } } diff --git a/src/Image.hpp b/src/Image.hpp index 0bc760b..f0f4ff5 100644 --- a/src/Image.hpp +++ b/src/Image.hpp @@ -104,7 +104,7 @@ private: QString filename; std::unique_ptr[]> scaled; - uint16_t satThreshold, max; + uint16_t satThreshold, max, min; double brightness; ResponseFunction response; double halfLightPercent; diff --git a/src/ImageIO.cpp b/src/ImageIO.cpp index a80ca51..3dbdfa3 100644 --- a/src/ImageIO.cpp +++ b/src/ImageIO.cpp @@ -183,7 +183,7 @@ void ImageIO::save(const SaveOptions & options, ProgressIndicator & progress) { params.width = stack.getWidth(); params.height = stack.getHeight(); params.adjustWhite(stack.getImage(stack.size() - 1)); - Array2D composedImage = stack.compose(params, options.featherRadius); + Array2D composedImage = stack.compose(params, options.featherRadius, options.bps); progress.advance(33, "Rendering preview"); QImage preview = renderPreview(composedImage, params, stack.getMaxExposure(), options.previewSize <= 1); diff --git a/src/ImageStack.cpp b/src/ImageStack.cpp index 6074321..5090f10 100644 --- a/src/ImageStack.cpp +++ b/src/ImageStack.cpp @@ -21,6 +21,7 @@ */ #include +#include #include "BoxBlur.hpp" #include "ImageStack.hpp" @@ -166,8 +167,8 @@ void ImageStack::crop() { void ImageStack::computeResponseFunctions() { Timer t("Compute response functions"); - for (int i = images.size() - 2; i >= 0; --i) { - images[i].computeResponseFunction(images[i + 1]); + for (int i = 1; i < images.size(); ++i) { + images[i].computeResponseFunction(images[i - 1]); } } @@ -394,7 +395,7 @@ static Array2D fattenMask(const Array2D & mask, int radius) { } #endif -Array2D ImageStack::compose(const RawParameters & params, int featherRadius) const { +Array2D ImageStack::compose(const RawParameters & params, int featherRadius, int bit_depth) const { int imageMax = images.size() - 1; BoxBlur map(fattenMask(mask, featherRadius)); measureTime("Blur", [&] () { @@ -459,7 +460,10 @@ Array2D ImageStack::compose(const RawParameters & params, int featherRadi dst.displace(params.leftMargin, params.topMargin); // Scale to params.max and recover the black levels - float mult = (params.max - params.maxBlack) / max; + int max_possible = std::pow(2.0, bit_depth); // almost always 65536 + int max_black = params.maxBlack * ((double)max_possible / (double)params.max); + float mult = (max_possible - max_black) / max; // scale dst to fit the bit depth space + #pragma omp parallel for for (size_t y = 0; y < params.rawHeight; ++y) { for (size_t x = 0; x < params.rawWidth; ++x) { diff --git a/src/ImageStack.hpp b/src/ImageStack.hpp index 87610da..a16c63a 100644 --- a/src/ImageStack.hpp +++ b/src/ImageStack.hpp @@ -48,7 +48,7 @@ public: void crop(); void computeResponseFunctions(); void generateMask(); - Array2D compose(const RawParameters & md, int featherRadius) const; + Array2D compose(const RawParameters & md, int featherRadius, int bit_depth) const; size_t size() const { return images.size(); }