Problem Displaying on a Windows Form in C#
Posted: 03 March 2010 08:03 AM   [ Ignore ]
New Member
Rank
Total Posts:  4
Joined  2010-01-21

I am doing a tracking application where I need to be able to access all the pixels and display them to a windows form.
The best way I thought of doing this was converting the InteropBitmap to a System.Drawing.Bitmap

To do that I am doing this

//img is the InteropBitmap

            
Bitmap bmp null;
            
byte[] byte_arr = new byte[(int)(img.PixelWidth img.PixelHeight)];
            try
            
{
                
//The Width and Height should be static don't bother depending on the 
                //InteropBitmap for them
                
if (imgW == -|| imgH == -1)
                
{
                    imgW 
= (int)img.PixelWidth;
                    
imgH = (int)img.PixelHeight;
                
}

                bmp 
= new Bitmap(imgWimgHPixelFormat.Format32bppArgb);


                
System.Drawing.Imaging.BitmapData bData bmp.LockBits(new Rectangle(new Point(), bmp.Size),
                    
ImageLockMode.ReadWritePixelFormat.Format8bppIndexed);


                
int stride 320;
                
img.CopyPixels(byte_arrstride0);
                
Marshal.Copy(byte_arr0bData.Scan0byte_arr.Length);


                
bmp.UnlockBits(bData);
            
}
            
catch(Exception ex)
            
{
            }

            
return bmp

This is the image I end up getting when I draw bmp
XDRF3.png

It should be a black and white image, but I am getting these weird colors

I am setting it to greyscale with this line in my Form1_Load event
device.ColorMode = CLEyeCameraColorMode.CLEYE_GRAYSCALE;

What I am attempting to do is write finger tracking software that detects when my fingers are pressed up against this piece of glass. Greyscale values would be extremely helpful in doing this.

When I just run the CLEyeMulticamWPFTest I get an image I’m expecting, but unfortunately I can’t really work with InteropBitmaps.
Unless anyone knows a way of getting a 2d array of greyscale values from the InteropBitmap. I thought my way would have done something similar, but with those wacky colors I’m unsure of what I am doing.
PZlmS.png

