Bitmap/Histogram: Difference between revisions
(Vedit macro language added) |
No edit summary |
||
Line 13: | Line 13: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
Histogram of an image: |
Histogram of an image: |
||
<ada> |
<lang ada> |
||
type Pixel_Count is mod 2**64; |
type Pixel_Count is mod 2**64; |
||
type Histogram is array (Luminance) of Pixel_Count; |
type Histogram is array (Luminance) of Pixel_Count; |
||
Line 31: | Line 31: | ||
return Result; |
return Result; |
||
end Get_Histogram; |
end Get_Histogram; |
||
</ |
</lang> |
||
Median of a histogram: |
Median of a histogram: |
||
<ada> |
<lang ada> |
||
function Median (H : Histogram) return Luminance is |
function Median (H : Histogram) return Luminance is |
||
From : Luminance := Luminance'First; |
From : Luminance := Luminance'First; |
||
Line 51: | Line 51: | ||
return From; |
return From; |
||
end Median; |
end Median; |
||
</ |
</lang> |
||
Conversion of an image to black and white art: |
Conversion of an image to black and white art: |
||
<ada> |
<lang ada> |
||
F1, F2 : File_Type; |
F1, F2 : File_Type; |
||
begin |
begin |
||
Line 76: | Line 76: | ||
end; |
end; |
||
Close (F2); |
Close (F2); |
||
</ |
</lang> |
||
=={{header|C}}== |
=={{header|C}}== |
||
<c>typedef unsigned int histogram_t; |
<lang c>typedef unsigned int histogram_t; |
||
typedef histogram_t *histogram;</ |
typedef histogram_t *histogram;</lang> |
||
<c>#define GET_LUM(IMG, X, Y) ( (IMG)->buf[ (Y) * (IMG)->width + (X)][0] ) |
<lang c>#define GET_LUM(IMG, X, Y) ( (IMG)->buf[ (Y) * (IMG)->width + (X)][0] ) |
||
histogram get_histogram(grayimage im) |
histogram get_histogram(grayimage im) |
||
Line 104: | Line 104: | ||
} |
} |
||
return t; |
return t; |
||
}</ |
}</lang> |
||
The given <tt>histogram</tt> must be freed with a simple <tt>free(histogram)</tt>. |
The given <tt>histogram</tt> must be freed with a simple <tt>free(histogram)</tt>. |
||
Line 110: | Line 110: | ||
{{trans|Ada}} |
{{trans|Ada}} |
||
<c>luminance histogram_median(histogram h) |
<lang c>luminance histogram_median(histogram h) |
||
{ |
{ |
||
luminance From, To; |
luminance From, To; |
||
Line 128: | Line 128: | ||
} |
} |
||
return From; |
return From; |
||
}</ |
}</lang> |
||
An example of usage is the following code. |
An example of usage is the following code. |
||
<c>#include <stdio.h> |
<lang c>#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
/* #include "imglib.h" */ |
/* #include "imglib.h" */ |
||
Line 182: | Line 182: | ||
free_img(color_img); |
free_img(color_img); |
||
} |
} |
||
</ |
</lang> |
||
Which reads from the file specified from the command line and outputs to the standard out the PPM B/W version of the input image. The input image can be of any format handled by ImageMagick (see [[Read image file through a pipe]]) |
Which reads from the file specified from the command line and outputs to the standard out the PPM B/W version of the input image. The input image can be of any format handled by ImageMagick (see [[Read image file through a pipe]]) |
Revision as of 15:36, 3 February 2009
You are encouraged to solve this task according to the task description, using any language you may know.
Extend the basic bitmap storage defined on this page to support dealing with image histograms. The image histogram contains for each luminance the count of image pixels having this luminance. Choosing a histogram representation take care about the data type used for the counts. It must have range of at least 0..NxM, where N is the image width and M is the image height.
Test task
Histogram is useful for many image processing operations. As an example, use it to convert an image into black and white art. The method works as follows:
- Convert image to grayscale;
- Compute the histogram
- Find the median of. The median is defined as the luminance such that the image has an approximately equal number of pixels with lesser and greater luminance.
- Replace each pixel of luminance lesser than the median to black, and others to white.
Use read/write ppm file, and grayscale image solutions.
Ada
Histogram of an image: <lang ada> type Pixel_Count is mod 2**64; type Histogram is array (Luminance) of Pixel_Count;
function Get_Histogram (Picture : Grayscale_Image) return Histogram is
Result : Histogram := (others => 0);
begin
for I in Picture'Range (1) loop for J in Picture'Range (2) loop declare Count : Pixel_Count renames Result (Picture (I, J)); begin Count := Count + 1; end; end loop; end loop; return Result;
end Get_Histogram; </lang> Median of a histogram: <lang ada> function Median (H : Histogram) return Luminance is
From : Luminance := Luminance'First; To : Luminance := Luminance'Last; Left : Pixel_Count := H (From); Right : Pixel_Count := H (To);
begin
while From /= To loop if Left < Right then From := From + 1; Left := Left + H (From); else To := To - 1; Right := Right + H (To); end if; end loop; return From;
end Median; </lang> Conversion of an image to black and white art: <lang ada>
F1, F2 : File_Type;
begin
Open (F1, In_File, "city.ppm"); declare X : Image := Get_PPM (F1); Y : Grayscale_Image := Grayscale (X); T : Luminance := Median (Get_Histogram (Y)); begin Close (F1); Create (F2, Out_File, "city_art.ppm"); for I in Y'Range (1) loop for J in Y'Range (2) loop if Y (I, J) < T then X (I, J) := Black; else X (I, J) := White; end if; end loop; end loop; Put_PPM (F2, X); end; Close (F2);
</lang>
C
<lang c>typedef unsigned int histogram_t; typedef histogram_t *histogram;</lang>
<lang c>#define GET_LUM(IMG, X, Y) ( (IMG)->buf[ (Y) * (IMG)->width + (X)][0] )
histogram get_histogram(grayimage im) {
histogram t; unsigned int x, y; if ( im == NULL ) return NULL; t = malloc( sizeof(histogram_t)*256 ); memset(t, 0, sizeof(histogram_t)*256 ); if (t!=NULL) { for(x=0; x < im->width; x++ ) { for(y=0; y < im->height; y++ ) { t[ GET_LUM(im, x, y) ]++; } } } return t;
}</lang>
The given histogram must be freed with a simple free(histogram).
<lang c>luminance histogram_median(histogram h) {
luminance From, To; unsigned int Left, Right; From = 0; To = (1 << (8*sizeof(luminance)))-1; Left = h[From]; Right = h[To]; while( From != To ) { if ( Left < Right ) { From++; Left += h[From]; } else { To--; Right += h[To]; } } return From;
}</lang>
An example of usage is the following code.
<lang c>#include <stdio.h>
- include <stdlib.h>
/* #include "imglib.h" */
/* usage example */
- define BLACK 0,0,0
- define WHITE 255,255,255
int main(int argc, char **argv) {
image color_img; grayimage g_img; histogram h; luminance T; unsigned int x, y; if ( argc < 2 ) { fprintf(stderr, "histogram FILE\n"); exit(1); } color_img = read_image(argv[1]); if ( color_img == NULL ) exit(1); g_img = tograyscale(color_img); h = get_histogram(g_img); if ( h != NULL ) { T = histogram_median(h); for(x=0; x < g_img->width; x++) { for(y=0; y < g_img->height; y++) { if ( GET_LUM(g_img,x,y) < T ) { put_pixel_unsafe(color_img, x, y, BLACK); } else { put_pixel_unsafe(color_img, x, y, WHITE); } } } output_ppm(stdout, color_img); /* print_jpg(color_img, 90); */ free(h); } free_img((image)g_img); free_img(color_img);
} </lang>
Which reads from the file specified from the command line and outputs to the standard out the PPM B/W version of the input image. The input image can be of any format handled by ImageMagick (see Read image file through a pipe)
Forth
: histogram ( array gmp -- ) over 256 cells erase dup bdim * over bdata + swap bdata do 1 over i c@ cells + +! loop drop ;
Vedit macro language
The input image is in edit buffer pointed by numeric register #15. On return, #30 points to buffer containing histogram data. The histogram data is given as ASCII decimal values, one value per line.
:HISTOGRAM: #30 = Buf_Free // #30 = buffer to store histogram data for (#9=0; #9<256; #9++) { Out_Reg(21) TC(#9) Out_Reg(Clear) // @21 = intensity value to be counted Buf_Switch(#15) // switch to image buffer #8 = Search(@21, CASE+BEGIN+ALL+NOERR) // count intensity values Buf_Switch(#30) // switch to histogram buffer Num_Ins(#8, FILL) // store count } Return