LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Procesing image in Labview using a dll in c

I have a image in Labview I want this image as an input in my DLL in C but I don not know how to read every pixel to process the image. What I want to do is to pass the whole image to the DLL.

I have a cluster with the pointer pixel of the image, the size of the pixel and the size of the image.

 

Captura.PNGThis is the function in my DLL. "a" should contain the blue value of pixel [i][j]

 

DLLIMPORT int funcImage(int *pixel_pointer, int line_width, int pixel_size, int x_resolution, int y_resolution)
{
int j;
int i;
unsigned char b;
unsigned char g;
unsigned char r;
int gray[1000][100];

for(j = 0;j < y_resolution;j++){
    for(i = 0;i < x_resolution;i++){
        b = pixel_pointer[3*i + x_resolution*j] ;
        g = pixel_pointer[3*i + 1 + x_resolution*j];
        r = pixel_pointer[3*i + 2 + x_resolution*j];
        //gray[i][j] = ((int)r)* 0.3 + ((int)g)* 0.58 + ((int)b)* 0.11;
    }
}
int a;
b = pixel_pointer[3*14*648 + 3*21 - 2];
a = (int)b;

return a;
}
0 Kudos
Message 1 of 14
(3,241 Views)

There should be examples...

 

I presume that line_width has a function. It's probably used for word aligning each row. So I'd think (guess actually):

 

for(j = 0;j < y_resolution;j++){
    for(i = 0;i < x_resolution;i++){
        b = pixel_pointer[3*i + line_width*j] ;
        g = pixel_pointer[3*i + 1 + line_width*j];
        r = pixel_pointer[3*i + 2 + line_width*j];
        //gray[i][j] = ((int)r)* 0.3 + ((int)g)* 0.58 + ((int)b)* 0.11;
    }
}
0 Kudos
Message 2 of 14
(3,224 Views)

I tried what you said but it is still wrong, I am not sure how it is saved the image

0 Kudos
Message 3 of 14
(3,200 Views)

I can't look into the Call Library Node at all since you only posted an image!!! How did you configure it?

You declare the pixel_pointer parameter to be an int array but then index the pixel components in the C code like it was a byte array. The way your code is currently getting compiled your DLL treats the image pointer as if it was an RGB (U128) image that is an image with 128 bit per pixel and a 32 bit value per color. Change the pixel pointer parameter to be char * type to use your addressing method!  

 

And are you sure you create an RGB (U32) image in LabVIEW? There is no infomation in the pointer what image is contained, you have to make sure you pass a correct image to your function which assumes it is getting a 32bit RGB image. And in that case you also have to change the 3 in the index calculation with a 4 since there are always 4 bytes per pixel. IMAQ does not support a 24-bit pixel format!

 

Also configure the Pixel pointer as pointer sized integer in the Call Library Node! Then you won't have to worry about if you use this VI in 32-bit or 64-bit LabVIEW (with according DLL of course).

 

This is the function in my DLL. "a" should contain the blue value of pixel [i][j]

That's factually wrong! IYou need to adapt this also to account for the line_width just as you did with the rest and and it doesn't access the pixel at {j]ij} but at [14][20] since you do a minus for the color offset.

 

b = pixel_pointer[line_width * j + 4 * i + 2];

 

So much about C programming. You do not really appear to understand a lot about things pointers. Are you sure you want to continue on this path of doing this in C, where you will continously shoot in your foot by crashing the application even if you know C pointers very well?

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 14
(3,179 Views)

This is how I configure it: (I have change pixel_pointer to type string)

 

Captura2.PNG

0 Kudos
Message 5 of 14
(3,168 Views)

That 1st parameter isn't a string!

 

DLLIMPORT int funcImage(int *pixel_pointer, int line_width, int pixel_size, int x_resolution, int y_resolution)

You defined it as pointer to integer, so pass it as pointer to integer!

 

You could define it as integer (U64), and pass it as integer. No need to make it a pointer (to a pointer).

 

 

0 Kudos
Message 6 of 14
(3,161 Views)

True, but I changed to char:

 

DLLIMPORT int funcImage(unsigned char *pixel_pointer, int line_width, int pixel_size, int x_resolution, int y_resolution)
0 Kudos
Message 7 of 14
(3,158 Views)

@lamarck wrote:

True, but I changed to char:

 

DLLIMPORT int funcImage(unsigned char *pixel_pointer, int line_width, int pixel_size, int x_resolution, int y_resolution)

Why? It's not a char, nor a pointer to a char?

0 Kudos
Message 8 of 14
(3,154 Views)

Pointer to char is correct! C doesn't know a byte datatype, maybe nicer in terms of looks would be to define it in terms of the C11 standard types as uint8_t *pixel_pointer in the C function declaration.

 

But in the LabVIEW Call Library Node you really need to configure it as pointer sized integer passed by value. This is what the pixel pointer from the IMAQ GetImagePixelPtr vi is returning.

 

If you want to leave it as int* pixel_pointer in the function declaration you would have to change your code as follows (not sure about the byte locations of the r, g, and b components in the 32 bit integer, you will have to try it out):

DLLIMPORT int funcImage(int *pixel_pointer, int line_width, int pixel_size, int x_resolution, int y_resolution)
{
    int j;
    int i;
    int pixel;
    unsigned char b;
    unsigned char g;
    unsigned char r;
    int gray[1000][100];

if (pixel_size != 4)
return 0; // our code only handles 32 bit RGB values
for(j = 0;j < y_resolution;j++) { for(i = 0;i < x_resolution;i++) { pixel = pixel_pointer[i + line_width / pixel_size * j] b = pixel & 0xFF ; g = (pixel & 0xFF00) >> 8; r = (pixel & 0xFF0000) >> 16; //gray[i][j] = ((int)r)* 0.3 + ((int)g)* 0.58 + ((int)b)* 0.11; } } int a; pixel = pixel_pointer[21 + line_width / pixel_size * 14]; return (pixel & 0xFF); }

And if you enable the grey calculation, please make sure to never pass in an image with more than 100 * 1000 pixels or you cause a memory protection error.

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 9 of 14
(3,145 Views)

The integer itself is a pointer. Shouldn't it be passed as value, and then used in C as a pointer?

 

The dll would now get a pointer to the pointer, so the address of the first pointer will be where the data is expected.

0 Kudos
Message 10 of 14
(3,136 Views)