Leptonica 1.68
C Image Processing Library

otsutest1.c

Go to the documentation of this file.
00001 /*====================================================================*
00002  -  Copyright (C) 2001 Leptonica.  All rights reserved.
00003  -  This software is distributed in the hope that it will be
00004  -  useful, but with NO WARRANTY OF ANY KIND.
00005  -  No author or distributor accepts responsibility to anyone for the
00006  -  consequences of using this software, or for whether it serves any
00007  -  particular purpose or works at all, unless he or she says so in
00008  -  writing.  Everyone is granted permission to copy, modify and
00009  -  redistribute this source code, for commercial or non-commercial
00010  -  purposes, with the following restrictions: (1) the origin of this
00011  -  source code must not be misrepresented; (2) modified versions must
00012  -  be plainly marked as such; and (3) this notice may not be removed
00013  -  or altered from any source or modified source distribution.
00014  *====================================================================*/
00015 
00016 /*
00017  *   otsutest1.c
00018  */
00019 
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <math.h>
00023 #include "allheaders.h"
00024 
00025 static const l_int32 NTests = 5;
00026 static const l_int32 gaussmean1[5] = {20, 40, 60, 80, 60};
00027 static const l_int32 gaussstdev1[5] = {10, 20, 20, 20, 30};
00028 static const l_int32 gaussmean2[5] = {220, 200, 140, 180, 150};
00029 static const l_int32 gaussstdev2[5] = {15, 20, 40, 20, 30};
00030 static const l_float32 gaussfract1[5] = {0.2, 0.3, 0.1, 0.5, 0.3};
00031 static char  buf[256];
00032 
00033 static l_int32  GenerateSplitPlot(l_int32 i);
00034 static NUMA *MakeGaussian(l_int32 mean, l_int32 stdev, l_float32 fract);
00035 
00036 
00037 
00038 main(int    argc,
00039      char **argv)
00040 {
00041 l_int32  i;
00042 PIX     *pix;
00043 PIXA    *pixa;
00044 
00045     for (i = 0; i < NTests; i++)
00046         GenerateSplitPlot(i);
00047 
00048        /* Read the results back in ...  */
00049     pixa = pixaCreate(0);
00050     for (i = 0; i < NTests; i++) {
00051         sprintf(buf, "/tmp/junkplot.%d.png", i);
00052         pix = pixRead(buf);
00053         pixSaveTiled(pix, pixa, 1, 1, 25, 32);
00054         pixDestroy(&pix);
00055         sprintf(buf, "/tmp/junkplots.%d.png", i);
00056         pix = pixRead(buf);
00057         pixSaveTiled(pix, pixa, 1, 0, 25, 32);
00058         pixDestroy(&pix);
00059     }
00060 
00061         /* ... and save into a tiled pix  */
00062     pix = pixaDisplay(pixa, 0, 0);
00063     pixWrite("/tmp/junkotsuplot.png", pix, IFF_PNG);
00064     pixDisplay(pix, 100, 100);
00065     pixaDestroy(&pixa);
00066     pixDestroy(&pix);
00067     return 0;
00068 }
00069 
00070 
00071 static l_int32
00072 GenerateSplitPlot(l_int32  i)
00073 {
00074 char       title[256];
00075 l_int32    split;
00076 l_float32  ave1, ave2, num1, num2, maxnum, maxscore;
00077 GPLOT     *gplot;
00078 NUMA      *na1, *na2, *nascore, *nax, *nay;
00079 PIX       *pixs, *pixd;
00080 
00081         /* Generate */
00082     na1 = MakeGaussian(gaussmean1[i], gaussstdev1[i], gaussfract1[i]);
00083     na2 = MakeGaussian(gaussmean2[i], gaussstdev1[i], 1.0 - gaussfract1[i]);
00084     numaArithOp(na1, na1, na2, L_ARITH_ADD);
00085 
00086         /* Otsu splitting */
00087     numaSplitDistribution(na1, 0.08, &split, &ave1, &ave2, &num1, &num2,
00088                           &nascore);
00089     fprintf(stderr, "split = %d, ave1 = %6.1f, ave2 = %6.1f\n",
00090             split, ave1, ave2);
00091     fprintf(stderr, "num1 = %8.0f, num2 = %8.0f\n", num1, num2);
00092 
00093         /* Prepare for plotting a vertical line at the split point */
00094     nax = numaMakeConstant(split, 2);
00095     numaGetMax(na1, &maxnum, NULL);
00096     nay = numaMakeConstant(0, 2);
00097     numaReplaceNumber(nay, 1, (l_int32)(0.5 * maxnum));
00098 
00099         /* Plot the input histogram with the split location */
00100     sprintf(buf, "/tmp/junkplot.%d", i);
00101     sprintf(title, "Plot %d", i);
00102     gplot = gplotCreate(buf, GPLOT_PNG,
00103                         "Histogram: mixture of 2 gaussians",
00104                         "Grayscale value", "Number of pixels");
00105     gplotAddPlot(gplot, NULL, na1, GPLOT_LINES, title);
00106     gplotAddPlot(gplot, nax, nay, GPLOT_LINES, NULL);
00107     gplotMakeOutput(gplot);
00108     gplotDestroy(&gplot);
00109     numaDestroy(&na1);
00110     numaDestroy(&na2);
00111 
00112         /* Plot the score function */
00113     sprintf(buf, "/tmp/junkplots.%d", i);
00114     sprintf(title, "Plot %d", i);
00115     gplot = gplotCreate(buf, GPLOT_PNG,
00116                         "Otsu score function for splitting",
00117                         "Grayscale value", "Score");
00118     gplotAddPlot(gplot, NULL, nascore, GPLOT_LINES, title);
00119     numaGetMax(nascore, &maxscore, NULL);
00120     numaReplaceNumber(nay, 1, maxscore);
00121     gplotAddPlot(gplot, nax, nay, GPLOT_LINES, NULL);
00122     gplotMakeOutput(gplot);
00123     gplotDestroy(&gplot);
00124     numaDestroy(&nax);
00125     numaDestroy(&nay);
00126     numaDestroy(&nascore);
00127     return 0;
00128 }
00129 
00130 
00131 static NUMA *
00132 MakeGaussian(l_int32 mean, l_int32 stdev, l_float32 fract)
00133 {
00134 l_int32    i, total;
00135 l_float32  norm, val;
00136 NUMA      *na;
00137 
00138     na = numaMakeConstant(0.0, 256);
00139     norm = fract / ((l_float32)stdev * sqrt(2 * 3.14159));
00140     total = 0;
00141     for (i = 0; i < 256; i++) {
00142         val = norm * 1000000. * exp(-(l_float32)((i - mean) * (i - mean)) /
00143                                       (l_float32)(2 * stdev * stdev));
00144         total += (l_int32)val;
00145         numaSetValue(na, i, val);
00146     }
00147     fprintf(stderr, "Total = %d\n", total);
00148 
00149     return na;
00150 }
00151 
00152 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines