eahd demosaic: convert rgb to Lab using Color::RGB2Lab() instead of duplicating code, #4727

This commit is contained in:
heckflosse
2018-08-18 16:15:32 +02:00
parent 9fb9aaeec2
commit d4894ef948
4 changed files with 20 additions and 101 deletions

View File

@@ -19,6 +19,7 @@
*/
#include <cmath>
#include "color.h"
#include "rawimagesource.h"
#include "rawimagesource_i.h"
#include "jaggedarray.h"
@@ -35,54 +36,6 @@ using namespace std;
namespace rtengine
{
inline void RawImageSource::convert_to_cielab_row (const LUTf &cache, const float* ar, const float* ag, const float* ab, float* oL, float* oa, float* ob)
{
int j = 0;
#ifdef __SSE2__
vfloat lc00v = F2V(lc00);
vfloat lc01v = F2V(lc01);
vfloat lc02v = F2V(lc02);
vfloat lc10v = F2V(lc10);
vfloat lc11v = F2V(lc11);
vfloat lc12v = F2V(lc12);
vfloat lc20v = F2V(lc20);
vfloat lc21v = F2V(lc21);
vfloat lc22v = F2V(lc22);
vfloat c116v = F2V(116.f);
vfloat c200v = F2V(200.f);
vfloat c500v = F2V(500.f);
for (; j < W - 3; j += 4) {
vfloat r = LVFU(ar[j]);
vfloat g = LVFU(ag[j]);
vfloat b = LVFU(ab[j]);
vfloat x = lc00v * r + lc01v * g + lc02v * b;
vfloat y = lc10v * r + lc11v * g + lc12v * b;
vfloat z = lc20v * r + lc21v * g + lc22v * b;
vfloat cy = cache[y];
STVFU(oL[j], c116v * cy);
STVFU(oa[j], c500v * (cache[x] - cy));
STVFU(ob[j], c200v * (cy - cache[z]));
}
#endif
for (; j < W; j++) {
float r = ar[j];
float g = ag[j];
float b = ab[j];
float x = lc00 * r + lc01 * g + lc02 * b;
float y = lc10 * r + lc11 * g + lc12 * b;
float z = lc20 * r + lc21 * g + lc22 * b;
float cy = cache[y];
oL[j] = 116.f * cy;
oa[j] = 500.f * (cache[x] - cy);
ob[j] = 200.f * (cy - cache[z]);
}
}
inline void RawImageSource::interpolate_row_g (float* agh, float* agv, int i)
{
@@ -267,31 +220,21 @@ void RawImageSource::eahd_demosaic ()
plistener->setProgress (0.0);
}
// prepare cache and constants for cielab conversion
// prepare constants for cielab conversion
//TODO: revisit after conversion to D50 illuminant
lc00 = (0.412453 * imatrices.rgb_cam[0][0] + 0.357580 * imatrices.rgb_cam[0][1] + 0.180423 * imatrices.rgb_cam[0][2]) ;// / 0.950456;
lc01 = (0.412453 * imatrices.rgb_cam[1][0] + 0.357580 * imatrices.rgb_cam[1][1] + 0.180423 * imatrices.rgb_cam[1][2]) ;// / 0.950456;
lc02 = (0.412453 * imatrices.rgb_cam[2][0] + 0.357580 * imatrices.rgb_cam[2][1] + 0.180423 * imatrices.rgb_cam[2][2]) ;// / 0.950456;
const float lc00 = (0.412453 * imatrices.rgb_cam[0][0] + 0.357580 * imatrices.rgb_cam[0][1] + 0.180423 * imatrices.rgb_cam[0][2]) ;// / 0.950456;
const float lc01 = (0.412453 * imatrices.rgb_cam[1][0] + 0.357580 * imatrices.rgb_cam[1][1] + 0.180423 * imatrices.rgb_cam[1][2]) ;// / 0.950456;
const float lc02 = (0.412453 * imatrices.rgb_cam[2][0] + 0.357580 * imatrices.rgb_cam[2][1] + 0.180423 * imatrices.rgb_cam[2][2]) ;// / 0.950456;
lc10 = 0.212671 * imatrices.rgb_cam[0][0] + 0.715160 * imatrices.rgb_cam[0][1] + 0.072169 * imatrices.rgb_cam[0][2];
lc11 = 0.212671 * imatrices.rgb_cam[1][0] + 0.715160 * imatrices.rgb_cam[1][1] + 0.072169 * imatrices.rgb_cam[1][2];
lc12 = 0.212671 * imatrices.rgb_cam[2][0] + 0.715160 * imatrices.rgb_cam[2][1] + 0.072169 * imatrices.rgb_cam[2][2];
const float lc10 = 0.212671 * imatrices.rgb_cam[0][0] + 0.715160 * imatrices.rgb_cam[0][1] + 0.072169 * imatrices.rgb_cam[0][2];
const float lc11 = 0.212671 * imatrices.rgb_cam[1][0] + 0.715160 * imatrices.rgb_cam[1][1] + 0.072169 * imatrices.rgb_cam[1][2];
const float lc12 = 0.212671 * imatrices.rgb_cam[2][0] + 0.715160 * imatrices.rgb_cam[2][1] + 0.072169 * imatrices.rgb_cam[2][2];
lc20 = (0.019334 * imatrices.rgb_cam[0][0] + 0.119193 * imatrices.rgb_cam[0][1] + 0.950227 * imatrices.rgb_cam[0][2]) ;// / 1.088754;
lc21 = (0.019334 * imatrices.rgb_cam[1][0] + 0.119193 * imatrices.rgb_cam[1][1] + 0.950227 * imatrices.rgb_cam[1][2]) ;// / 1.088754;
lc22 = (0.019334 * imatrices.rgb_cam[2][0] + 0.119193 * imatrices.rgb_cam[2][1] + 0.950227 * imatrices.rgb_cam[2][2]) ;// / 1.088754;
const float lc20 = (0.019334 * imatrices.rgb_cam[0][0] + 0.119193 * imatrices.rgb_cam[0][1] + 0.950227 * imatrices.rgb_cam[0][2]) ;// / 1.088754;
const float lc21 = (0.019334 * imatrices.rgb_cam[1][0] + 0.119193 * imatrices.rgb_cam[1][1] + 0.950227 * imatrices.rgb_cam[1][2]) ;// / 1.088754;
const float lc22 = (0.019334 * imatrices.rgb_cam[2][0] + 0.119193 * imatrices.rgb_cam[2][1] + 0.950227 * imatrices.rgb_cam[2][2]) ;// / 1.088754;
int maxindex = 65536; //2*65536 3 = avoid crash 3/2013 J.Desmis
LUTf cache(65536);
threshold = 0.008856 * MAXVALD;
for (int i = 0; i < maxindex; i++) {
if(i <= threshold)
cache[i] = (7.787f / MAXVALF) * i + 16.f / 116.f;
else
cache[i] = std::cbrt(double(i) / MAXVALD);
}
const float wp[3][3] = {{lc00, lc01, lc02}, {lc10, lc11, lc12}, {lc20, lc21, lc22}};
// end of cielab preparation
@@ -311,10 +254,10 @@ void RawImageSource::eahd_demosaic ()
interpolate_row_rb (rh[1], bh[1], gh[0], gh[1], gh[2], 1);
interpolate_row_rb (rv[1], bv[1], gv[0], gv[1], gv[2], 1);
convert_to_cielab_row (cache, rh[0], gh[0], bh[0], lLh[0], lah[0], lbh[0]);
convert_to_cielab_row (cache, rv[0], gv[0], bv[0], lLv[0], lav[0], lbv[0]);
convert_to_cielab_row (cache, rh[1], gh[1], bh[1], lLh[1], lah[1], lbh[1]);
convert_to_cielab_row (cache, rv[1], gv[1], bv[1], lLv[1], lav[1], lbv[1]);
Color::RGB2Lab(rh[0], gh[0], bh[0], lLh[0], lah[0], lbh[0], wp, W);
Color::RGB2Lab(rv[0], gv[0], bv[0], lLv[0], lav[0], lbv[0], wp, W);
Color::RGB2Lab(rh[1], gh[1], bh[1], lLh[1], lah[1], lbh[1], wp, W);
Color::RGB2Lab(rv[1], gv[1], bv[1], lLv[1], lav[1], lbv[1], wp, W);
for (int j = 0; j < W; j++) {
homh[0][j] = 0;
@@ -345,8 +288,8 @@ void RawImageSource::eahd_demosaic ()
interpolate_row_rb (rv[(i + 1) % 3], bv[(i + 1) % 3], gv[i % 4], gv[(i + 1) % 4], nullptr, i + 1);
}
convert_to_cielab_row (cache, rh[(i + 1) % 3], gh[(i + 1) % 4], bh[(i + 1) % 3], lLh[(i + 1) % 3], lah[(i + 1) % 3], lbh[(i + 1) % 3]);
convert_to_cielab_row (cache, rv[(i + 1) % 3], gv[(i + 1) % 4], bv[(i + 1) % 3], lLv[(i + 1) % 3], lav[(i + 1) % 3], lbv[(i + 1) % 3]);
Color::RGB2Lab(rh[(i + 1) % 3], gh[(i + 1) % 4], bh[(i + 1) % 3], lLh[(i + 1) % 3], lah[(i + 1) % 3], lbh[(i + 1) % 3], wp, W);
Color::RGB2Lab(rv[(i + 1) % 3], gv[(i + 1) % 4], bv[(i + 1) % 3], lLv[(i + 1) % 3], lav[(i + 1) % 3], lbv[(i + 1) % 3], wp, W);
for (int j = 0; j < W; j++) {
homh[ipx][j] = 0;