Posts

Software Algorithm Complexity Cheat-Sheet

Software Algorithm Complexities – Having trouble remembering your O(n)’s from your O(log N)’s, not to worry I just found this very handy complexity cheat-sheet –

http://bigocheatsheet.com/

I am currently doing some research into possible indexing mechanisms for very large sets of images in Computer Vision applications, so this sheet is very handy, thanks Eric!

C# Create a Cognex 8bit image (CogImage8Grey) from an 8bit Grayscale image array (byte[])

Here is some code that shows how to create an 8bit grayscale cognex image (CogImage8Grey) from an 8bit raw image stored as a byte array (byte[]). This type of memory messing is difficult in .NET at the best of times and it’s just a pity the the cognex library doesn’t help much more than it does.

 

I also have a feeling that the cognex library is doing more copying than it strictly needs to, but in true style its software documentation does not detail if, or when, it copies image data (or much else for that matter!) So I copy the image data from the byte array into a malloc’ed buffer before creating the cognex image.

 

First we have to define a SafeBuffer through which cognex can free up the allocated memory when it is finished with it, to do this we can derive a class from SafeBuffer like this:
[crayon lang=”csharp”]
///

/// A wrapper around malloc so that FreeHGlobal() is called
/// when the object is disposed.
///

class SafeMalloc : SafeBuffer
{
///

/// Allocates memory and initialises the SaveBuffer
///

///The number of bytes to allocate public SafeMalloc(int size) : base(true)
{
this.SetHandle(Marshal.AllocHGlobal(size));
this.Initialize((ulong)size);
}

///

/// Called when the object is disposed, ferr the
/// memory via FreeHGlobal().
///

///
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(this.handle);
return true;
}

///

/// Cast to IntPtr
///

public static implicit operator IntPtr(SafeMalloc h)
{
return h.handle;
}
}
[/crayon]

 

Its constructor mallocs the memory and when it is disposed ReleaseHandle() is called, and this frees the memory. I also added a cast to IntPtr so that we can pass it into functions that expect an IntPtr.

 

Now that we have SafeMalloc we can write function to create the cognex image like this:
[crayon lang=”csharp”]
class CognexStuff
{
public ICogImage Convert8BitRawImageToCognexImage(
byte[] imageData, int width, int height)
{
// no padding etc. so size calculation
// is simple.
var rawSize = width * height;

var buf = new SafeMalloc(rawSize);

// Copy from the byte array into the
// previously allocated. memory
Marshal.Copy(imageData, 0, buf, rawSize);

// Create Cognex Root thing.
var cogRoot = new CogImage8Root();

// Initialise the image root, the stride is the
// same as the widthas the input image is byte alligned and
// has no padding etc.
cogRoot.Initialize(width, height, buf, width, buf);

// Create cognex 8 bit image.
var cogImage = new CogImage8Grey();

// And set the image roor
cogImage.SetRoot(cogRoot);

return cogImage;
}
}
[/crayon]

 

This function allocates memory via SafeMalloc, it then copies the raw image data from the input array into this memory. Then CogImage8Root.Initialize() is called passing in a pointer to this memory. not that in this case the image’s stride is the same as its width. Once the CogImage8Root has been initialised we can create a CogImage8Grey image and set the root via a call to SetRoot()!

 

They certainly make you work for it!!

 

If you know that nobody else will be using your image array and are willing to go ‘unsafe'(!) then you could avoid this extra memory copy by pinning the array and getting a pointer to it, you could then pass this pointer directly to the root Initialize() function. In this case you won’t need the SafeMalloc class etc.

 

Thanks to all on this thread for hints on SafeBuffer!

 

C# Save Grayscale byte array Image (byte[]) as Bitmap file (.bmp) example

Here is a quick, dirty and inefficient example of how to save an 8bit Grey scale image stored in a C# byte array as a 32bit bitmap file (.bmp). Saving bitmaps can be quite suprisingly difficult in .NET so I am posting this for future reference!

This code copies each byte (8 bit pixel) in the 8bit image into an array of 32bit pixels (4 bytes per pixel) and then saves it to disk. Note that you have to build your project with the ‘Allow unsafe code’ checkbox checked (go to project properties / Build and you will see the ‘Allow unsafe code’ checkbox.)

public void SaveAsBitmap(string fileName, int width, int height, byte[] imageData)
{
    // Need to copy our 8 bit greyscale image into a 32bit layout.
    // Choosing 32bit rather than 24 bit as its easier to calculate stride etc.
    // This will be slow enough and isn't the most efficient method.
    var data = new byte[width * height * 4];
    int o = 0;
    for (var i = 0; i < width * height; i++)
    {
        var value = imageData[i];
        // Greyscale image so r, g, b, get the same
        // intensity value.
        data[o++] = value;
        data[o++] = value;
        data[o++] = value;
        data[o++] = 0; // Alpha isn't actually used
    }
    unsafe
    {
        fixed (byte* ptr = data)
        {
            // Create a bitmap wit a raw pointer to the data
            using (Bitmap image = new Bitmap(width, height, width * 4,
            PixelFormat.Format32bppRgb, new IntPtr(ptr)))
            {
                // And save it.
                image.Save(Path.ChangeExtension(fileName, ".bmp"));
            }
        }
    }
}

Thanks to all on this thread for the pointers!

Update, 02/2014:

This code will save the 8 bit bitmap in a compressed (but perfectly valid) format, to have your software save it in an uncompressed format take a look at this post.

.NET, WPF – BitmapImage File Locking

Q: How can I stop BitmapImage, in .NET Windows Presentation Foundation (WPF) from locking the source image file?

 

A: By default BitmapInfo seems to lock the source image file so that you can use the bitmapinfo object and modify or delete the source file at the same (or similar) time. For example, this C# will probably yield a locked image file:

 


var bitmap = new BitmapImage(new Uri(imageFilePath));
// use bitmap...

 

You can get around this locking problem as follows, it’s a little bit more long-winded but it worked for us….

 


var bitmap = new BitmapImage();
var stream = File.OpenRead(imageFilePath);
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
stream.Close();
stream.Dispose();
// Use bitmap.....

 

Magento, Customized theme not using overridden images

Q: I have created a new skins folder beside my default theme’s skin folder, and placed some images that I want to override into an images sub folder. I have changed the ‘Skin (Images / CSS)’ setting in System -> Configuration -> Design -> Themes to point to my new skins, I have cleared the magento cache about 10 million times, but magento still won’t use my new images, it keeps using the originals…. what do I do?

 

A: This has caught me out once or twice and I have always forgotten about it by the time it happens again! The problem stems from the fact that the theme css file calls in images using a relative path, e.g.:

 


body {background-image:url('../images/bg.gif');}

 

So because the css file that uses your images remains in its original location it will still use your original images, to get it to use your overridden images you must create a css folder in your new skin folder and copy any css files that reference the images into there and clear the cache a further 20 times – hopefully magento will then use your new images!

 

Have a look here for some more details:

 

http://www.magentocommerce.com/boards/viewthread/2445/