Rank: Advanced Member
Groups: Guest
Joined: 7/28/2003(UTC) Posts: 1,660
Thanks: 5 times Was thanked: 76 time(s) in 74 post(s)
|
This simple algorithm is based on the work of Tanner Helland. Please note this implementation supports neither interpolation nor memory-efficient pipeline image processing. Code:/// <summary>
/// Corrects lens distortion
/// </summary>
/// <param name="source">source bitmap</param>
/// <param name="strength">>= 0. 0 = no change, high numbers equal stronger correction.</param>
/// <param name="zoom">>= 1. (1 = no change in zoom)</param>
/// <returns></returns>
private Aurigma.GraphicsMill.Bitmap CorrectLensDistortion(Aurigma.GraphicsMill.Bitmap source
, float strength, float zoom)
{
if (source.PixelFormat.Size < 8)
{
throw new Aurigma.GraphicsMill.UnsupportedPixelFormatException();
}
if (strength < 0)
{
throw new ArgumentOutOfRangeException();
}
if (zoom < 1)
{
throw new ArgumentOutOfRangeException();
}
var target = new Aurigma.GraphicsMill.Bitmap(source.Width, source.Height, source.PixelFormat);
var bytes = source.PixelFormat.Size / 8;
int halfWidth = source.Width / 2;
int halfHeight = source.Height / 2;
float correctionRadius = (float)(Math.Sqrt(source.Width ^ 2 + source.Height ^ 2)) / strength;
unsafe
{
//A pointer to the beginning of the pixel data region
byte* sourcePointer = (byte*)(source.Scan0.ToPointer());
byte* targetPointer = (byte*)(target.Scan0.ToPointer());
//Number of bytes in a row
int stride = target.Stride;
//Number of rows
int height = target.Height;
int width = target.Width;
for (int i = 0; i < height; i++)
{
byte* position = targetPointer + stride * i;
for (int j = 0; j < width; j++)
{
float newX = (float)(j - halfWidth);
float newY = (float)(i - halfHeight);
float distance = (float)(Math.Sqrt(newX * newX + newY * newY));
float r = distance / correctionRadius;
float theta;
if (r == 0)
{
theta = 1;
}
else
{
theta = (float)(Math.Atan(r)) / r;
}
int sourceX = halfWidth + (int)(theta * newX * zoom);
int sourceY = halfHeight + (int)(theta * newY * zoom);
//set color of pixel (x, y) to color of source image pixel at (sourceX, sourceY)
if (sourceX >= 0 && sourceX < source.Width && sourceY >= 0 && sourceY < source.Height)
{
//target.SetPixel(j, i, source.GetPixel(sourceX, sourceY));
byte* s = sourcePointer + stride * sourceY + sourceX * bytes;
for (int z = 0; z < bytes; z++)
{
*position = *s;
position++;
s++;
}
}
else
{
for (int z = 0; z < bytes; z++)
{
*position = 0;
position++;
}
}
}
}
}
return target;
}
Using: Code:var source = new Aurigma.GraphicsMill.Bitmap(@"c:\temp\photo.jpg");
var target = CorrectLensDistortion(source, 0.02f, 1f);
target.Save(@"c:\temp\out.jpg");
Edited by user Thursday, June 19, 2014 12:33:36 AM(UTC)
| Reason: Not specified |
Best regards, Fedor Skvortsov
|
|
|
|
Rank: Newbie
Groups: Guest
Joined: 6/19/2014(UTC) Posts: 1
|
Thanks Fedor, just what I needed... :o) Jon Ivar
|
|
|
|
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.