I have a batch of thousand bmp images that are labelled in sequence (file name followed by a number). I need to make a 3D histogram for all these images combined and then do statistical analysis on this. By 3D histogram, I mean the histogram corresponding to each image in the batch all stacked together to form a surface plot. Any advice would be appreciated.
You are really not providing sufficient and precise detail of what you need to do.
First, are your images grayscale or color? Normal bmp images load as RGB waves so you need to take some extra steps if your data are only grayscale. What histogram exactly are you interested in: a global histogram for the full image or a per-pixel histogram of the distribution among images?
Thanks for your reply. My images are in color (Rainbow). They were originally grayscale bmp (0 -> 255). Converted the images to color (specifically Rainbow).
The histogram for each image I am talking about is a plot of frequency (y-axis), vs grayscale value(0 -> 255) on the x-axis.
Thanks again for your help. Any advice appreciated.
To add to my reply, the final histogram I am looking for is a combination of the histogram type I described for each image, stacked along the z-axis (coming out of the page), looking like a surface plot.
If I understood you correctly then I'd use the following steps:
1. Find out how many images you plan to process, say N.
2. Create an output wave:
Make/O/N=(256,N) outHist
3. Loop through the images and for each image:
3.1 convert to grayscale. This is wasteful and unfortunate that you changed your images but...
ImageTransform RGB2Gray imageWave
3.2 histogram the gray image:
ImageHistogram M_RGB2Gray
3.3 store the histogram of image (i) in the output wave:
outHist[][i]=W_ImageHist[p]
4. display an image or a Gizmo plot of the wave outHist.
I was trying to implement your program but ran into the following challenges:
What is the function W_Histogram? What is the variable p in the line "outHist[][i]=W_ImageHist[p]" ?
To make it easier, I will explain my problem as it is. I have a thousand .bmp files named as follows:
(Morning_Tuesday_0001, Morning_Tuesday_0002, Morning_Tuesday_0003,.......................................................................... Morning_Tuesday_1000) all under the folder "Morning_Tuesday"
These are the images I need to convert into grayscale frequency vs grayscale histograms and then combine them into a combined 3D histogram with Grayscale frequency, grayscale, image no. representing the three axes.
I understand in your procedure you want me to define an output wave and to store each histogram in it as it is created and use Gizmo to do a combined plot. I think the procedure is perfect for my problem, except I need to figure the answers to the first two questions I have asked you, else Igor will not compile.
Still having problems! The problem may be with the way I am implementing W_Histogram and the Output Wave function. Here's the code I have written so far. It picks up the files(.bmp images) named "LiC44M006__rec000, LiC44M006__rec001....................................LiC44M006__rec700 " from the folder "LiC44M006 ", i.e, "loads" them, makes a histogram and stacks up frames to make a movie. I need to modify this (remove the movie function, add the out put wave and put each histogram created in every iteration of the loop into the output wave. As before, I am getting the 'p' and the 'i' wrong everytime I include the W_Histogram function & Output Wave. Need help. Here's the code:
#pragma rtGlobals=1 // Use modern global access method.
Function LoadThis(start, final)
Variable start, final
String Test = ""
NewMovie
Do
if ((start < 10) && (start>=0))
Test = "LiC44M006__rec000" + num2str(start) +".bmp"
endif
if ((start < 100) && (start>10))
Test = "LiC44M006__rec00" + num2str(start) +".bmp"
endif
if ((start < 1000) && (start>100))
Test = "LiC44M006__rec0" + num2str(start) +".bmp"
endif
if ((start < 10000) && (start>1000))
Test = "LiC44M006__rec" + num2str(start) +".bmp"
endif
ImageLoad/q/p=home/T=bmp/O/N=image0 Test
Redimension/N=(-1,-1) image0
Histogram/B={0,1,256} image0,image0_Hist
DoUpdate
AddMovieFrame
start +=1
While (start <= final)
closemovie
End
I apologize for the misinformation in my reply above. W_Histogram is not automatically created by the Histogram operation. You must create the histogram output wave. I made a few changes to your code to collect the histograms in the columns of a wave called wOutput. wOutput should have as many rows as there are bins in the histogram and as many columns as there are files to be processed. I haven't tested this code so bewary of additional mistakes on my part.
#pragma rtGlobals=1// Use modern global access method.
Function LoadThis(start, final) Variable start, final String Test = "" NewMovie Make image0_Hist //contains histogram, size and scaling will be controlled by /B flag in Histogram operation Make/N=(256, 1000) wOutput //collects all histograms, rows = # of histogram bins, cols = number of images Do if((start <10)&&(start>=0))
Test = "LiC44M006__rec000" + num2str(start) +".bmp" endif if((start <100)&&(start>10))
Test = "LiC44M006__rec00" + num2str(start) +".bmp" endif if((start <1000)&&(start>100))
Test = "LiC44M006__rec0" + num2str(start) +".bmp" endif if((start <10000)&&(start>1000))
Test = "LiC44M006__rec" + num2str(start) +".bmp" endif ImageLoad/q/p=home/T=bmp/O/N=image0 Test Redimension/N=(-1,-1) image0 Histogram/B={0,1,256} image0,image0_Hist
wOutput[][start] = image0_Hist[p]//copy new histogram to output wave DoUpdate AddMovieFrame
start +=1 While(start <= final) closemovie End
While compiling, it highlights 1000 in the WOutput line in the beginning. This refers to the total number of images. I think the problem is that the way the program is written, it would pick up how many ever images there are in the parent folder, so the total number of images cannot be predefined.
Any solution? I tried to use the variable 'start' in place of 1000, but it does not accept.
Sorry, my error. The line Make N=(256, 1000) wOutput should be written Make /N=(256, 1000) wOutput. It needs a forward slash just before the "N". I have edited this in the original post.
As for getting the proper value for the number of columns, it depends on how often you will use this function. The easiest may be to visually inspect the directory to determine the number and enter it as an input parameter to the function such as
Function LoadThis(start, final, numfiles) Variable start, final, numfiles String Test = "" NewMovie Make image0_Hist //contains histogram, size and scaling will be controlled by /B flag in Histogram operation Make/N=(256, numfiles) wOutput //collects all histograms, rows = # of histogram bins, cols = number of images
There are other means to this end as well. For example, take a look at IndexedFile in the command help. You could combine this with a loop to enumerate the number of files to be loaded.
If you haven't done it already, you should take a spin through the tutorial. Enter displayhelptopic "Getting Started" on the command line.
First, are your images grayscale or color? Normal bmp images load as RGB waves so you need to take some extra steps if your data are only grayscale. What histogram exactly are you interested in: a global histogram for the full image or a per-pixel histogram of the distribution among images?
A.G.
WaveMetrics, Inc.
May 11, 2012 at 09:52 am - Permalink
Thanks for your reply. My images are in color (Rainbow). They were originally grayscale bmp (0 -> 255). Converted the images to color (specifically Rainbow).
The histogram for each image I am talking about is a plot of frequency (y-axis), vs grayscale value(0 -> 255) on the x-axis.
Thanks again for your help. Any advice appreciated.
Regards
May 11, 2012 at 08:30 pm - Permalink
May 11, 2012 at 09:09 pm - Permalink
1. Find out how many images you plan to process, say N.
2. Create an output wave:
Make/O/N=(256,N) outHist
3. Loop through the images and for each image:
3.1 convert to grayscale. This is wasteful and unfortunate that you changed your images but...
ImageTransform RGB2Gray imageWave
3.2 histogram the gray image:
ImageHistogram M_RGB2Gray
3.3 store the histogram of image (i) in the output wave:
outHist[][i]=W_ImageHist[p]
4. display an image or a Gizmo plot of the wave outHist.
I hope this helps,
A.G.
WaveMetrics, Inc.
May 13, 2012 at 08:26 am - Permalink
Regards.
May 13, 2012 at 09:09 am - Permalink
I was trying to implement your program but ran into the following challenges:
What is the function W_Histogram? What is the variable p in the line "outHist[][i]=W_ImageHist[p]" ?
To make it easier, I will explain my problem as it is. I have a thousand .bmp files named as follows:
(Morning_Tuesday_0001, Morning_Tuesday_0002, Morning_Tuesday_0003,.......................................................................... Morning_Tuesday_1000) all under the folder "Morning_Tuesday"
These are the images I need to convert into grayscale frequency vs grayscale histograms and then combine them into a combined 3D histogram with Grayscale frequency, grayscale, image no. representing the three axes.
I understand in your procedure you want me to define an output wave and to store each histogram in it as it is created and use Gizmo to do a combined plot. I think the procedure is perfect for my problem, except I need to figure the answers to the first two questions I have asked you, else Igor will not compile.
Thanks again for your continuing help.
Regards.
May 13, 2012 at 03:43 pm - Permalink
W_Histogram is an output wave containing the histogram. It is automatically created by the Histogram operaation.
The "p" variable is an index into outHist wave. Effectively the code executes outHist[p][i] = W_ImageHist[p].
So the elements of W_ImageHist are transferred into the ith column of outHist.
Hope this helps.
May 13, 2012 at 06:01 pm - Permalink
#pragma rtGlobals=1 // Use modern global access method.
Function LoadThis(start, final)
Variable start, final
String Test = ""
NewMovie
Do
if ((start < 10) && (start>=0))
Test = "LiC44M006__rec000" + num2str(start) +".bmp"
endif
if ((start < 100) && (start>10))
Test = "LiC44M006__rec00" + num2str(start) +".bmp"
endif
if ((start < 1000) && (start>100))
Test = "LiC44M006__rec0" + num2str(start) +".bmp"
endif
if ((start < 10000) && (start>1000))
Test = "LiC44M006__rec" + num2str(start) +".bmp"
endif
ImageLoad/q/p=home/T=bmp/O/N=image0 Test
Redimension/N=(-1,-1) image0
Histogram/B={0,1,256} image0,image0_Hist
DoUpdate
AddMovieFrame
start +=1
While (start <= final)
closemovie
End
May 17, 2012 at 06:17 am - Permalink
Function LoadThis(start, final)
Variable start, final
String Test = ""
NewMovie
Make image0_Hist //contains histogram, size and scaling will be controlled by /B flag in Histogram operation
Make /N=(256, 1000) wOutput //collects all histograms, rows = # of histogram bins, cols = number of images
Do
if ((start < 10) && (start>=0))
Test = "LiC44M006__rec000" + num2str(start) +".bmp"
endif
if ((start < 100) && (start>10))
Test = "LiC44M006__rec00" + num2str(start) +".bmp"
endif
if ((start < 1000) && (start>100))
Test = "LiC44M006__rec0" + num2str(start) +".bmp"
endif
if ((start < 10000) && (start>1000))
Test = "LiC44M006__rec" + num2str(start) +".bmp"
endif
ImageLoad/q/p=home/T=bmp/O/N=image0 Test
Redimension/N=(-1,-1) image0
Histogram/B={0,1,256} image0,image0_Hist
wOutput[][start] = image0_Hist[p] //copy new histogram to output wave
DoUpdate
AddMovieFrame
start +=1
While (start <= final)
closemovie
End
May 17, 2012 at 08:06 pm - Permalink
Any solution? I tried to use the variable 'start' in place of 1000, but it does not accept.
Regards
May 17, 2012 at 05:24 pm - Permalink
As for getting the proper value for the number of columns, it depends on how often you will use this function. The easiest may be to visually inspect the directory to determine the number and enter it as an input parameter to the function such as
Variable start, final, numfiles
String Test = ""
NewMovie
Make image0_Hist //contains histogram, size and scaling will be controlled by /B flag in Histogram operation
Make /N=(256, numfiles) wOutput //collects all histograms, rows = # of histogram bins, cols = number of images
There are other means to this end as well. For example, take a look at IndexedFile in the command help. You could combine this with a loop to enumerate the number of files to be loaded.
If you haven't done it already, you should take a spin through the tutorial. Enter displayhelptopic "Getting Started" on the command line.
May 17, 2012 at 08:05 pm - Permalink