Add flat field correction for monochrome raw files
This commit is contained in:
parent
9e05e18c8f
commit
84f46eaab6
@ -138,7 +138,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);
|
||||||
int rSize = W * ((ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS) ? 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];
|
||||||
|
|
||||||
for( int row = 0; row < H; row++) {
|
for( int row = 0; row < H; row++) {
|
||||||
@ -160,7 +160,7 @@ void ffInfo::updateRawImage()
|
|||||||
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
|
||||||
nFiles++;
|
nFiles++;
|
||||||
|
|
||||||
if( ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS ) {
|
if( ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1 ) {
|
||||||
for( int row = 0; row < H; row++) {
|
for( int row = 0; row < H; row++) {
|
||||||
for( int col = 0; col < W; col++) {
|
for( int col = 0; col < W; col++) {
|
||||||
acc[row][col] += temp->data[row][col];
|
acc[row][col] += temp->data[row][col];
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
// use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat*
|
// use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat*
|
||||||
virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hlp, const RAWParams &raw) = 0;
|
virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hlp, const RAWParams &raw) = 0;
|
||||||
virtual eSensorType getSensorType () const = 0;
|
virtual eSensorType getSensorType () const = 0;
|
||||||
|
virtual bool isMono () const = 0;
|
||||||
// true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource
|
// true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource
|
||||||
virtual bool isWBProviderReady () = 0;
|
virtual bool isWBProviderReady () = 0;
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
|
|||||||
// If high detail (=100%) is newly selected, do a demosaic update, since the last was just with FAST
|
// If high detail (=100%) is newly selected, do a demosaic update, since the last was just with FAST
|
||||||
|
|
||||||
if (imageTypeListener) {
|
if (imageTypeListener) {
|
||||||
imageTypeListener->imageTypeChanged (imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS);
|
imageTypeListener->imageTypeChanged (imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS, imgsrc->isMono());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (todo & M_RAW)
|
if ( (todo & M_RAW)
|
||||||
|
@ -2815,7 +2815,7 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
|||||||
cfaboxblur(riFlatFile, cfablur, BS, BS);
|
cfaboxblur(riFlatFile, cfablur, BS, BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ri->getSensorType() == ST_BAYER) {
|
if(ri->getSensorType() == ST_BAYER || ri->get_colors() == 1) {
|
||||||
float refcolor[2][2];
|
float refcolor[2][2];
|
||||||
|
|
||||||
//find centre average values by channel
|
//find centre average values by channel
|
||||||
@ -2823,8 +2823,8 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
|||||||
for (int n = 0; n < 2; n++) {
|
for (int n = 0; n < 2; n++) {
|
||||||
int row = 2 * (H >> 2) + m;
|
int row = 2 * (H >> 2) + m;
|
||||||
int col = 2 * (W >> 2) + n;
|
int col = 2 * (W >> 2) + n;
|
||||||
int c = FC(row, col);
|
int c = ri->get_colors() != 1 ? FC(row, col) : 0;
|
||||||
int c4 = ( c == 1 && !(row & 1) ) ? 3 : c;
|
int c4 = ri->get_colors() != 1 ? (( c == 1 && !(row & 1) ) ? 3 : c) : 0;
|
||||||
refcolor[m][n] = max(0.0f, cfablur[row * W + col] - black[c4]);
|
refcolor[m][n] = max(0.0f, cfablur[row * W + col] - black[c4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2836,8 +2836,8 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
|||||||
for (int m = 0; m < 2; m++)
|
for (int m = 0; m < 2; m++)
|
||||||
for (int n = 0; n < 2; n++) {
|
for (int n = 0; n < 2; n++) {
|
||||||
float maxval = 0.f;
|
float maxval = 0.f;
|
||||||
int c = FC(m, n);
|
int c = ri->get_colors() != 1 ? FC(m, n) : 0;
|
||||||
int c4 = ( c == 1 && !(m & 1) ) ? 3 : c;
|
int c4 = ri->get_colors() != 1 ? (( c == 1 && !(m & 1) ) ? 3 : c) : 0;
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
@ -2886,13 +2886,20 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
|||||||
refcolor[m][n] *= limitFactor;
|
refcolor[m][n] *= limitFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int c[2][2] {};
|
||||||
unsigned int c[2][2] = {{FC(0, 0), FC(0, 1)}, {FC(1, 0), FC(1, 1)}};
|
unsigned int c4[2][2] {};
|
||||||
unsigned int c4[2][2];
|
if(ri->get_colors() != 1) {
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
for(int j = 0; j < 2; ++j) {
|
||||||
|
c[i][j] = FC(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
c4[0][0] = ( c[0][0] == 1) ? 3 : c[0][0];
|
c4[0][0] = ( c[0][0] == 1) ? 3 : c[0][0];
|
||||||
c4[0][1] = ( c[0][1] == 1) ? 3 : c[0][1];
|
c4[0][1] = ( c[0][1] == 1) ? 3 : c[0][1];
|
||||||
c4[1][0] = c[1][0];
|
c4[1][0] = c[1][0];
|
||||||
c4[1][1] = c[1][1];
|
c4[1][1] = c[1][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
vfloat refcolorv[2] = {_mm_set_ps(refcolor[0][1], refcolor[0][0], refcolor[0][1], refcolor[0][0]),
|
vfloat refcolorv[2] = {_mm_set_ps(refcolor[0][1], refcolor[0][0], refcolor[0][1], refcolor[0][0]),
|
||||||
@ -3016,13 +3023,20 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
|||||||
cfaboxblur(riFlatFile, cfablur1, 0, 2 * BS); //now do horizontal blur
|
cfaboxblur(riFlatFile, cfablur1, 0, 2 * BS); //now do horizontal blur
|
||||||
cfaboxblur(riFlatFile, cfablur2, 2 * BS, 0); //now do vertical blur
|
cfaboxblur(riFlatFile, cfablur2, 2 * BS, 0); //now do vertical blur
|
||||||
|
|
||||||
if(ri->getSensorType() == ST_BAYER) {
|
if(ri->getSensorType() == ST_BAYER || ri->get_colors() == 1) {
|
||||||
unsigned int c[2][2] = {{FC(0, 0), FC(0, 1)}, {FC(1, 0), FC(1, 1)}};
|
unsigned int c[2][2] {};
|
||||||
unsigned int c4[2][2];
|
unsigned int c4[2][2] {};
|
||||||
|
if(ri->get_colors() != 1) {
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
for(int j = 0; j < 2; ++j) {
|
||||||
|
c[i][j] = FC(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
c4[0][0] = ( c[0][0] == 1) ? 3 : c[0][0];
|
c4[0][0] = ( c[0][0] == 1) ? 3 : c[0][0];
|
||||||
c4[0][1] = ( c[0][1] == 1) ? 3 : c[0][1];
|
c4[0][1] = ( c[0][1] == 1) ? 3 : c[0][1];
|
||||||
c4[1][0] = c[1][0];
|
c4[1][0] = c[1][0];
|
||||||
c4[1][1] = c[1][1];
|
c4[1][1] = c[1][1];
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]),
|
vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]),
|
||||||
@ -3140,6 +3154,9 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (riFlatFile && W == riFlatFile->get_width() && H == riFlatFile->get_height()) {
|
||||||
|
processFlatField(raw, riFlatFile, black);
|
||||||
|
} // flatfield
|
||||||
} else {
|
} else {
|
||||||
// No bayer pattern
|
// No bayer pattern
|
||||||
// TODO: Is there a flat field correction possible?
|
// TODO: Is there a flat field correction possible?
|
||||||
|
@ -145,6 +145,10 @@ public:
|
|||||||
{
|
{
|
||||||
return ri != nullptr ? ri->getSensorType() : ST_NONE;
|
return ri != nullptr ? ri->getSensorType() : ST_NONE;
|
||||||
}
|
}
|
||||||
|
bool isMono () const
|
||||||
|
{
|
||||||
|
return ri->get_colors() == 1;
|
||||||
|
}
|
||||||
ColorTemp getWB () const
|
ColorTemp getWB () const
|
||||||
{
|
{
|
||||||
return camera_wb;
|
return camera_wb;
|
||||||
|
@ -359,7 +359,7 @@ class ImageTypeListener
|
|||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
virtual ~ImageTypeListener() = default;
|
virtual ~ImageTypeListener() = default;
|
||||||
virtual void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans) = 0;
|
virtual void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool is_Mono = false) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WaveletListener
|
class WaveletListener
|
||||||
|
@ -52,6 +52,7 @@ public:
|
|||||||
ColorTemp getSpotWB (std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, int tran, double equal);
|
ColorTemp getSpotWB (std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, int tran, double equal);
|
||||||
|
|
||||||
eSensorType getSensorType() const {return ST_NONE;}
|
eSensorType getSensorType() const {return ST_NONE;}
|
||||||
|
bool isMono() const {return false;}
|
||||||
|
|
||||||
bool isWBProviderReady ()
|
bool isWBProviderReady ()
|
||||||
{
|
{
|
||||||
|
@ -261,7 +261,7 @@ ToolPanelCoordinator::~ToolPanelCoordinator ()
|
|||||||
delete toolBar;
|
delete toolBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans)
|
void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono)
|
||||||
{
|
{
|
||||||
if (isRaw) {
|
if (isRaw) {
|
||||||
if (isBayer) {
|
if (isBayer) {
|
||||||
@ -292,7 +292,20 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt
|
|||||||
};
|
};
|
||||||
idle_register.add(func, this);
|
idle_register.add(func, this);
|
||||||
}
|
}
|
||||||
else {
|
else if (isMono) {
|
||||||
|
const auto func = [](gpointer data) -> gboolean {
|
||||||
|
ToolPanelCoordinator* const self = static_cast<ToolPanelCoordinator*>(data);
|
||||||
|
|
||||||
|
self->rawPanelSW->set_sensitive (true);
|
||||||
|
self->sensorbayer->FoldableToolPanel::hide();
|
||||||
|
self->sensorxtrans->FoldableToolPanel::hide();
|
||||||
|
self->preprocess->FoldableToolPanel::hide();
|
||||||
|
self->flatfield->FoldableToolPanel::show();
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
};
|
||||||
|
idle_register.add(func, this);
|
||||||
|
} else {
|
||||||
const auto func = [](gpointer data) -> gboolean {
|
const auto func = [](gpointer data) -> gboolean {
|
||||||
ToolPanelCoordinator* const self = static_cast<ToolPanelCoordinator*>(data);
|
ToolPanelCoordinator* const self = static_cast<ToolPanelCoordinator*>(data);
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ public:
|
|||||||
// toolpanellistener interface
|
// toolpanellistener interface
|
||||||
void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr);
|
void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr);
|
||||||
|
|
||||||
void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans);
|
void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono = false);
|
||||||
// profilechangelistener interface
|
// profilechangelistener interface
|
||||||
void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited = nullptr);
|
void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited = nullptr);
|
||||||
void setDefaults (rtengine::procparams::ProcParams* defparams);
|
void setDefaults (rtengine::procparams::ProcParams* defparams);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user