Skip to content

Commit

Permalink
Merge pull request #122 from CarVac/testbuild
Browse files Browse the repository at this point in the history
Testbuild
  • Loading branch information
CarVac authored Nov 21, 2020
2 parents 3fa7f70 + 2ea656c commit a544d2d
Show file tree
Hide file tree
Showing 23 changed files with 1,581 additions and 209 deletions.
213 changes: 130 additions & 83 deletions filmulator-gui/core/imagePipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,18 @@ matrix<unsigned short>& ImagePipeline::processImage(ParameterManager * paramMana
std::string camName = demosaicParam.cameraName.toStdString();
const lfCamera * camera = NULL;
const lfCamera ** cameraList = ldb->FindCamerasExt(NULL,camName.c_str());

//Set up stuff for rotation.
//We expect rotation to be from -45 to +45
//But -50 will be the signal from the UI to disable it.
float rotationAngle = demosaicParam.rotationAngle * 3.1415926535/180;//convert degrees to radians
if (demosaicParam.rotationAngle <= -49) {
rotationAngle = 0;
}
cout << "cos rotationangle: " << cos(rotationAngle) << endl;
cout << "sin rotationangle: " << sin(rotationAngle) << endl;
bool lensfunGeometryCorrectionApplied = false;

if (cameraList)
{
const float cropFactor = cameraList[0]->CropFactor;
Expand Down Expand Up @@ -776,12 +788,18 @@ matrix<unsigned short>& ImagePipeline::processImage(ParameterManager * paramMana
matrix<float> new_image;
new_image.set_size(height, width*3);

if (demosaicParam.lensfunCA && demosaicParam.lensfunDistortion)
if (demosaicParam.lensfunCA || demosaicParam.lensfunDistortion)
{
//ApplySubpixelGeometryDistortion
lensfunGeometryCorrectionApplied = true;
bool success = true;
int listWidth = width * 2 * 3;
#pragma omp parallel for

//Check how far out of bounds we go
float maxOvershootDistance = 1.0f;
float semiwidth = (width-1)/2.0f;
float semiheight = (height-1)/2.0f;
#pragma omp parallel for reduction(max:maxOvershootDistance)
for (int row = 0; row < height; row++)
{
float positionList[listWidth];
Expand All @@ -793,104 +811,65 @@ matrix<unsigned short>& ImagePipeline::processImage(ParameterManager * paramMana
int listIndex = col * 2 * 3; //list index
for (int c = 0; c < 3; c++)
{
float coordX = positionList[listIndex+2*c];
float coordY = positionList[listIndex+2*c+1];
int sX = max(0, min(width-1, int(floor(coordX))))*3 + c;//startX
int eX = max(0, min(width-1, int(ceil(coordX))))*3 + c; //endX
int sY = max(0, min(height-1, int(floor(coordY)))); //startY
int eY = max(0, min(height-1, int(ceil(coordY)))); //endY
float notUsed;
float eWX = modf(coordX, &notUsed); //end weight X
float eWY = modf(coordY, &notUsed); //end weight Y;
float sWX = 1 - eWX; //start weight X
float sWY = 1 - eWY; //start weight Y;
new_image(row, col*3 + c) = recovered_image(sY, sX) * sWY * sWX +
recovered_image(eY, sX) * eWY * sWX +
recovered_image(sY, eX) * sWY * eWX +
recovered_image(eY, eX) * eWY * eWX;
}
}
}
}
recovered_image = std::move(new_image);
} else {
if (demosaicParam.lensfunCA)
{
cout << "apply lensfun ca" << endl;
//ApplySubpixelDistortion
bool success = true;
int listWidth = width * 2 * 3;
#pragma omp parallel for
for (int row = 0; row < height; row++)
{
float positionList[listWidth];
success = mod->ApplySubpixelDistortion(0.0f, row, width, 1, positionList);
if (success)
{
for (int col = 0; col < width; col++)
{
int listIndex = col * 2 * 3; //list index
for (int c = 0; c < 3; c++)
float coordX = positionList[listIndex+2*c] - semiwidth;
float coordY = positionList[listIndex+2*c+1] - semiheight;
float rotatedX = coordX * cos(rotationAngle) - coordY * sin(rotationAngle);
float rotatedY = coordX * sin(rotationAngle) + coordY * cos(rotationAngle);

float overshoot = 1.0f;

if (abs(rotatedX) > semiwidth)
{
overshoot = max(abs(rotatedX)/semiwidth,overshoot);
}
if (abs(rotatedY) > semiheight)
{
overshoot = max(abs(rotatedY)/semiheight,overshoot);
}

if (overshoot > maxOvershootDistance)
{
float coordX = positionList[listIndex+2*c];
float coordY = positionList[listIndex+2*c+1];
int sX = max(0, min(width-1, int(floor(coordX))))*3 + c;//startX
int eX = max(0, min(width-1, int(ceil(coordX))))*3 + c; //endX
int sY = max(0, min(height-1, int(floor(coordY)))); //startY
int eY = max(0, min(height-1, int(ceil(coordY)))); //endY
float notUsed;
float eWX = modf(coordX, &notUsed); //end weight X
float eWY = modf(coordY, &notUsed); //end weight Y;
float sWX = 1 - eWX; //start weight X
float sWY = 1 - eWY; //start weight Y;
new_image(row, col*3 + c) = recovered_image(sY, sX) * sWY * sWX +
recovered_image(eY, sX) * eWY * sWX +
recovered_image(sY, eX) * sWY * eWX +
recovered_image(eY, eX) * eWY * eWX;
maxOvershootDistance = overshoot;
}
}
}
}
recovered_image = std::move(new_image);
}
if (demosaicParam.lensfunDistortion)

#pragma omp parallel for
for (int row = 0; row < height; row++)
{
//ApplyGeometryDistortion
bool success = true;
int listWidth = width * 2;
#pragma omp parallel for
for (int row = 0; row < height; row++)
float positionList[listWidth];
success = mod->ApplySubpixelGeometryDistortion(0.0f, row, width, 1, positionList);
if (success)
{
float positionList[listWidth];
success = mod->ApplyGeometryDistortion(0.0f, row, width, 1, positionList);
if (success)
for (int col = 0; col < width; col++)
{
for (int col = 0; col < width; col++)
int listIndex = col * 2 * 3; //list index
for (int c = 0; c < 3; c++)
{
int listIndex = col * 2; //list index
float coordX = positionList[listIndex];
float coordY = positionList[listIndex+1];
int sX = max(0, min(width-1, int(floor(coordX))))*3;//startX
int eX = max(0, min(width-1, int(ceil(coordX))))*3; //endX
int sY = max(0, min(height-1, int(floor(coordY)))); //startY
int eY = max(0, min(height-1, int(ceil(coordY)))); //endY
float coordX = positionList[listIndex+2*c] - semiwidth;
float coordY = positionList[listIndex+2*c+1] - semiheight;
float rotatedX = (coordX * cos(rotationAngle) - coordY * sin(rotationAngle)) / maxOvershootDistance + semiwidth;
float rotatedY = (coordX * sin(rotationAngle) + coordY * cos(rotationAngle)) / maxOvershootDistance + semiheight;
int sX = max(0, min(width-1, int(floor(rotatedX))))*3 + c;//startX
int eX = max(0, min(width-1, int(ceil(rotatedX))))*3 + c; //endX
int sY = max(0, min(height-1, int(floor(rotatedY)))); //startY
int eY = max(0, min(height-1, int(ceil(rotatedY)))); //endY
float notUsed;
float eWX = modf(coordX, &notUsed); //end weight X
float eWY = modf(coordY, &notUsed); //end weight Y;
float eWX = modf(rotatedX, &notUsed); //end weight X
float eWY = modf(rotatedY, &notUsed); //end weight Y;
float sWX = 1 - eWX; //start weight X
float sWY = 1 - eWY; //start weight Y;
for (int c = 0; c < 3; c++)
{
new_image(row, col*3 + c) = recovered_image(sY, sX + c) * sWY * sWX +
recovered_image(eY, sX + c) * eWY * sWX +
recovered_image(sY, eX + c) * sWY * eWX +
recovered_image(eY, eX + c) * eWY * eWX;
}
new_image(row, col*3 + c) = recovered_image(sY, sX) * sWY * sWX +
recovered_image(eY, sX) * eWY * sWX +
recovered_image(sY, eX) * sWY * eWX +
recovered_image(eY, eX) * eWY * eWX;
}
}
}
recovered_image = std::move(new_image);
}
recovered_image = std::move(new_image);
}

if (mod != NULL)
Expand All @@ -908,6 +887,74 @@ matrix<unsigned short>& ImagePipeline::processImage(ParameterManager * paramMana
lf_db_destroy(ldb);
}

if (!lensfunGeometryCorrectionApplied)
{
//also do rotations on non-corrected images
float maxOvershootDistance = 1.0f;
float semiwidth = (width-1)/2.0f;
float semiheight = (height-1)/2.0f;

//check the four corners
for (int row = 0; row < height; row += height-1)
{
for (int col = 0; col < width; col += width-1)
{
float coordX = col - semiwidth;
float coordY = row - semiheight;
float rotatedX = coordX * cos(rotationAngle) - coordY * sin(rotationAngle);
float rotatedY = coordX * sin(rotationAngle) + coordY * cos(rotationAngle);

float overshoot = 1.0f;

if (abs(rotatedX) > semiwidth)
{
overshoot = max(abs(rotatedX)/semiwidth,overshoot);
}
if (abs(rotatedY) > semiheight)
{
overshoot = max(abs(rotatedY)/semiheight,overshoot);
}

if (overshoot > maxOvershootDistance)
{
maxOvershootDistance = overshoot;
}
}
}

//Apply the rotation
matrix<float> new_image;
new_image.set_size(height, width*3);

for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
float coordX = col - semiwidth;
float coordY = row - semiheight;
float rotatedX = (coordX * cos(rotationAngle) - coordY * sin(rotationAngle)) / maxOvershootDistance + semiwidth;
float rotatedY = (coordX * sin(rotationAngle) + coordY * cos(rotationAngle)) / maxOvershootDistance + semiheight;
int sX = max(0, min(width-1, int(floor(rotatedX))))*3;//startX
int eX = max(0, min(width-1, int(ceil(rotatedX))))*3; //endX
int sY = max(0, min(height-1, int(floor(rotatedY)))); //startY
int eY = max(0, min(height-1, int(ceil(rotatedY)))); //endY
float notUsed;
float eWX = modf(rotatedX, &notUsed); //end weight X
float eWY = modf(rotatedY, &notUsed); //end weight Y;
float sWX = 1 - eWX; //start weight X
float sWY = 1 - eWY; //start weight Y;
for (int c = 0; c < 3; c++)
{
new_image(row, col*3 + c) = recovered_image(sY, sX + c) * sWY * sWX +
recovered_image(eY, sX + c) * eWY * sWX +
recovered_image(sY, eX + c) * sWY * eWX +
recovered_image(eY, eX + c) * eWY * eWX;
}
}
}
recovered_image = std::move(new_image);
}

valid = paramManager->markDemosaicComplete();
updateProgress(valid, 0.0f);
[[fallthrough]];
Expand Down
Loading

0 comments on commit a544d2d

Please sign in to comment.