views:

207

answers:

4

i need to re-project a series of ariel images that have been referenced in a geographical coordinate system into a UTM projection. I had read that using getPixel and setPixel might be slow - should set up a series of 2 dimensional arrays for intermediate access and then flush the values to the destination image when I am done.

Is this normally this sort of image processing is done by the professionals?

+4  A: 

Most image processing is feature detection, segmentation of a scene, fault finding, classification and tracking ....

You might want to take a peek at the book:

  1. Image Processing in C (applicable for other languages too)
  2. Image Processing - Principles and Applications

Which describes many fast and effective means of many image transformations. These two books helped me when I was processing images :)

If I understand your question ... If you are re-aligning or assembling many images, and you don't have orientation as well as position, you can use these algorithms for re-alignment of edges and common features. If you are stitching by position then these algorithms will help in re-sampling/resizing your images for more efficient assembly. There are also some open source libraries for these kinds of things. (OpenCV comes to mind)

edit: If I were re-projecting large images into new projections based on position conversion (and it were dynamic, not static) I would look into building an on-demand application that will refactor images given required resolution and desired position. The application can then pull the nearest resolution of the relative neighbourhood images and provide a result at the desired resolution.

Without more background, I hope this helps!

edit 2: Comment from answer below: Depends on the images. If they are fixed size then an array might be good. If they vary then it might be better to implement a system that provides get/setpixel using relative sampling/averaging to match up images of differing res?

I don't know the ins and outs of the images you are working with, and what you are doing, but often abstracting what a 'pixel' is rather than accessing values in an array is useful. This way you can implement conversion, sampling, rotating, correcting algorithms on the backend. Like GetVPixel() or SetVPixel(). This may be more useful when working with multiple, differing res/format images. Like

SetVPixel(img1, coord1, GetVPixel(img2, coord2))

Obviously in an OOP/C# manner. img1 and img2 can be different in size, res, geographics, alignment or anything else providing your backend understands both.

Aiden Bell
+1  A: 

AFAIK the overhead of GetPixel/SetPixel is the call to it, when accessing an array there is no call hence less overhead.

You should start with GetPixel/SetPixel, you can alway override those calls later to use direct data access.

Shay Erlichmen
Depends on the images. If they are fixed size then an array might be good. If they vary then it might be better to implement a system that provides get/setpixel using relative sampling/averaging to match up images of differing res?
Aiden Bell
+3  A: 

If you don't mind using unsafe code, you can wrap the Bitmap's BitmapData in an object that allows you to efficiently get and set pixels. The below code is mostly taken from a gaussian blur filter, with a couple of modifications of my own. It's not the most flexible code if your bitmap formats differ but I hope it illustrates how you can manipulate bitmaps more efficiently.

public unsafe class RawBitmap : IDisposable
{
    private BitmapData _bitmapData;
    private byte* _begin;

    public RawBitmap(Bitmap originBitmap)
    {
        OriginBitmap = originBitmap;
        _bitmapData = OriginBitmap.LockBits(new Rectangle(0, 0, OriginBitmap.Width, OriginBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        _begin = (byte*)(void*)_bitmapData.Scan0;
    }

    #region IDisposable Members

    public void Dispose()
    {
        OriginBitmap.UnlockBits(_bitmapData);
    }

    #endregion

    public unsafe byte* Begin
    {
        get { return _begin; }
    }

    public unsafe byte* this[int x, int y]
    {
        get
        {
            return _begin + y * (_bitmapData.Stride) + x * 3;
        }
    }

    public unsafe byte* this[int x, int y, int offset]
    {
        get
        {
            return _begin + y * (_bitmapData.Stride) + x * 3 + offset;
        }
    }

    public unsafe void SetColor(int x, int y, Color color)
    {
        byte* p = this[x, y];
        p[0] = color.B;
        p[1] = color.G;
        p[2] = color.R;
    }

    public unsafe Color GetColor(int x, int y)
    {
        byte* p = this[x, y];

        return new Color
        (
            p[2],
            p[1],
            p[0]
        );
    }

    public int Stride
    {
        get { return _bitmapData.Stride; }
    }

    public int Width
    {
        get { return _bitmapData.Width; }
    }

    public int Height
    {
        get { return _bitmapData.Height; }
    }

    public int GetOffset()
    {
        return _bitmapData.Stride - _bitmapData.Width * 3;
    }

    public Bitmap OriginBitmap { get; private set; }
}
Morten Christiansen
+2  A: 

The FreeImage library is pretty fast and offers a Cut and Paste that might be useful. The distribution comes with a C# wrapper.

R Ubben