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 H = ri->get_height();
|
||||||
int W = ri->get_width();
|
int W = ri->get_width();
|
||||||
ri->compress_image(0);
|
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);
|
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];
|
acc_t **acc = new acc_t*[H];
|
||||||
|
|
||||||
@ -165,6 +166,7 @@ void ffInfo::updateRawImage()
|
|||||||
|
|
||||||
if( !temp->loadRaw(true)) {
|
if( !temp->loadRaw(true)) {
|
||||||
temp->compress_image(0); //\ TODO would be better working on original, because is temporary
|
temp->compress_image(0); //\ TODO would be better working on original, because is temporary
|
||||||
|
temp->set_prefilters();
|
||||||
nFiles++;
|
nFiles++;
|
||||||
|
|
||||||
if( ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1 ) {
|
if( ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1 ) {
|
||||||
@ -204,6 +206,7 @@ void ffInfo::updateRawImage()
|
|||||||
ri = nullptr;
|
ri = nullptr;
|
||||||
} else {
|
} else {
|
||||||
ri->compress_image(0);
|
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
|
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
|
// BENCHFUN
|
||||||
std::unique_ptr<float[]> cfablur(new float[H * W]);
|
std::unique_ptr<float[]> cfablur(new float[H * W]);
|
||||||
|
|
||||||
const int BS = raw.ff_BlurRadius + (raw.ff_BlurRadius & 1);
|
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)) {
|
if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::V)) {
|
||||||
cfaboxblur(riFlatFile->data, cfablur.get(), 2 * BS, 0, H, W);
|
cfaboxblur(riFlatFile->data, cfablur.get(), 2 * BS, 0, H, W);
|
||||||
} else if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::H)) {
|
} 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 col = 2 * (W >> 2) + n;
|
||||||
const int c = ri->get_colors() != 1 ? FC(row, col) : 0;
|
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;
|
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;
|
float limitFactor = 1.f;
|
||||||
@ -314,7 +322,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
|||||||
clippedBefore = true;
|
clippedBefore = true;
|
||||||
break;
|
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);
|
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]]),
|
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]])
|
_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 onev = F2V(1.f);
|
||||||
const vfloat minValuev = F2V(minValue);
|
const vfloat minValuev = F2V(minValue);
|
||||||
@ -375,10 +386,11 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
|||||||
int col = 0;
|
int col = 0;
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
const vfloat rowBlackv = blackv[row & 1];
|
const vfloat rowBlackv = blackv[row & 1];
|
||||||
|
const vfloat ffrowBlackv = ffblackv[row & 1];
|
||||||
const vfloat rowRefcolorv = refcolorv[row & 1];
|
const vfloat rowRefcolorv = refcolorv[row & 1];
|
||||||
|
|
||||||
for (; col < W - 3; col += 4) {
|
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;
|
vfloat vignettecorrv = rowRefcolorv / blurv;
|
||||||
vignettecorrv = vself(vmaskf_le(blurv, minValuev), onev, vignettecorrv);
|
vignettecorrv = vself(vmaskf_le(blurv, minValuev), onev, vignettecorrv);
|
||||||
const vfloat valv = LVFU(rawData[row][col]) - rowBlackv;
|
const vfloat valv = LVFU(rawData[row][col]) - rowBlackv;
|
||||||
@ -388,7 +400,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (; col < W; ++col) {
|
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;
|
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]];
|
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]]),
|
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]])
|
_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);
|
const vfloat epsv = F2V(1e-5f);
|
||||||
#endif
|
#endif
|
||||||
@ -501,10 +517,11 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
|||||||
int col = 0;
|
int col = 0;
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
const vfloat rowBlackv = blackv[row & 1];
|
const vfloat rowBlackv = blackv[row & 1];
|
||||||
|
const vfloat ffrowBlackv = ffblackv[row & 1];
|
||||||
|
|
||||||
for (; col < W - 3; col += 4) {
|
for (; col < W - 3; col += 4) {
|
||||||
const vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - rowBlackv, epsv)) /
|
const vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - ffrowBlackv, epsv)) /
|
||||||
(vmaxf(LVFU(cfablur1[row * W + col]) - rowBlackv, epsv) * vmaxf(LVFU(cfablur2[row * W + col]) - rowBlackv, 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;
|
const vfloat valv = LVFU(rawData[row][col]) - rowBlackv;
|
||||||
STVFU(rawData[row][col], valv * linecorrv + rowBlackv);
|
STVFU(rawData[row][col], valv * linecorrv + rowBlackv);
|
||||||
}
|
}
|
||||||
@ -512,8 +529,8 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (; col < W; ++col) {
|
for (; col < W; ++col) {
|
||||||
const float linecorr = SQR(std::max(1e-5f, cfablur[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] - black[c4[row & 1][col & 1]]) * std::max(1e-5f, cfablur2[row * W + col] - black[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]];
|
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
|
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 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 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;
|
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