Merge pull request #6991 from sgotti/flat_field_different_black_levels

Handle flat field images with different black levels than raw image
This commit is contained in:
Lawrence37 2024-03-24 12:04:35 -07:00 committed by GitHub
commit 8b783d8008
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 10 deletions

View File

@ -145,6 +145,7 @@ void ffInfo::updateRawImage()
int H = ri->get_height();
int W = ri->get_width();
ri->compress_image(0);
ri->set_prefilters();
int rSize = W * ((ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1) ? 1 : 3);
acc_t **acc = new acc_t*[H];
@ -165,6 +166,7 @@ void ffInfo::updateRawImage()
if( !temp->loadRaw(true)) {
temp->compress_image(0); //\ TODO would be better working on original, because is temporary
temp->set_prefilters();
nFiles++;
if( ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1 ) {
@ -204,6 +206,7 @@ void ffInfo::updateRawImage()
ri = nullptr;
} else {
ri->compress_image(0);
ri->set_prefilters();
}
}

View File

@ -263,13 +263,21 @@ void cfaboxblur(const float* const * riFlatFile, float* cfablur, int boxH, int b
namespace rtengine
{
void RawImageSource::processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, array2D<float> &rawData, const float black[4])
void RawImageSource::processFlatField(const procparams::RAWParams &raw, RawImage *riFlatFile, array2D<float> &rawData, const float black[4])
{
// BENCHFUN
std::unique_ptr<float[]> cfablur(new float[H * W]);
const int BS = raw.ff_BlurRadius + (raw.ff_BlurRadius & 1);
std::array<float, 4> ffblack;
{
const auto tmpfilters = riFlatFile->get_filters();
riFlatFile->set_filters(riFlatFile->prefilters); // we need 4 blacks for bayer processing
riFlatFile->get_colorsCoeff(nullptr, nullptr, ffblack.data(), false);
riFlatFile->set_filters(tmpfilters);
}
if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::V)) {
cfaboxblur(riFlatFile->data, cfablur.get(), 2 * BS, 0, H, W);
} else if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::H)) {
@ -291,7 +299,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
const int col = 2 * (W >> 2) + n;
const int c = ri->get_colors() != 1 ? FC(row, col) : 0;
const int c4 = ri->get_colors() != 1 ? ((c == 1 && !(row & 1)) ? 3 : c) : 0;
refcolor[m][n] = std::max(0.0f, cfablur[row * W + col] - black[c4]);
refcolor[m][n] = std::max(0.0f, cfablur[row * W + col] - ffblack[c4]);
}
float limitFactor = 1.f;
@ -314,7 +322,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
clippedBefore = true;
break;
}
const float tempval = (rawVal - black[c4]) * (refcolor[m][n] / std::max(1e-5f, cfablur[(row + m) * W + col + n] - black[c4]));
const float tempval = (rawVal - black[c4]) * (refcolor[m][n] / std::max(1e-5f, cfablur[(row + m) * W + col + n] - ffblack[c4]));
maxval = std::max(maxval, tempval);
}
}
@ -363,6 +371,9 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
const vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]),
_mm_set_ps(black[c4[1][1]], black[c4[1][0]], black[c4[1][1]], black[c4[1][0]])
};
const vfloat ffblackv[2] = {_mm_set_ps(ffblack[c4[0][1]], ffblack[c4[0][0]], ffblack[c4[0][1]], ffblack[c4[0][0]]),
_mm_set_ps(ffblack[c4[1][1]], ffblack[c4[1][0]], ffblack[c4[1][1]], ffblack[c4[1][0]])
};
const vfloat onev = F2V(1.f);
const vfloat minValuev = F2V(minValue);
@ -375,10 +386,11 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
int col = 0;
#ifdef __SSE2__
const vfloat rowBlackv = blackv[row & 1];
const vfloat ffrowBlackv = ffblackv[row & 1];
const vfloat rowRefcolorv = refcolorv[row & 1];
for (; col < W - 3; col += 4) {
const vfloat blurv = LVFU(cfablur[row * W + col]) - rowBlackv;
const vfloat blurv = LVFU(cfablur[row * W + col]) - ffrowBlackv;
vfloat vignettecorrv = rowRefcolorv / blurv;
vignettecorrv = vself(vmaskf_le(blurv, minValuev), onev, vignettecorrv);
const vfloat valv = LVFU(rawData[row][col]) - rowBlackv;
@ -388,7 +400,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
#endif
for (; col < W; ++col) {
const float blur = cfablur[row * W + col] - black[c4[row & 1][col & 1]];
const float blur = cfablur[row * W + col] - ffblack[c4[row & 1][col & 1]];
const float vignettecorr = blur <= minValue ? 1.f : refcolor[row & 1][col & 1] / blur;
rawData[row][col] = (rawData[row][col] - black[c4[row & 1][col & 1]]) * vignettecorr + black[c4[row & 1][col & 1]];
}
@ -490,6 +502,10 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
const vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]),
_mm_set_ps(black[c4[1][1]], black[c4[1][0]], black[c4[1][1]], black[c4[1][0]])
};
const vfloat ffblackv[2] = {_mm_set_ps(ffblack[c4[0][1]], ffblack[c4[0][0]], ffblack[c4[0][1]], ffblack[c4[0][0]]),
_mm_set_ps(ffblack[c4[1][1]], ffblack[c4[1][0]], ffblack[c4[1][1]], ffblack[c4[1][0]])
};
const vfloat epsv = F2V(1e-5f);
#endif
@ -501,10 +517,11 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
int col = 0;
#ifdef __SSE2__
const vfloat rowBlackv = blackv[row & 1];
const vfloat ffrowBlackv = ffblackv[row & 1];
for (; col < W - 3; col += 4) {
const vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - rowBlackv, epsv)) /
(vmaxf(LVFU(cfablur1[row * W + col]) - rowBlackv, epsv) * vmaxf(LVFU(cfablur2[row * W + col]) - rowBlackv, epsv));
const vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - ffrowBlackv, epsv)) /
(vmaxf(LVFU(cfablur1[row * W + col]) - ffrowBlackv, epsv) * vmaxf(LVFU(cfablur2[row * W + col]) - ffrowBlackv, epsv));
const vfloat valv = LVFU(rawData[row][col]) - rowBlackv;
STVFU(rawData[row][col], valv * linecorrv + rowBlackv);
}
@ -512,8 +529,8 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
#endif
for (; col < W; ++col) {
const float linecorr = SQR(std::max(1e-5f, cfablur[row * W + col] - black[c4[row & 1][col & 1]])) /
(std::max(1e-5f, cfablur1[row * W + col] - black[c4[row & 1][col & 1]]) * std::max(1e-5f, cfablur2[row * W + col] - black[c4[row & 1][col & 1]]));
const float linecorr = SQR(std::max(1e-5f, cfablur[row * W + col] - ffblack[c4[row & 1][col & 1]])) /
(std::max(1e-5f, cfablur1[row * W + col] - ffblack[c4[row & 1][col & 1]]) * std::max(1e-5f, cfablur2[row * W + col] - ffblack[c4[row & 1][col & 1]]));
rawData[row][col] = (rawData[row][col] - black[c4[row & 1][col & 1]]) * linecorr + black[c4[row & 1][col & 1]];
}
}

View File

@ -138,7 +138,7 @@ public:
return rgbSourceModified; // tracks whether cached rgb output of demosaic has been modified
}
void processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, array2D<float> &rawData, const float black[4]);
void processFlatField(const procparams::RAWParams &raw, RawImage *riFlatFile, array2D<float> &rawData, const float black[4]);
void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, const RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData );
void scaleColors (int winx, int winy, int winw, int winh, const procparams::RAWParams &raw, array2D<float> &rawData); // raw for cblack
void WBauto(bool extra, double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) override;