07-22-2008 07:14 AM
07-25-2008 08:59 AM
07-25-2008 09:20 AM
11-26-2008 05:17 AM
Thanx for the code example below, helpfull!
I now can read the pixel values, but how to write the pixel values?
Can you (or anyone) give me an code example how to set (proces) the pixel value in the code below? e.g. for instance set all pixel values to 128?
Image *img; // let's say this variable contains a valid image grayscale image
ImageInfo info;
imaqGetImageInfo( img, &info );
now you can access any pixel into the buffer:
unsigned char *pixel_address = (unsigned char *)info.imageStart + y * info.pixelsPerLine + x;
unsigned char pixel_value = *pixel_address; // or combine this with the previous line to get direclty the pixel value
you can also go through your entire image:
for ( int y = 0; y < info.yRes; y++ )
{
for ( int x = 0; x < info.xRes; x++ )
{
pixel_address = (unsigned char *)info.imageStart + y * info.pixelsPerLine + x;
// proces your pixel straight into the buffer here...
// can you give me an code example how to set (proces) the pixel value here? for instance set all pixel values to 128?
}
}
11-26-2008 07:39 AM
the method i described gives you direct access to the image buffer. this means that you can read pixel values but also write values.
taking from my previous example:
for ( int y = 0; y < info.yRes; y++ )
{
for ( int x = 0; x < info.xRes; x++ )
{
pixel_address = (unsigned char *)info.imageStart + y * info.pixelsPerLine + x;
*pixel_address = 128;
}
}
more efficient:
unsigned char *pixel = info.imageStart;
for ( int y = 0; y < info.yRes; y++ )
{
for ( int x = 0; x < info.xRes; x++ )
{
*pixel = 128;
pixel += 1;
}
pixel += info.pixelsPerLine - info.xRes; // jump over all padding and border
}
since the values are written directly to the image buffer, the image does not need any further processing before using it in any other ni vision function.
11-27-2008 04:00 AM
Thanx. Now it works!
...I saw that I wrote the local var (pixel_value) in stead of directly writing into the buffer 🙂
(my C is a little rusty it's been a while)
If my image is not grayscale 8bit per pixel, how can I adjust the data type (used for the pointer arithmetic), or add a factor to the pixel address computation? code example?
Can you direct me how to write your own image sharpen function or some convolution filter (kernel)? or image processing library...(info links?)
For filtering here you need to access the correct neighbour pixels (up, down, left, right etc.) of the single long row of pixel values (image buffer) and process the current pixel? Code Example?
11-27-2008 04:13 PM
there are two ways of adjusting the bit-depth of the image:
- you can change the data type. for a 16 bit grayscale image, declare pixel address as a pointer to an "unsigned short".
- stay with an unsigned char pointer and adjust the offset in the pixel arithmetic: for 16 bit grayscale image, you get:
pixel_address = (unsigned char *)info.imageStart + (y * info.pixelsPerLine + x)*sizeof( unsigned short );
or better:
unsigned int pixel_size = sizeof( unsigned short );
pixel_address = (unsigned char *)info.imageStart + (y * info.pixelsPerLine + x)*pixel_size;
don't forget to adjust any pixel address computation.
the two are perfectly valid, but i'd rather use the second solution: the first solution will force you to repeat your function over and over again until you covered all possible data types. with the second option, the pixel size becomes a parameter, and the functions works for any data type: not just 8bit or 16bit grayscale, but also for floating point pixels, RGBA color pixels or even structures (for example, a 2 band image: one 16 bits color index associated with one 8 bit transparency value)... (if you were using C++, the data type could become a template, and this would be even more powerful).
writing your own convolution is a little bit more tricky. generally, your image processing library will do better than you. of course you can still do it yourself, but this would be overkill. there are some rare cases where what you want to perform is not available in the library: that's why i ended up writing my own contour walking function to compute the oriented bounding box of binary particles... there are plenty of places on the internet to find informations about image processing algorithm (the first one is googling for "image processing algorithm"). you have to read lots and lots of pages to find the real useful information, which is how to perform the function efficiently.
one last thing: CVI IS NOT AN OPTIMIZING COMPILER. you have to be very careful with the code you write, or it can be slower than using the NI vision library. also, do never think you found the fastest way to perform any given image processing task: generally, writing it in simple C statements and compiling it with an optimizing compiler will give you far better results. (Visual C++ is one such compiler if you don't forget to turn on all optimizations). i hope one day CVI will make some optimizations available.