Super-sharpening(?) the image
I may have forgotten to mention it, but my expertise is not in image processing. The people who know better will likely tsk mightily at this and upcoming posts. My apologies. =)
Last time got me a b&w-converted version of a picture, but didn’t do much with it. Next up, I need a sequence of integer values from each row in the image for more processing. Eventually I want to convert those numbers to simple on-and-off values for processing. For starters, it seems like I should be able to convert each RGB pixel value into its 0-255 greyscale equivalent. Once I’ve got a byte, my simple theory is that squaring that 8-bit grayscale will produce a 16-bit ushort to process.
Thus:
- Access the bits of the image
- Convert each pixel to greyscale
- Push “light” pixels towards some high-value, push “dark” pixels down towards some low-value
- Wrap that up in some sort of enumerator.
With a little yield fun, I ended up with an enumerator that produces ushort[] from each row in the image.
- Why ushorts? 255*255 = 65025, which is less than 65535.
- Why not put the RowData function into the enumerator with the yield? Because C# doesn’t allow unsafe code blocks in iterators. Wierd.
- I’ll need to put the Bitmap acquisition and the LockData outsidethe enumerator, but that’s OK.
public class ImageRowEnumerator : IEnumerable<ushort[]> {
BitmapData _bmpData;
int _rowSkip;
public ImageRowEnumerator(BitmapData b, int skip) {
_bmpData = b;
_rowSkip = skip;
}
public IEnumerator<ushort[]> GetEnumerator() {
for (int row = 0; row < _bmpData.Height; row += _rowSkip)
yield return RowData(_bmpData, row);
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
unsafe ushort[] RowData(BitmapData bmpData, int row) {
ushort[] row_data = new ushort[_bmpData.Width];
byte* pData = (byte*)bmpData.Scan0 + (bmpData.Stride * row);
for (int col = 0; col < _bmpData.Width; col++, pData += 3) {
ushort color = (ushort)((pData[0] * .3f) + (pData[1] * .59f) + (pData[2] * .11f));
row_data[col] = (ushort)(color * color);
}
return row_data;
}
}
Next time, converting from the ushort values to on/off. It’s not just checking for 50%.