Image Attachments
PZlmS.pngXDRF3.png
Profile
 
 
Posted: 03 March 2010 10:47 AM   [ Ignore ]   [ # 1 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  585
Joined  2009-09-17

Not sure why you need 2d array of grayscale values, but you can definitely get 1d array from the CLEyeCameraGetFrame function.
I would use the bitmap only for display and do all the processing straight from the data array you get from CLEyeCameraGetFrame function. Alternatively, which will result in better performance, I would write a native C++/C# dll that does all the processing and then use that in your Windows Form C# app.

In your example you setting up the capture as monochrome 8bits per pixel. But your bitmap is set to 32bits, then you are getting monochrome buffer from it with the stride is set to 320 bytes. This seems like unnecessary pixel format conversion. Why not create a mono bitmap in the first place? This will eliminate all the weird colors you are getting.

Profile
 
 
Posted: 03 March 2010 08:53 PM   [ Ignore ]   [ # 2 ]
New Member
Rank
Total Posts:  4
Joined  2010-01-21

There is a reason that I had is set as a 32 bit scheme. For some reason the form will not display indexed bitmaps. I’m still relatively new to C# and image processing, and I don’t know all the in’s and out’s yet. 

I did not even realize that I had static methods to work with. I’m so happy you mentioned these it will make work much easier.

Because I’m new to image processing I don’t really know how I would parse the 1D array of pixels. My guess is I would have to do something like this. Is this correct?

int imgW;
int imgH;
int stride;
byte pxl[];

for(
int i 0imgHi++)
{
  
for(int j 0imgWj++)
  
{
   Console
.out.WriteLine("The pixel at x: "+j+" y: "+i+" has a value of: "+pxl[(i*stride)+j];
  
}
Profile
 
 
Posted: 04 March 2010 01:47 AM   [ Ignore ]   [ # 3 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  585
Joined  2009-09-17

Yes you are correct. This is how you would address the pixels in the 1d image array.
To go back to your previous code example, after looking it over again I noticed that you are using indexed colors. This the problem. You never initialize the indexed color array. It should be initialized so that it corresponds to a grayscale value you are indexing.

Profile
 
 
Posted: 04 March 2010 08:16 AM   [ Ignore ]   [ # 4 ]
New Member
Rank
Total Posts:  4
Joined  2010-01-21

I thought that may have been the problem. I’ve been searching google for a way to do that for the past week or so. I can’t find it.

I’ve tried doing something like this

ColorPalette pal bmp.Palette;
                for (
int i 016i++)
                
{
                    pal
.Entries[i] Color.FromArgb(1iii);
                

I put that before the bmp.UnlockBits(bData);

and it produced a graphics error where a red X was drawn to my form

then I tried it after and it produced no result.

How do I initialize the indexed color array correctly?

Profile
 
 
Posted: 04 March 2010 05:20 PM   [ Ignore ]   [ # 5 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  585
Joined  2009-09-17

I quickly put together a WinForms program (using the latest CL-Eye Platform SDK) that demonstrates what you want to do. It basically sets up a bitmap, allocates global memory that continuously gets filled with camera image data. The bitmap is then refreshed by the thread and image is displayed.
To get the sample working, create a simple WinForms app and add picturebox with 320x240 dimensions to the main form.
Replace Program.cs in the project with this code. Make sure that the CLEyeMulticam.dll is in the same directory with the generated exe file.

Here is the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Drawing;
using System.Threading;

namespace 
CLEyeWinFormTest
{
    
public class Program
    {
        
#region [ Camera Parameters ]
        // camera color mode
        
public enum CLEyeCameraColorMode
        {
            CLEYE_MONO_PROCESSED
,
            
CLEYE_COLOR_PROCESSED,
            
CLEYE_MONO_RAW,
            
CLEYE_COLOR_RAW,
            
CLEYE_BAYER_RAW
        }
;

        
// camera resolution
        
public enum CLEyeCameraResolution
        {
            CLEYE_QVGA
,
            
CLEYE_VGA
        }
;
        
// camera parameters
        
public enum CLEyeCameraParameter
        {
            
// camera sensor parameters
            
CLEYE_AUTO_GAIN,            // [false, true]
            
CLEYE_GAIN,                    // [0, 79]
            
CLEYE_AUTO_EXPOSURE,        // [false, true]
            
CLEYE_EXPOSURE,                // [0, 511]
            
CLEYE_AUTO_WHITEBALANCE,    // [false, true]
            
CLEYE_WHITEBALANCE_RED,        // [0, 255]
            
CLEYE_WHITEBALANCE_GREEN,    // [0, 255]
            
CLEYE_WHITEBALANCE_BLUE,    // [0, 255]
            // camera linear transform parameters
            
CLEYE_HFLIP,                // [false, true]
            
CLEYE_VFLIP,                // [false, true]
            
CLEYE_HKEYSTONE,            // [-500, 500]
            
CLEYE_VKEYSTONE,            // [-500, 500]
            
CLEYE_XOFFSET,                // [-500, 500]
            
CLEYE_YOFFSET,                // [-500, 500]
            
CLEYE_ROTATION,                // [-500, 500]
            
CLEYE_ZOOM,                    // [-500, 500]
            // camera non-linear transform parameters
            
CLEYE_LENSCORRECTION1,        // [-500, 500]
            
CLEYE_LENSCORRECTION2,        // [-500, 500]
            
CLEYE_LENSCORRECTION3,        // [-500, 500]
            
CLEYE_LENSBRIGHTNESS        // [-500, 500]
        
};
        
#endregion

        #region [ CLEyeMulticam Imports ]
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern int CLEyeGetCameraCount();
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern Guid CLEyeGetCameraUUID(int camId);
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern IntPtr CLEyeCreateCamera(Guid camUUIDCLEyeCameraColorMode modeCLEyeCameraResolution resfloat frameRate);
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern bool CLEyeDestroyCamera(IntPtr camera);
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern bool CLEyeCameraStart(IntPtr camera);
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern bool CLEyeCameraStop(IntPtr camera);
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern bool CLEyeCameraLED(IntPtr camerabool on);
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern bool CLEyeSetCameraParameter(IntPtr cameraCLEyeCameraParameter paramint value);
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern int CLEyeGetCameraParameter(IntPtr cameraCLEyeCameraParameter param);
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern bool CLEyeCameraGetFrameDimensions(IntPtr cameraref int widthref int height);
        
[DllImport("CLEyeMulticam.dll")]
        
public static extern bool CLEyeCameraGetFrame(IntPtr cameraIntPtr pDataint waitTimeout);
        
#endregion

        #region [ Program Singleton ]
        
private static Program instance;
        public static 
Program Instance
        {
            get
            {
                
if (instance == null)
                    
instance = new Program();
                return 
instance;
            
}
        }
        
#endregion

        #region [ Variables ]
        
MainForm _form;
        
IntPtr _ptrBmpPixels;
        
bool _threadRunning;
        
ManualResetEvent _exitEvent;
        
IntPtr _camera;
        
#endregion

        
public static int CameraCount { get { return CLEyeGetCameraCount(); } }
        
public static Guid CameraUUID(int idxreturn CLEyeGetCameraUUID(idx); }

        
public Program()
        
{
            Application
.EnableVisualStyles();
            
Application.SetCompatibleTextRenderingDefault(false);
            
_form = new MainForm();
            
_form.Load += new EventHandler(OnLoaded);
        
}

        void OnLoaded
(object senderEventArgs e)
        
{
            int w 
00;
            
_camera CLEyeCreateCamera(CameraUUID(0), CLEyeCameraColorMode.CLEYE_MONO_RAWCLEyeCameraResolution.CLEYE_QVGA30);
            if (
_camera == IntPtr.Zero) return;
            
CLEyeCameraGetFrameDimensions(_cameraref wref h);
            
CreateBitmap(wh);
            
// create thread exit event
            
_exitEvent = new ManualResetEvent(false);
            
// start capture here
            
ThreadPool.QueueUserWorkItem(Capture);

        
}

        void CreateBitmap
(int wint h)
        
{
            
// allocate bitmap memory
            
_ptrBmpPixels Marshal.AllocHGlobal(h);
            
// create bitmap object
            
Bitmap bmpGraph = new Bitmap(whwPixelFormat.Format8bppIndexed_ptrBmpPixels);

            
// setup gray-scale palette
            
ColorPalette GrayPalette bmpGraph.Palette;
            for (
int i 0GrayPalette.Entries.Lengthi++)
                
GrayPalette.Entries[i] Color.FromArgb(iii);
            
bmpGraph.Palette GrayPalette;

            
// set bitmap to the picture box
            
_form.pictureBox1.Image bmpGraph;
        
}

        
// capture thread
        
void Capture(object obj)
        
{
            _threadRunning 
true;
            
Random rng = new Random();
            
CLEyeCameraStart(_camera);
            while (
_threadRunning)
            
{
                
if(CLEyeCameraGetFrame(_camera_ptrBmpPixels500))
                    
_form.pictureBox1.Invalidate();
            
}
            CLEyeCameraStop
(_camera);
            
CLEyeDestroyCamera(_camera);
            
_exitEvent.Set();
        
}

        
public void Run()
        
{
            Application
.Run(_form);
            
// stop capture thread here
            
_threadRunning false;
            
_exitEvent.WaitOne(3000);
        
}

        
/// <summary>
        /// The main entry point for the application.
        /// </summary>
        
[STAThread]
        
static void Main()
        
{
            
// check if camera is connected
            
if (Program.CameraCount == 0) return;
            
Program.Instance.Run();
        
}
    }
Profile
 
 
Posted: 06 March 2010 11:59 AM   [ Ignore ]   [ # 6 ]
New Member
Rank
Total Posts:  4
Joined  2010-01-21

For some reason when I did what you said it wouldn’t create a camera, but I did some tweaking to the code and was able to get it working on my machine. Thank you so much for helping me with this.

Profile
 
 
Posted: 06 March 2010 12:41 PM   [ Ignore ]   [ # 7 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  585
Joined  2009-09-17
BossOfTheGame - 06 March 2010 11:59 AM

For some reason when I did what you said it wouldn’t create a camera, but I did some tweaking to the code and was able to get it working on my machine. Thank you so much for helping me with this.

Not sure why you couldn’t create the camera, but if you are running under x64 Windows, make sure to compile your project with x86 CPU type.

Profile
 
 
 
 


RSS 2.0     Atom Feed