Page 1 of 1

reading pixels from a ImageMagik image?

Posted: 2007-06-23T22:40:42-07:00
by zacwitte
I'm trying to use the MagickWand C API to read in a .pgm file and get the grayscale intensities of each pixel into an array, but I'm having trouble figureing out how to get that pixel data once I read in the image. I'm using MagickReadImage() which works pretty well and I've verified it understands the image correctly by outputting it again as a .png file. But I've found the documentation lacking. I guess I can use GetImageFromMagickWand() to get an Image stuct, but I can't find the documentation for whats inside the Image and how to access the pixels. I've found this function called AcquireImagePixels(), but that gives me an array of PixelPackets and I can't find documentation for what a PixelPacket consists of and how to access its members. Plus, I have to somehow detect the image dimensions and generate this ExceptionInfo object. How do I then get those pixels into an int array?


Has whoever is responsible for maintaining the documentation considered using something more similar to JavaDoc or Doxygen? Could make people's lives much easier.

Thanks much for your help!

Re: reading pixels from a ImageMagik image?

Posted: 2007-06-24T09:00:45-07:00
by magick
The source distribution includes a wand/wandtest.c source module that illustrates accessing pixels:

Code: Select all

  (void) fprintf(stdout,"Utilitize pixel iterator to draw diagonal...\n");
  iterator=NewPixelIterator(magick_wand);
  if (iterator == (PixelIterator *) NULL)
    ThrowAPIException(magick_wand);
  pixels=PixelGetNextIteratorRow(iterator,&number_wands);
  for (i=0; pixels != (PixelWand **) NULL; i++)
  { 
    (void) PixelSetColor(pixels[i],"#224466");
    (void) PixelSyncIterator(iterator);
    pixels=PixelGetNextIteratorRow(iterator,&number_wands);
  }
  (void) PixelSyncIterator(iterator);
  iterator=DestroyPixelIterator(iterator);

Re: reading pixels from a ImageMagik image?

Posted: 2007-07-01T21:06:10-07:00
by anthony
Can this be put into the 'wand' documentation please.

Re: reading pixels from a ImageMagik image?

Posted: 2007-07-06T14:09:49-07:00
by zacwitte
OK, that code helped a good deal. Examples, I think, are very important in the documentation of an API. It would be really nice if someone mentioned the existence of wanttest.c on the MagickWand API main page and hopefully adds some comments to the actual wandtest.c file.

I'm having some more problems though. I'm trying to read in the pixels values of a greyscale pgm file, which has intensities from 0 to 255 into an array. So I assume PixelGetBlack() would be the correct function for that, but all I get are values of 0. I also tried PixelGetAlpha, but predictably, all I got were values of 1 since the image contains no transparency.

Some other strange phenomenon is that I get random values for the last 18 pixels. (I'm working with 19x19 images) Which is probably due to a simple coding error on my part. The values are always the same every time I run it, regardless of what image file I'm loading.

This is the values of the last 18 elements in my imagepixels[] array as output by printf.

Code: Select all

-0.000000 
0.000000 
-0.000000 
0.000000 
-0.000000 
-0.000000 
-1.998543 
-1.998536 
-0.000000 
0.000000 
-0.000000 
-1.998536 
-0.000000 
0.000000 
0.000000 
919596694055811559401113095282899304729954696342536204743465047440244947124341404649235703820709968908496688687896667912706581481511944562763882660979899035755352187469824.000000 
0.000000 
-0.000000 

Here's the full code:

Code: Select all

#include <wand/MagickWand.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
	MagickBooleanType status;
	
	MagickWand *magick_wand;
	
	MagickWandGenesis();
	magick_wand = NewMagickWand();
	
	status = MagickReadImage(magick_wand, "train-face/cmu_0301.pgm");
	
	if (status == MagickFalse) {
		printf("Error reading image\n");
	}
	else {
		printf("w00t\n");
	}
	
	//char imagepixels[19*19][10];
	double imagepixels[19*19];
	int i=0, j=0;
	
	printf("Utilitize pixel iterator to draw diagonal...\n");
	PixelIterator* iterator = NewPixelIterator(magick_wand);
	//if (iterator == (PixelIterator *) NULL) {
		//ThrowAPIException(magick_wand);
	//}
	
	//this will store the number of pixels in each row
	unsigned long number_wands; 
	
	PixelWand **pixels = PixelGetNextIteratorRow(iterator,&number_wands);
	for (i=0; pixels != (PixelWand **) NULL; i++)
	{
		printf("Number of pixels in this row: %lu \n", number_wands);
		PixelSetColor(pixels[i],"#224466");
		
		//read all the pixels for this row into our own array
		for (j=0; j<number_wands; j++){
			//strcpy(imagepixels[i*(number_wands-1) + j], PixelGetColorAsString(pixels[i]));
			imagepixels[i*(number_wands-1) + j] = PixelGetAlpha(pixels[i]);
		}
		
		PixelSyncIterator(iterator);
		pixels=PixelGetNextIteratorRow(iterator,&number_wands);
 	}
	PixelSyncIterator(iterator);
	iterator=DestroyPixelIterator(iterator);
	
	//write back out to png
	status = MagickWriteImages(magick_wand, "w00tness.png", MagickTrue);
	if (status == MagickFalse) {
		printf("Error writing to png\n");
	}
	else {
		printf("still w00tness!!\n");
	}
	
	for (j=0; j<361; j++) {
		printf("%lf \n", imagepixels[j]);
		//if (j+1 % 19 == 0)
		//	printf("\n");
	}
	
	magick_wand = DestroyMagickWand(magick_wand);
	MagickWandTerminus();
	
	return 0;
}

Re: reading pixels from a ImageMagik image?

Posted: 2007-07-06T19:18:24-07:00
by magick
We added an example using MagickWand to get and set pixels to the ImageMagick web site (allow 24 hours for the update to mirror). Unfortunately it requires ImageMagick 6.3.5-1 Beta (release date in about a week).

Re: reading pixels from a ImageMagik image?

Posted: 2007-07-06T19:31:48-07:00
by el_supremo
So I assume PixelGetBlack() would be the correct function for that
What you need is PixelGetRed() (or Green() or Blue() since each pixel should have equal R, G and B values).

[EDIT]: I thought you meant your image was already grayscale but perhaps it is colour and you want the grayscale value. If you get the red, green and blue values you could use intensity = sqrt(r*r+g*g+b*b)

Pete

Re: reading pixels from a ImageMagik image?

Posted: 2007-07-07T07:36:53-07:00
by zacwitte
pgm files are only greyscale intensity. Pixel values just range between 0 and 255. If I use PixelGetBlue then 0.400000 is returned for each pixel. Red is 0.13333333 and Green is 0.2777777.

Re: reading pixels from a ImageMagik image?

Posted: 2007-07-07T09:15:17-07:00
by magick
Programmer error. Use 255.0*GetPixelRed(pixels[j]). Note the j rather than the i.

Re: reading pixels from a ImageMagik image?

Posted: 2007-07-07T10:24:54-07:00
by el_supremo
Two programmer errors methinks. This:

Code: Select all

imagepixels[i*(number_wands-1) + j] = PixelGetAlpha(pixels[i]);
should be this:

Code: Select all

imagepixels[i*number_wands + j] = PixelGetAlpha(pixels[j]);

Pete