Handle flat field images with different black levels than raw image
For bayer images handle flat field images with different black levels than the raw image.
This commit is contained in:
parent
7751019b6e
commit
2aea26b5f3
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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]];
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user