You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.0 KiB
136 lines
4.0 KiB
/* ============================================================
|
|
*
|
|
* This file is a part of digiKam project
|
|
* http://www.digikam.org
|
|
*
|
|
* Date : 2005-05-25
|
|
* Description : lens distortion algorithm.
|
|
*
|
|
* Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
|
* Copyright (C) 2001-2003 by David Hodson <hodsond@acm.org>
|
|
*
|
|
* This program is free software; you can redistribute it
|
|
* and/or modify it under the terms of the GNU General
|
|
* Public License as published by the Free Software Foundation;
|
|
* either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* ============================================================ */
|
|
|
|
// C++ includes.
|
|
|
|
#include <cmath>
|
|
#include <cstdlib>
|
|
|
|
// Local includes.
|
|
|
|
#include "dimg.h"
|
|
#include "ddebug.h"
|
|
#include "pixelaccess.h"
|
|
#include "lensdistortion.h"
|
|
|
|
namespace DigikamLensDistortionImagesPlugin
|
|
{
|
|
|
|
LensDistortion::LensDistortion(Digikam::DImg *orgImage, TQObject *parent, double main,
|
|
double edge, double rescale, double brighten,
|
|
int center_x, int center_y)
|
|
: Digikam::DImgThreadedFilter(orgImage, parent, "LensDistortion")
|
|
{
|
|
m_main = main;
|
|
m_edge = edge;
|
|
m_rescale = rescale;
|
|
m_brighten = brighten;
|
|
m_centre_x = center_x;
|
|
m_centre_y = center_y;
|
|
|
|
initFilter();
|
|
}
|
|
|
|
void LensDistortion::filterImage(void)
|
|
{
|
|
int Width = m_orgImage.width();
|
|
int Height = m_orgImage.height();
|
|
int bytesDepth = m_orgImage.bytesDepth();
|
|
|
|
uchar *data = m_destImage.bits();
|
|
|
|
// initial copy
|
|
|
|
m_destImage.bitBltImage(&m_orgImage, 0, 0);
|
|
|
|
// initialize coefficients
|
|
|
|
double normallise_radius_sq = 4.0 / (Width * Width + Height * Height);
|
|
double center_x = Width * (100.0 + m_centre_x) / 200.0;
|
|
double center_y = Height * (100.0 + m_centre_y) / 200.0;
|
|
double mult_sq = m_main / 200.0;
|
|
double mult_qd = m_edge / 200.0;
|
|
double rescale = pow(2.0, - m_rescale / 100.0);
|
|
double brighten = - m_brighten / 10.0;
|
|
|
|
PixelAccess *pa = new PixelAccess(&m_orgImage);
|
|
|
|
/*
|
|
* start at image (i, j), increment by (step, step)
|
|
* output goes to dst, which is w x h x d in size
|
|
* NB: d <= image.bpp
|
|
*/
|
|
|
|
// We are working on the full image.
|
|
int dstWidth = Width;
|
|
int dstHeight = Height;
|
|
uchar* dst = (uchar*)data;
|
|
int step = 1, progress;
|
|
|
|
int iLimit, jLimit;
|
|
double srcX, srcY, mag;
|
|
|
|
iLimit = dstWidth * step;
|
|
jLimit = dstHeight * step;
|
|
|
|
for (int dstJ = 0 ; !m_cancel && (dstJ < jLimit) ; dstJ += step)
|
|
{
|
|
for (int dstI = 0 ; !m_cancel && (dstI < iLimit) ; dstI += step)
|
|
{
|
|
// Get source Coordinates.
|
|
double radius_sq;
|
|
double off_x;
|
|
double off_y;
|
|
double radius_mult;
|
|
|
|
off_x = dstI - center_x;
|
|
off_y = dstJ - center_y;
|
|
radius_sq = (off_x * off_x) + (off_y * off_y);
|
|
|
|
radius_sq *= normallise_radius_sq;
|
|
|
|
radius_mult = radius_sq * mult_sq + radius_sq * radius_sq * mult_qd;
|
|
mag = radius_mult;
|
|
radius_mult = rescale * (1.0 + radius_mult);
|
|
|
|
srcX = center_x + radius_mult * off_x;
|
|
srcY = center_y + radius_mult * off_y;
|
|
|
|
brighten = 1.0 + mag * brighten;
|
|
pa->pixelAccessGetCubic(srcX, srcY, brighten, dst);
|
|
dst += bytesDepth;
|
|
}
|
|
|
|
// Update progress bar in dialog.
|
|
|
|
progress = (int) (((double)dstJ * 100.0) / jLimit);
|
|
if (m_parent && progress%5 == 0)
|
|
postProgress(progress);
|
|
}
|
|
|
|
delete pa;
|
|
}
|
|
|
|
} // NameSpace DigikamLensDistortionImagesPlugin
|