Problems creating a Frame for Photodetector


#1

Hi everyone,

I am pretty new to Affectiva. I have been using it for my research projects. So my question is related to create a Frame and pass it to a PhotoDetector to detect emotions in a picture.

When I create a Frame I get an AffdexException related to “memory violation” and my program breaks just in the line I have created the Frame in this way:

Frame frame = new Frame(img.Width, img.Height, pixelsArray, Frame.COLOR_FORMAT.RGB);

Assuming that:

  • “img” is a correct image object (I checked)
  • “width” is in pixels
  • “height” is in pixels
  • “pixelsArray” is a byte array containing image data.

I don´t know if I am in the good way to create a Frame or I am doing something wrong.

P.S: I have read this topic C# AccessViolationException but this didn´t help me.

I would appreciate your help!
Thanks!!!


#2

That line of code looks correct, assuming that pixelsArray points to an RGB image.


#3

The image is a RGB image. But I left my entire code here:

        PhotoDetector detector = new PhotoDetector(1, FaceDetectorMode.LARGE_FACES);
        Process process = new Process(detector);
        String classifierPath = "C:\\Program Files\\Affectiva\\AffdexSDK\\data";
        detector.setClassifierPath(classifierPath);

        detector.setDetectAllExpressions(true);
        detector.setDetectAllEmotions(true);
        detector.setDetectBrowRaise(true);
        detector.setDetectSmirk(true);
        detector.setDetectGender(true);
        detector.setDetectGlasses(true);
        detector.start();
        byte[] pixelsArray = Convert.FromBase64String(base64);
        Image img = Base64ToImage(base64);

        Affdex.Frame frame = new Affdex.Frame(img.Width, img.Height, pixelsArray, Frame.COLOR_FORMAT.RGB);
        
        detector.process(frame);
            
        detector.stop();

“base64” is a Base64 string that I receive in my server.


#4

What is img.PixelFormat, and what is the size of pixelsArray?


#5

The code img.PixelFormat returns this: Format24bppRgb.

The code img.Width returns: 268.
The code img.Heigth returns : 188.

The size of “pixelsArray” is 4906.


#6

Each pixel is 24 bits (3 bytes), so the pixel array should be 268 x 188 x 3 = 151,152 bytes in size.


#7

But why the size of the image in bytes is the same that I obtain by code?

size

If it is possible, how could I get the “correct” byte array with size 151,152?


#8

I have the same problem when I try create the Frame. I use .PNG image to do that, but I don’t know why it doesn’t work. I get the following error:

Affdex.AffdexException: “Attempt to read or write to the protected memory. This often indicates that another memory is damaged”.

My data:
pixelformat: Format32bppArgb
img.width: 275
img.height: 275
byte[] lenght: 28197


#9

JPG and PNG are compressed image file formats. The pixel data passed to the Frame constructor should be uncompressed, and in the format that matches the value of the color format parameter supplied to it (e.g. RGB or RGBA).


#10

Finally I found a way to create a frame in a proper way. I leave the code here for people that need it in a future.

public Frame LoadFrameFromFile(string filePath)
    {
        Bitmap bitmap = new Bitmap(filePath);

        // Lock the bitmap's bits.
        Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
        BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);

        // Get the address of the first line.
        IntPtr ptr = bmpData.Scan0;

        // Declare an array to hold the bytes of the bitmap. 
        int numBytes = bitmap.Width * bitmap.Height * 3;
        byte[] rgbValues = new byte[numBytes];

        int data_x = 0;
        int ptr_x = 0;
        int row_bytes = bitmap.Width * 3;      //3 bytes per pixel

        // The bitmap requires bitmap data to be byte aligned.

        for (int y = 0; y < bitmap.Height; y++)
        {
            Marshal.Copy(ptr + ptr_x, rgbValues, data_x, row_bytes);//(pixels, data_x, ptr + ptr_x, row_bytes);
            data_x += row_bytes;
            ptr_x += bmpData.Stride;
        }

        bitmap.UnlockBits(bmpData);

        return new Affdex.Frame(bitmap.Width, bitmap.Height, rgbValues, Affdex.Frame.COLOR_FORMAT.BGR);
    }