Page 1 of 1

Strange result of MagickGetImageChannelRange

Posted: 2012-02-01T09:15:20-07:00
by jrrose
With 'identify -verbose file' I can show minmal and maximal pixel values, e.g.

rose@moose:/home_moose/rose/Txt/src/Test/C/ImageMagick/Wand(203)$ identify -verbose lena.png
...
Colorspace: RGB
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Red:
min: 38 (0.14902)
max: 255 (1)
mean: 179.987 (0.705832)
standard deviation: 49.3533 (0.193542)
kurtosis: -0.777526
skewness: -0.690397
Green:
min: 0 (0)
max: 243 (0.952941)
mean: 99.4344 (0.389939)
standard deviation: 52.5844 (0.206213)
kurtosis: -0.740379
skewness: 0.219766
Blue:
min: 9 (0.0352941)
max: 234 (0.917647)
mean: 105.311 (0.412985)
standard deviation: 34.1127 (0.133775)
kurtosis: -0.15
skewness: 0.622583
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 128.244 (0.502919)
standard deviation: 46.0599 (0.180627)
kurtosis: 2.6211
skewness: 0.461482
...

I try to get the same information with a small MagickWand program (getChannelRange.c):

Code: Select all

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

int main(int argc,char **argv) {

#define ThrowWandException(wand) { \
		description=MagickGetException(wand,&severity);											\
		(void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
		description=(char *) MagickRelinquishMemory(description);						\
		exit(-1);																														\
	}

  char *description;
  ExceptionType severity;
  MagickBooleanType status;

  /*
    Read an image.
  */
  MagickWandGenesis();
	MagickWand *wand=NewMagickWand();
  status=MagickReadImage(wand,argv[1]);
  if (status == MagickFalse) ThrowWandException(wand);

	double minimum, maximum;

	fprintf(stderr,"RedChannel=%d\n",RedChannel);
	fprintf(stderr,"GreenChannel=%d\n",GreenChannel);
	fprintf(stderr,"BlueChannel=%d\n",BlueChannel);

	MagickGetImageChannelRange(wand,RedChannel,&minimum,&maximum);
	fprintf(stderr,"	  after 'GetImageChannelRange(,RedChannel,)  '   minimum=%13.1f  maximum=%13.1f\n",minimum,maximum);

	MagickGetImageChannelRange(wand,GreenChannel,&minimum,&maximum);
	fprintf(stderr,"	  after 'GetImageChannelRange(,GreenChannel,)'   minimum=%13.1f  maximum=%13.1f\n",minimum,maximum);

	MagickGetImageChannelRange(wand,BlueChannel,&minimum,&maximum);
	fprintf(stderr,"	  after 'GetImageChannelRange(,BlueChannel,) '   minimum=%13.1f  maximum=%13.1f\n",minimum,maximum);

	MagickGetImageChannelRange(wand,GrayChannel,&minimum,&maximum);
	fprintf(stderr,"	  after 'GetImageChannelRange(,GrayChannel,) '   minimum=%13.1f  maximum=%13.1f\n",minimum,maximum);
  wand=DestroyMagickWand(wand);
  MagickWandTerminus();
  return(0);
}
The result of this program is:

rose@moose:/home_moose/rose/Txt/src/Test/C/ImageMagick/Wand(204)$ ./getChannelRange lena.png
RedChannel=1
GreenChannel=2
BlueChannel=4
after 'GetImageChannelRange(,RedChannel,) ' minimum= 640034368.0 maximum= 4294967296.0
after 'GetImageChannelRange(,GreenChannel,)' minimum= 0.0 maximum= 4092851200.0
after 'GetImageChannelRange(,BlueChannel,) ' minimum= 151587088.0 maximum= 3941264128.0
after 'GetImageChannelRange(,GrayChannel,) ' minimum= 640034368.0 maximum= 4294967296.0

I.e. the resulting values are about a factor of 16843009.5... too large. What I am doing wrong. Any hint is deeply appreciated.

Re: Strange result of MagickGetImageChannelRange

Posted: 2012-02-01T12:13:07-07:00
by jrrose
I assume, that I found the solution:

Code: Select all

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

