Share Image Processing

Embed

size(px)

Link

Share

Description

Image Processing for Displacement filters, including swirl
Introduction This project displacement filters most of the information image processing is similar to the changing an image by changing the color values of pixels. Instead the filters we are looking at today change an image by changing each pixels location. Writing code to resize images the answer was that the last article explains bilinear filtering, a way of moving pixels so they are drawn to a theoretical location between physical pix

Image Processing for Displacement filters, includingswirl
Introduction
This project displacement filters most of the information image processing is similar to the changing an image by changing the color values of pixels. Instead the filters weare looking at today change an image by changing each pixels location. Writing codeto resize images the answer was that the last article explains bilinear filtering, a wayof moving pixels so they are drawn to a theoretical location between physical pixels.Once again we will start by implementing a frame work which we can use to createfilters. Our basic approach will be to create a two dimensional array of points. Thearray will be the size of the image, and each point will store the new location for the pixel at that index. We will do this two ways, one that stores a relative location, andone that stores an absolute location. Finally, we will create our own point struct,which contains two doubles instead of ints, which we will use to write theimplementation to performs the bilinear filtering.
Arrays in C#
I must admit I had not done anything with 2D arrays in C# before this, and they arevery cool. The code looks like this:Point [,] pt = new Point[nWidth, nHeight];This creates a 2D array dynamically, and we can access the pixels using notation like pt[2, 3], instead of the C++ pt[2][3]. Not only is this much neater than C++, but a
Point[,] is a valid parameter to pass into a function, making it a snap to pass aroundarrays of size unknown at compile time.
Offset Filter
The first helper function we will write will take a relative location, so for example if we want to move pixel 2, 4 to location 5, 2, then pt[2, 4] will equal 3, -2. We coulduse Set/GetPixel to do this, but we will continue to use direct access, which is probably faster. As we must now span an arbitrary number of rows to access pixelsfrom anywhere in the image, we will do so by using the Stride member of theBitmapData, which we can multiply by our Y value to get the number of rows down.Then our X value is multiplied by 3, because we are using 3 bytes per pixel ( 24 bit )as our format. The code looks like this:
Collapse
public static bool OffsetFilter(Bitmap b, Point[,] offset ){Bitmap bSrc = (Bitmap)b.Clone();
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height),ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int scanline = bmData.Stride; System.IntPtr Scan0 = bmData.Scan0;System.IntPtr SrcScan0 = bmSrc.Scan0; unsafe{byte * p = (byte *)(void *)Scan0;byte * pSrc = (byte *)(void *)SrcScan0; int nOffset = bmData.Stride - b.Width*3;int nWidth = b.Width;int nHeight = b.Height; int xOffset, yOffset; for(int y=0;y < nHeight;++y){for(int x=0; x < nWidth; ++x ){xOffset = offset[x,y].X;yOffset = offset[x,y].Y;
p[0] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3)];p[1] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3) + 1];p[2] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3) + 2]; p += 3;}p += nOffset;}} b.UnlockBits(bmData);bSrc.UnlockBits(bmSrc); return true;}You'll notice that the framework is there for a boolean success code, but it's not reallyused. The OffsetFilterAbs does pretty much the same thing, except that if we want tomove any pixel to location 3, 2, the point stored for that location will be 3, 2 and notan offset. OffsetFilterAntiAlias is much more complex because it implements a bilinear filter, if you don't understand that code, refer to the previous[^]article.
Now, the filters

Thank you for visiting our website and your interest in our free products and services. We are nonprofit website to share and download documents. To the running of this website, we need your help to support us.