I’m learning how to work with emgu cv in visual c #, there was a problem when working with pixels via unsafe code, in particular changing the Bitmap. The following code is for pixel-by-pixel painting of an image with PixelFormat "Format32bppArgb" in black and it works.

public unsafe void MyFunc(Mat image) { //CvInvoke.CvtColor(image, image, ColorConversion.Bgr2Gray); Bitmap bitmap = image.Bitmap; System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); byte* scan0 = (byte*)bitmapData.Scan0.ToPointer(); //byte Bpp = 8; //Format8bppIndexed byte Bpp = 32; //Format32bppArgb for (int i = 0; i < bitmapData.Height; ++i) { for (int j = 0; j < bitmapData.Width; ++j) { byte* data = scan0 + i * bitmapData.Stride + j * Bpp / 8; *data++ = 0; *data++ = 0; *data = 0; } } bitmap.UnlockBits(bitmapData); } 

result: And this code is intended for “pixel-by-pixel” painting of an image with PixelFormat “Format8bppIndexed” black, and it does not work, it seems that in the case of “Format8bppIndexed” another pixel is used to store the image pixels and the Bitmap changes do not affect him

  public unsafe void MyFunc(Mat image) { CvInvoke.CvtColor(image, image, ColorConversion.Bgr2Gray); Bitmap bitmap = image.Bitmap; System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); byte* scan0 = (byte*)bitmapData.Scan0.ToPointer(); byte Bpp = 8; //Format8bppIndexed //byte Bpp = 32; //Format32bppArgb for (int i = 0; i < bitmapData.Height; ++i) { for (int j = 0; j < bitmapData.Width; ++j) { byte* data = scan0 + i * bitmapData.Stride + j * Bpp / 8; //*data++ = 0; //*data++ = 0; *data = 0; } } bitmap.UnlockBits(bitmapData); } 

result: Please tell me what I can do wrong.

... News from the front))

  unsafe { CvInvoke.CvtColor(image, image, ColorConversion.Bgr2Gray); Bitmap bitmap = image.Bitmap; System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); byte* scan0 = (byte*)bitmapData.Scan0.ToPointer(); byte Bpp = 8; //Format8bppIndexed //byte Bpp = 32; //Format32bppArgb for (int i = 0; i < bitmapData.Height; ++i) { for (int j = 0; j < bitmapData.Width; ++j) { byte* data = scan0 + i * bitmapData.Stride + j * Bpp / 8; //*data++ = 0; //*data++ = 0; *data = 0; } } bitmap.UnlockBits(bitmapData); //////////////////////TEST/////////////////////////////////////////////////////////////// Bitmap bitmap_test = image.Bitmap; bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); System.Drawing.Imaging.BitmapData bitmapData_test = bitmap_test.LockBits(new Rectangle(0, 0, bitmap_test.Width, bitmap_test.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap_test.PixelFormat); byte* scan0_test = (byte*)bitmapData_test.Scan0.ToPointer(); byte[] arr = new byte[bitmap.Width* bitmap.Height]; byte[] arr_test = new byte[bitmap_test.Width*bitmap_test.Height]; for (int i = 0; i < bitmapData.Height; ++i) { for (int j = 0; j < bitmapData.Width; ++j) { arr[i * bitmapData.Width + j] = scan0[i * bitmapData.Width + j]; arr_test[i * bitmapData.Width + j] = scan0_test[i * bitmapData.Width + j]; } } bitmap_test.UnlockBits(bitmapData_test); bitmap.UnlockBits(bitmapData); ////////////////////////////////////////////////////////////////////////////////////////// } 

using the above code, it was possible to find out that the initially taken "bitmap" successfully underwent all the necessary changes, but the repeated taking of the image.Bitmap property returned a new object, I come to the conclusion that with PixelFormat.Format8bppIndexed the Mat object returns not Bitmap but something like Bitmap.Clone ( ). Am I right? (I want to not)

I need the fastest way to "pixel-by-pixel" image changes Mat Format8bppIndexed, the "accelerated" analog of SetPixel. I would be grateful if someone tells you the direction in which to dig?

  • Absolutely correct impression: the indexed color format means that a color table is used (palette) - a pixel does not contain the color itself, but its index in the table. - Alias
  • Perhaps you need a response from the English. SO: stackoverflow.com/questions/2593212/… - Alias
  • Good afternoon, I know about Palette, in this case the code should have worked anyway, as with * data = 0, the value should have referred to Palette [0] - SergiyPW

0