int main(int argc,char **argv) {

#define ThrowWandException(wand) { \
		description=MagickGetException(wand,&severity);\
		(void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
		description=(char *) MagickRelinquishMemory(description);	\
		exit(-1);	\
	}

  char *description;
  ExceptionType severity;
  MagickBooleanType status;

  /*
    Read an image.
  */
  MagickWandGenesis();
	MagickWand *wand=NewMagickWand();
  status=MagickReadImage(wand,argv[1]);
  if (status == MagickFalse) ThrowWandException(wand);

  double minimum, maximum;
  size_t IM_quantum_depth;
  const char *IM_quantum_depth_str=GetMagickQuantumDepth(&IM_quantum_depth);
  size_t img_depth=MagickGetImageDepth(wand);
  const char *quantum_format=MagickGetImageProperty(wand,"quantum:format");
  fprintf(stderr,"IM_quantum_depth_str=|%s|  IM_quantum_depth=|%lu|  img_depth=%lu  quantum_format=|%s|\n",
             IM_quantum_depth_str,IM_quantum_depth,img_depth,quantum_format);

  fprintf(stderr,"RedChannel=%d\n",RedChannel);
  printf(stderr,"GreenChannel=%d\n",GreenChannel);
  fprintf(stderr,"BlueChannel=%d\n",BlueChannel);

  long long unsigned max_IM_val=1ULL<<IM_quantum_depth;
  long long unsigned max_img_val=(1ULL<<img_depth)-1;

  MagickGetImageChannelRange(wand,RedChannel,&minimum,&maximum);
  fprintf(stderr,"	  after 'GetImageChannelRange(,RedChannel,)  '   minimum=%13.1lf(%5.3lf)  maximum=%13.1lf(%5.3lf)\n",
             max_img_val*minimum/max_IM_val,minimum/max_IM_val,max_img_val*maximum/max_IM_val,maximum/max_IM_val);

  MagickGetImageChannelRange(wand,GreenChannel,&minimum,&maximum);
  fprintf(stderr,"	  after 'GetImageChannelRange(,GreenChannel,)'   minimum=%13.1lf(%5.3lf)  maximum=%13.1lf(%5.3lf)\n",
             max_img_val*minimum/max_IM_val,minimum/max_IM_val,max_img_val*maximum/max_IM_val,maximum/max_IM_val);

  MagickGetImageChannelRange(wand,BlueChannel,&minimum,&maximum);
  fprintf(stderr,"	  after 'GetImageChannelRange(,BlueChannel,) '   minimum=%13.1lf(%5.3lf)  maximum=%13.1lf(%5.3lf)\n",
            max_img_val*minimum/max_IM_val,minimum/max_IM_val,max_img_val*maximum/max_IM_val,maximum/max_IM_val);

  MagickGetImageChannelRange(wand,GrayChannel,&minimum,&maximum);
  fprintf(stderr,"	  after 'GetImageChannelRange(,GrayChannel,) '   minimum=%13.1lf(%5.3lf)  maximum=%13.1lf(%5.3lf)\n",
             max_img_val*minimum/max_IM_val,minimum/max_IM_val,max_img_val*maximum/max_IM_val,maximum/max_IM_val);

  wand=DestroyMagickWand(wand);
  MagickWandTerminus();
  return(0);
}

Re: Strange result of MagickGetImageChannelRange

Posted: 2012-02-01T12:16:33-07:00
by jrrose
The result is now:

rose@moose:/home_moose/rose/Txt/src/Test/C/ImageMagick/Wand(268)$ ./getChannelRange lena.png
IM_quantum_depth_str=|Q32| IM_quantum_depth=|32| img_depth=8 quantum_format=|(null)|
RedChannel=1
GreenChannel=2
BlueChannel=4
after 'GetImageChannelRange(,RedChannel,) ' minimum= 38.0(0.149) maximum= 255.0(1.000)
after 'GetImageChannelRange(,GreenChannel,)' minimum= 0.0(0.000) maximum= 243.0(0.953)
after 'GetImageChannelRange(,BlueChannel,) ' minimum= 9.0(0.035) maximum= 234.0(0.918)
after 'GetImageChannelRange(,GrayChannel,) ' minimum= 38.0(0.149) maximum= 255.0(1.000)


So the values are as expected. But I am not yet completely convinced, that this procedure will work for all all kind of images, i.e. for all kind of image formats, image depth and quantum formats.