lensmetadata: add abstract center radius helper class
Add a CenterRadiusMetadataLensCorrection helper class that will be implemented by vendor specific corrections based on center radius.
This commit is contained in:
parent
2b97de233f
commit
f64ad13363
@ -24,6 +24,114 @@
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
CenterRadiusMetadataLensCorrection::CenterRadiusMetadataLensCorrection(const FramesMetaData *meta) :
|
||||||
|
swap_xy(false)
|
||||||
|
{
|
||||||
|
metadata = Exiv2Metadata(meta->getFileName());
|
||||||
|
metadata.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CenterRadiusMetadataLensCorrection::initCorrections(int width, int height, const procparams::CoarseTransformParams &coarse, int rawRotationDeg)
|
||||||
|
{
|
||||||
|
if (rawRotationDeg >= 0) {
|
||||||
|
int rot = (coarse.rotate + rawRotationDeg) % 360;
|
||||||
|
swap_xy = (rot == 90 || rot == 270);
|
||||||
|
if (swap_xy) {
|
||||||
|
std::swap(width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w2 = width * 0.5f;
|
||||||
|
h2 = height * 0.5f;
|
||||||
|
rf = 1 / std::sqrt(SQR(w2) + SQR(h2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CenterRadiusMetadataLensCorrection::process(double &x, double &y, int cx, int cy, int channel, bool dist, bool ca) const
|
||||||
|
{
|
||||||
|
double xx = x + cx;
|
||||||
|
double yy = y + cy;
|
||||||
|
if (swap_xy) {
|
||||||
|
std::swap(xx, yy);
|
||||||
|
}
|
||||||
|
|
||||||
|
double xc = xx - w2;
|
||||||
|
double yc = yy - h2;
|
||||||
|
|
||||||
|
double rout = rf * std::sqrt(SQR(xc) + SQR(yc));
|
||||||
|
double cf = 1;
|
||||||
|
if (dist && ca) {
|
||||||
|
cf = distortionAndCACorrectionFactor(rout, channel);
|
||||||
|
} else if (dist) {
|
||||||
|
cf = distortionCorrectionFactor(rout);
|
||||||
|
} else if (ca) {
|
||||||
|
cf = caCorrectionFactor(rout, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
x = cf * xc + w2;
|
||||||
|
y = cf * yc + h2;
|
||||||
|
|
||||||
|
if (swap_xy) {
|
||||||
|
std::swap(x, y);
|
||||||
|
}
|
||||||
|
x -= cx;
|
||||||
|
y -= cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CenterRadiusMetadataLensCorrection::correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const
|
||||||
|
{
|
||||||
|
if (!hasDistortionCorrection() || !hasCACorrection()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(x, y, cx, cy, channel, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CenterRadiusMetadataLensCorrection::correctDistortion(double &x, double &y, int cx, int cy) const
|
||||||
|
{
|
||||||
|
if (!hasDistortionCorrection()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(x, y, cx, cy, 1, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CenterRadiusMetadataLensCorrection::correctCA(double &x, double &y, int cx, int cy, int channel) const
|
||||||
|
{
|
||||||
|
if (!hasCACorrection()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(x, y, cx, cy, channel, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CenterRadiusMetadataLensCorrection::processVignetteNChannels(int width, int height, float **rawData, int channels) const
|
||||||
|
{
|
||||||
|
if (!hasVignettingCorrection()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < height; ++y) {
|
||||||
|
for (int x = 0; x < width; ++x) {
|
||||||
|
double xc = x - w2;
|
||||||
|
double yc = y - h2;
|
||||||
|
double sf = vignettingCorrectionFactor(rf * std::sqrt(SQR(xc) + SQR(yc)));
|
||||||
|
for (int c = 0; c < channels; c++) {
|
||||||
|
rawData[y][x + c] *= sf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CenterRadiusMetadataLensCorrection::processVignette(int width, int height, float **rawData) const
|
||||||
|
{
|
||||||
|
return processVignetteNChannels(width, height, rawData, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CenterRadiusMetadataLensCorrection::processVignette3Channels(int width, int height, float **rawData) const
|
||||||
|
{
|
||||||
|
return processVignetteNChannels(width, height, rawData, 3);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<MetadataLensCorrection> MetadataLensCorrectionFinder::findCorrection(const FramesMetaData *meta)
|
std::unique_ptr<MetadataLensCorrection> MetadataLensCorrectionFinder::findCorrection(const FramesMetaData *meta)
|
||||||
{
|
{
|
||||||
static const std::unordered_set<std::string> makers = {};
|
static const std::unordered_set<std::string> makers = {};
|
||||||
|
@ -37,6 +37,48 @@ public:
|
|||||||
virtual void initCorrections(int width, int height, const procparams::CoarseTransformParams &coarse, int rawRotationDeg) = 0;
|
virtual void initCorrections(int width, int height, const procparams::CoarseTransformParams &coarse, int rawRotationDeg) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* CenterRadiusMetadataLensCorrection is an abstract class the extends MetadataLensCorrection to easily handle center radius based corrections */
|
||||||
|
class CenterRadiusMetadataLensCorrection : public MetadataLensCorrection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CenterRadiusMetadataLensCorrection(const FramesMetaData *meta);
|
||||||
|
|
||||||
|
void process(double &x, double &y, int cx, int cy, int channel, bool dist, bool ca) const;
|
||||||
|
|
||||||
|
void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const override;
|
||||||
|
void correctDistortion(double &x, double &y, int cx, int cy) const override;
|
||||||
|
void correctCA(double &x, double &y, int cx, int cy, int channel) const override;
|
||||||
|
void processVignette(int width, int height, float **rawData) const override;
|
||||||
|
void processVignette3Channels(int width, int height, float **rawData) const override;
|
||||||
|
|
||||||
|
void processVignetteNChannels(int width, int height, float **rawData, int channels) const;
|
||||||
|
void initCorrections(int width, int height, const procparams::CoarseTransformParams &coarse, int rawRotationDeg) override;
|
||||||
|
|
||||||
|
/* Implementers should implement the below methods */
|
||||||
|
virtual bool hasDistortionCorrection() const override = 0;
|
||||||
|
virtual bool hasCACorrection() const override = 0;
|
||||||
|
virtual bool hasVignettingCorrection() const override = 0;
|
||||||
|
|
||||||
|
/* These methods should return the distortion correction factor (cf) for the
|
||||||
|
* provided radius rout (radius of the output image (corrected)).
|
||||||
|
* So rin = rout * cf
|
||||||
|
* */
|
||||||
|
virtual double distortionCorrectionFactor(double rout) const = 0;
|
||||||
|
virtual double caCorrectionFactor(double rout, int channel) const = 0;
|
||||||
|
virtual double distortionAndCACorrectionFactor(double rout, int channel) const = 0;
|
||||||
|
|
||||||
|
/* This methods should return the vignetting correction factor (cf) for the
|
||||||
|
* provided radius */
|
||||||
|
virtual double vignettingCorrectionFactor(double r) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool swap_xy;
|
||||||
|
double w2;
|
||||||
|
double h2;
|
||||||
|
double rf;
|
||||||
|
Exiv2Metadata metadata;
|
||||||
|
};
|
||||||
|
|
||||||
/* MetadataLensCorrectionFinder tries to find and return MetadataLensCorrection for the provided metadata */
|
/* MetadataLensCorrectionFinder tries to find and return MetadataLensCorrection for the provided metadata */
|
||||||
class MetadataLensCorrectionFinder
|
class MetadataLensCorrectionFinder
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user