Leptonica 1.68
C Image Processing Library
|
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