00001 /* ImLib3D 00002 * Copyright (c) 2001, ULP-IPB Strasbourg. 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or (at 00007 * your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 */ 00021 // #include<ImLib3D/Image3D.hpp> 00022 #include<ImLib3D/Threshold.hpp> 00023 // #include<ImLib3D/Display.hpp> 00024 // #include<ImLib3D/TestPatterns.hpp> 00025 // #include<ImLib3D/ConvenienceProcessors.hpp> 00026 00027 void 00028 IP3D::UniModalThreshold(const Image3Df& src, double& threshold, Mask3D* res) 00029 { 00030 int nbBins=500; 00031 00032 vector<float> values; 00033 values.reserve(src.GetNVoxels()); 00034 Image3Df::const_iteratorFastMasked p; 00035 for(p=src.begin();p!=src.end();++p){values.push_back(*p);} 00036 00037 ProbabilityDistribution dist; 00038 dist.SetWithSamples(values,nbBins); 00039 00040 // cout << "pos of max = " << max_element(bins.begin(), bins.end())-bins.begin() << endl; 00041 float max=dist.GetMax(); 00042 float a0=dist.GetMaxPos(); 00043 float a1, dummy; 00044 00045 dist.GetRange(dummy, a1); 00046 // cout << "Histogram range ["<<dummy<<":"<<a1<<"]"<<endl; 00047 // cout <<"max=" << max << " at pos=" << a0 << endl; 00048 00049 // y=b0+b1x is the slope for max histo value to max image value 00050 float b0, b1; 00051 b1=max/(a0-a1); 00052 b0=max-b1*a0; 00053 00054 // iterator it = max_element(bins.begin(), bins.end()); 00055 // vector<float> datas; 00056 // copy(bins.begin(), bins.end(), back_inserter(datas)); 00057 // Plot plot; 00058 // plot.SetStyle("lines"); 00059 // plot.PlotData(datas,dummy, a1); 00060 // plot.PlotSlope(b1, b0); 00061 00062 float maxdist=0; 00063 float maxdistindex=0; 00064 int startindex=(int)dist.BinNum(a0); 00065 // cout << "Start search index = " << startindex << endl; 00066 00067 // find biggest distance of histogram perpendicular on the slope (b0,b1) 00068 for (int i=startindex; i<dist.GetNBins();i++) 00069 { 00070 float distance = (b1*dist.BinValue(i)+b0-dist[i]); 00071 if (distance>maxdist) 00072 { 00073 maxdist=distance; 00074 maxdistindex=i; 00075 } 00076 } 00077 00078 // cout << "Found Threshold : " << dist.BinValue(maxdistindex) << endl; 00079 threshold=dist.BinValue((int)maxdistindex); 00080 if (res) 00081 IP3D::SimpleThreshold(src, (float)threshold, *res); 00082 }