├── .gitignore ├── BasicImageSegmentation.sln ├── BasicImageSegmentation ├── 1_11_s.bmp ├── BasicImageSegmentation.cpp ├── BasicImageSegmentation.vcxproj ├── BasicImageSegmentation.vcxproj.filters ├── ConfigReader.cpp ├── ConfigReader.h ├── EfficientGraphBased │ ├── ReadMe.md │ ├── disjoint-set.h │ ├── segment-graph.h │ ├── segment-image.cpp │ └── segment-image.h ├── GrabCutSegmentor.cpp ├── GrabCutSegmentor.h ├── GraphBasedSegmentor.cpp ├── GraphBasedSegmentor.h ├── MeanShift │ ├── Example.cpp │ ├── RAList.cpp │ ├── RAList.h │ ├── ReadMe.md │ ├── ms.cpp │ ├── ms.h │ ├── msImageProcessor.cpp │ ├── msImageProcessor.h │ ├── msSys.cpp │ ├── msSys.h │ ├── rlist.cpp │ ├── rlist.h │ └── tdef.h ├── MeanShiftSegmentor.cpp ├── MeanShiftSegmentor.h ├── OneCutSegmentor.cpp ├── OneCutSegmentor.h ├── SEEDS │ ├── README.txt │ ├── ReadMe.md │ ├── seeds2.cpp │ └── seeds2.h ├── SEEDSSegmentor.cpp ├── SEEDSSegmentor.h ├── SLIC │ ├── README.md │ ├── SLIC.cpp │ ├── SLIC.h │ └── SLICO.exe ├── SLICSegmentor.cpp ├── SLICSegmentor.h ├── Timer.h ├── config.ini ├── config_example.ini ├── lena.jpg ├── lena_big.jpg ├── multi-labelGraphCut │ ├── GCoptimization.cpp │ ├── GCoptimization.h │ ├── LinkedBlockList.cpp │ ├── LinkedBlockList.h │ ├── ReadMe.md │ ├── block.h │ ├── energy.h │ ├── graph.cpp │ ├── graph.h │ └── maxflow.cpp ├── segmentor.cpp └── segmentor.h ├── LICENSE ├── OpenCV_248_x86.props ├── OpenCV_248d_x86.props ├── README.md └── Release ├── 1_11_s.bmp ├── BasicImageSegmentation.exe ├── config.ini ├── lena.jpg ├── lena_big.jpg ├── opencv_core248.dll ├── opencv_highgui248.dll └── opencv_imgproc248.dll /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | .class 19 | 20 | # External tool builders 21 | .externalToolBuilders/ 22 | 23 | # Locally stored "Eclipse launch configurations" 24 | *.launch 25 | 26 | # CDT-specific 27 | .cproject 28 | 29 | # PDT-specific 30 | .buildpath 31 | 32 | 33 | ################# 34 | ## Visual Studio 35 | ################# 36 | 37 | ## Ignore Visual Studio temporary files, build results, and 38 | ## files generated by popular Visual Studio add-ons. 39 | 40 | # User-specific files 41 | *.suo 42 | *.user 43 | *.sln.docstates 44 | 45 | # Build results 46 | 47 | */[Dd]ebug/ 48 | */[Rr]elease/ 49 | x64/ 50 | build/ 51 | [Bb]in/ 52 | [Oo]bj/ 53 | 54 | # MSTest test Results 55 | [Tt]est[Rr]esult*/ 56 | [Bb]uild[Ll]og.* 57 | 58 | *_i.c 59 | *_p.c 60 | *.ilk 61 | *.meta 62 | *.obj 63 | *.pch 64 | *.pdb 65 | *.pgc 66 | *.pgd 67 | *.rsp 68 | *.sbr 69 | *.tlb 70 | *.tli 71 | *.tlh 72 | *.tmp 73 | *.tmp_proj 74 | *.log 75 | *.vspscc 76 | *.vssscc 77 | .builds 78 | *.pidb 79 | *.log 80 | *.scc 81 | 82 | # Visual C++ cache files 83 | ipch/ 84 | *.aps 85 | *.ncb 86 | *.opensdf 87 | *.sdf 88 | *.cachefile 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | 102 | # TeamCity is a build add-in 103 | _TeamCity* 104 | 105 | # DotCover is a Code Coverage Tool 106 | *.dotCover 107 | 108 | # NCrunch 109 | *.ncrunch* 110 | .*crunch*.local.xml 111 | 112 | # Installshield output folder 113 | [Ee]xpress/ 114 | 115 | # DocProject is a documentation generator add-in 116 | DocProject/buildhelp/ 117 | DocProject/Help/*.HxT 118 | DocProject/Help/*.HxC 119 | DocProject/Help/*.hhc 120 | DocProject/Help/*.hhk 121 | DocProject/Help/*.hhp 122 | DocProject/Help/Html2 123 | DocProject/Help/html 124 | 125 | # Click-Once directory 126 | publish/ 127 | 128 | # Publish Web Output 129 | *.Publish.xml 130 | *.pubxml 131 | 132 | # NuGet Packages Directory 133 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 134 | #packages/ 135 | 136 | # Windows Azure Build Output 137 | csx 138 | *.build.csdef 139 | 140 | # Windows Store app package directory 141 | AppPackages/ 142 | 143 | # Others 144 | sql/ 145 | *.Cache 146 | ClientBin/ 147 | [Ss]tyle[Cc]op.* 148 | ~$* 149 | *~ 150 | *.dbmdl 151 | *.[Pp]ublish.xml 152 | *.pfx 153 | *.publishsettings 154 | 155 | # RIA/Silverlight projects 156 | Generated_Code/ 157 | 158 | # Backup & report files from converting an old project file to a newer 159 | # Visual Studio version. Backup files are not needed, because we have git ;-) 160 | _UpgradeReport_Files/ 161 | Backup*/ 162 | UpgradeLog*.XML 163 | UpgradeLog*.htm 164 | 165 | # SQL Server files 166 | App_Data/*.mdf 167 | App_Data/*.ldf 168 | 169 | ############# 170 | ## Windows detritus 171 | ############# 172 | 173 | # Windows image file caches 174 | Thumbs.db 175 | ehthumbs.db 176 | 177 | # Folder config file 178 | Desktop.ini 179 | 180 | # Recycle Bin used on file shares 181 | $RECYCLE.BIN/ 182 | 183 | # Mac crap 184 | .DS_Store 185 | 186 | 187 | ############# 188 | ## Python 189 | ############# 190 | 191 | *.py[co] 192 | 193 | # Packages 194 | *.egg 195 | *.egg-info 196 | dist/ 197 | build/ 198 | eggs/ 199 | parts/ 200 | var/ 201 | sdist/ 202 | develop-eggs/ 203 | .installed.cfg 204 | 205 | # Installer logs 206 | pip-log.txt 207 | 208 | # Unit test / coverage reports 209 | .coverage 210 | .tox 211 | 212 | #Translations 213 | *.mo 214 | 215 | #Mr Developer 216 | .mr.developer.cfg 217 | -------------------------------------------------------------------------------- /BasicImageSegmentation.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BasicImageSegmentation", "BasicImageSegmentation\BasicImageSegmentation.vcxproj", "{A071A84F-7D72-4135-9F58-EDBDB2EDFD1B}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {A071A84F-7D72-4135-9F58-EDBDB2EDFD1B}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {A071A84F-7D72-4135-9F58-EDBDB2EDFD1B}.Debug|Win32.Build.0 = Debug|Win32 14 | {A071A84F-7D72-4135-9F58-EDBDB2EDFD1B}.Release|Win32.ActiveCfg = Release|Win32 15 | {A071A84F-7D72-4135-9F58-EDBDB2EDFD1B}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /BasicImageSegmentation/1_11_s.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/1_11_s.bmp -------------------------------------------------------------------------------- /BasicImageSegmentation/BasicImageSegmentation.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/BasicImageSegmentation.cpp -------------------------------------------------------------------------------- /BasicImageSegmentation/BasicImageSegmentation.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {A071A84F-7D72-4135-9F58-EDBDB2EDFD1B} 15 | Win32Proj 16 | BasicImageSegmentation 17 | 18 | 19 | 20 | Application 21 | true 22 | v110 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v110 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | true 46 | 47 | 48 | false 49 | 50 | 51 | 52 | 53 | 54 | Level3 55 | Disabled 56 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 57 | 58 | 59 | Console 60 | true 61 | 62 | 63 | 64 | 65 | Level3 66 | 67 | 68 | MaxSpeed 69 | true 70 | true 71 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 72 | 73 | 74 | Console 75 | true 76 | true 77 | true 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /BasicImageSegmentation/BasicImageSegmentation.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {16f699ae-df88-4e39-bcb2-00d13fa4dce3} 18 | 19 | 20 | {c3f45132-40c6-4a16-a2fb-afd18f66e347} 21 | 22 | 23 | {6cd27ad4-c0cd-4602-befe-1ded861d60c1} 24 | 25 | 26 | {b01d190c-1264-4051-9acb-0ea6ee348dd2} 27 | 28 | 29 | 30 | 31 | 源文件 32 | 33 | 34 | MeanShift 35 | 36 | 37 | MeanShift 38 | 39 | 40 | MeanShift 41 | 42 | 43 | MeanShift 44 | 45 | 46 | MeanShift 47 | 48 | 49 | EfficientGraphBased 50 | 51 | 52 | SEEDs 53 | 54 | 55 | SLIC 56 | 57 | 58 | 源文件 59 | 60 | 61 | 源文件 62 | 63 | 64 | 源文件 65 | 66 | 67 | 源文件 68 | 69 | 70 | 源文件 71 | 72 | 73 | 源文件 74 | 75 | 76 | 源文件 77 | 78 | 79 | 源文件 80 | 81 | 82 | 83 | 84 | MeanShift 85 | 86 | 87 | MeanShift 88 | 89 | 90 | MeanShift 91 | 92 | 93 | MeanShift 94 | 95 | 96 | MeanShift 97 | 98 | 99 | MeanShift 100 | 101 | 102 | EfficientGraphBased 103 | 104 | 105 | EfficientGraphBased 106 | 107 | 108 | EfficientGraphBased 109 | 110 | 111 | SEEDs 112 | 113 | 114 | SLIC 115 | 116 | 117 | 头文件 118 | 119 | 120 | 头文件 121 | 122 | 123 | 头文件 124 | 125 | 126 | 头文件 127 | 128 | 129 | 头文件 130 | 131 | 132 | 头文件 133 | 134 | 135 | 头文件 136 | 137 | 138 | 头文件 139 | 140 | 141 | 头文件 142 | 143 | 144 | -------------------------------------------------------------------------------- /BasicImageSegmentation/ConfigReader.cpp: -------------------------------------------------------------------------------- 1 | #include "ConfigReader.h" 2 | 3 | 4 | ConfigReader::ConfigReader(void) 5 | { 6 | m_filename = "config.ini"; 7 | ReadConfig(); 8 | } 9 | 10 | ConfigReader::ConfigReader(const string& _name) 11 | { 12 | m_filename = _name; 13 | ReadConfig(); 14 | } 15 | 16 | ConfigReader::~ConfigReader(void) 17 | { 18 | } 19 | 20 | void ConfigReader::GetSegRequire(vector& _req) 21 | { 22 | _req = segList; 23 | } 24 | 25 | void ConfigReader::ReadConfig() 26 | { 27 | ifstream conFile(m_filename, ios::in); 28 | if (!conFile) 29 | { 30 | cout<<"--Error: Failed to read config!"< args; 55 | ss<>arg) { 58 | args.push_back(arg); 59 | } 60 | req.second = args; 61 | segList.push_back(req); 62 | req.first.clear(); 63 | req.second.clear(); 64 | } 65 | } 66 | if (!req.first.empty() && req.second.empty()) 67 | { 68 | segList.push_back(req); 69 | } 70 | 71 | conFile.close(); 72 | } 73 | 74 | void ConfigReader::Trim(string & str) 75 | { 76 | if (str.empty()) { 77 | return; 78 | } 79 | int i, start_pos, end_pos; 80 | for (i = 0; i < str.size(); ++i) { 81 | if (!IsSpace(str[i])) { 82 | break; 83 | } 84 | } 85 | if (i == str.size()) { 86 | str = ""; 87 | return; 88 | } 89 | 90 | start_pos = i; 91 | 92 | for (i = str.size() - 1; i >= 0; --i) { 93 | if (!IsSpace(str[i])) { 94 | break; 95 | } 96 | } 97 | end_pos = i; 98 | 99 | str = str.substr(start_pos, end_pos - start_pos + 1); 100 | } 101 | 102 | bool ConfigReader::IsSpace(char c) 103 | { 104 | if (' ' == c || '\t' == c) 105 | return true; 106 | return false; 107 | } 108 | -------------------------------------------------------------------------------- /BasicImageSegmentation/ConfigReader.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/ConfigReader.h -------------------------------------------------------------------------------- /BasicImageSegmentation/EfficientGraphBased/ReadMe.md: -------------------------------------------------------------------------------- 1 | Paper 2 | ====================== 3 | Felzenszwalb P F, Huttenlocher D P. Efficient graph-based image segmentation[J]. International Journal of Computer Vision, 2004, 59(2): 167-181. 4 | 5 | SourceCode 6 | ====================== 7 | http://cs.brown.edu/~pff/segment/ -------------------------------------------------------------------------------- /BasicImageSegmentation/EfficientGraphBased/disjoint-set.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #ifndef DISJOINT_SET 20 | #define DISJOINT_SET 21 | 22 | // disjoint-set forests using union-by-rank and path compression (sort of). 23 | 24 | typedef struct { 25 | int rank; 26 | int p; 27 | int size; 28 | } uni_elt; 29 | 30 | class universe { 31 | public: 32 | universe(int elements); 33 | ~universe(); 34 | int find(int x); 35 | void join(int x, int y); 36 | int size(int x) const { return elts[x].size; } 37 | int nu_sets() const { return num; } 38 | 39 | private: 40 | uni_elt *elts; 41 | int num; 42 | }; 43 | 44 | universe::universe(int elements) { 45 | elts = new uni_elt[elements]; 46 | num = elements; 47 | for (int i = 0; i < elements; i++) { 48 | elts[i].rank = 0; 49 | elts[i].size = 1; 50 | elts[i].p = i; 51 | } 52 | } 53 | 54 | universe::~universe() { 55 | delete [] elts; 56 | } 57 | 58 | int universe::find(int x) { 59 | int y = x; 60 | while (y != elts[y].p) 61 | y = elts[y].p; 62 | elts[x].p = y; 63 | return y; 64 | } 65 | 66 | void universe::join(int x, int y) { 67 | if (elts[x].rank > elts[y].rank) { 68 | elts[y].p = x; 69 | elts[x].size += elts[y].size; 70 | } else { 71 | elts[x].p = y; 72 | elts[y].size += elts[x].size; 73 | if (elts[x].rank == elts[y].rank) 74 | elts[y].rank++; 75 | } 76 | num--; 77 | } 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /BasicImageSegmentation/EfficientGraphBased/segment-graph.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #ifndef SEGMENT_GRAPH 20 | #define SEGMENT_GRAPH 21 | 22 | #include 23 | #include 24 | #include "disjoint-set.h" 25 | 26 | // threshold function 27 | #define THRESHOLD(size, c) (c/size) 28 | 29 | typedef struct { 30 | float w; 31 | int a, b; 32 | } edge; 33 | 34 | bool operator<(const edge &a, const edge &b) { 35 | return a.w < b.w; 36 | } 37 | 38 | /* 39 | * Segment a graph 40 | * 41 | * Returns a disjoint-set forest representing the segmentation. 42 | * 43 | * nu_vertices: number of vertices in graph. 44 | * nu_edges: number of edges in graph 45 | * edges: array of edges. 46 | * c: constant for treshold function. 47 | */ 48 | universe *segment_graph(int nu_vertices, int nu_edges, edge *edges, float c) { 49 | // sort edges by weight 50 | std::sort(edges, edges + nu_edges); 51 | 52 | // make a disjoint-set forest 53 | universe *u = new universe(nu_vertices); 54 | 55 | // init thresholds 56 | float *threshold = new float[nu_vertices]; 57 | for (int i = 0; i < nu_vertices; i++) 58 | threshold[i] = THRESHOLD(1,c); 59 | 60 | // for each edge, in non-decreasing weight order... 61 | for (int i = 0; i < nu_edges; i++) { 62 | edge *pedge = &edges[i]; 63 | 64 | // components conected by this edge 65 | int a = u->find(pedge->a); 66 | int b = u->find(pedge->b); 67 | if (a != b) { 68 | if ((pedge->w <= threshold[a]) && 69 | (pedge->w <= threshold[b])) { 70 | u->join(a, b); 71 | a = u->find(a); 72 | threshold[a] = pedge->w + THRESHOLD(u->size(a), c); 73 | } 74 | } 75 | } 76 | 77 | // free up 78 | delete[] threshold; 79 | return u; 80 | } 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /BasicImageSegmentation/EfficientGraphBased/segment-image.cpp: -------------------------------------------------------------------------------- 1 | #include "segment-graph.h" 2 | #include "segment-image.h" 3 | #include 4 | using namespace std; 5 | 6 | // dissimilarity measure between pixels 7 | static inline float diff(Mat &img3f, int x1, int y1, int x2, int y2) 8 | { 9 | const Vec3f &p1 = img3f.at(y1, x1); 10 | const Vec3f &p2 = img3f.at(y2, x2); 11 | return sqrt((p1[0] - p2[0])*(p1[0] - p2[0]) + (p1[1] - p2[1])*(p1[1] - p2[1]) + (p1[2] - p2[2])*(p1[2] - p2[2])); 12 | } 13 | 14 | /* 15 | * Segment an image 16 | * 17 | * Returns a color image representing the segmentation. 18 | * 19 | * Input: 20 | * im: image to segment. 21 | * sigma: to smooth the image. 22 | * c: constant for threshold function. 23 | * min_size: minimum component size (enforced by post-processing stage). 24 | * nu_ccs: number of connected components in the segmentation. 25 | * Output: 26 | * colors: colors assigned to each components 27 | * pImgInd: index of each components, [0, colors.size() -1] 28 | */ 29 | int SegmentImage(Mat &_src3f, Mat &pImgInd, double sigma, double c, int min_size) 30 | { 31 | CV_Assert(_src3f.type() == CV_32FC3); 32 | int width(_src3f.cols), height(_src3f.rows); 33 | Mat smImg3f; 34 | GaussianBlur(_src3f, smImg3f, Size(), sigma, 0, BORDER_REPLICATE); 35 | 36 | // build graph 37 | edge *edges = new edge[width*height*4]; 38 | int num = 0; 39 | { 40 | for (int y = 0; y < height; y++) { 41 | for (int x = 0; x < width; x++) { 42 | if (x < width-1) { 43 | edges[num].a = y * width + x; 44 | edges[num].b = y * width + (x+1); 45 | edges[num].w = diff(smImg3f, x, y, x+1, y); 46 | num++; 47 | } 48 | 49 | if (y < height-1) { 50 | edges[num].a = y * width + x; 51 | edges[num].b = (y+1) * width + x; 52 | edges[num].w = diff(smImg3f, x, y, x, y+1); 53 | num++; 54 | } 55 | 56 | if ((x < width-1) && (y < height-1)) { 57 | edges[num].a = y * width + x; 58 | edges[num].b = (y+1) * width + (x+1); 59 | edges[num].w = diff(smImg3f, x, y, x+1, y+1); 60 | num++; 61 | } 62 | 63 | if ((x < width-1) && (y > 0)) { 64 | edges[num].a = y * width + x; 65 | edges[num].b = (y-1) * width + (x+1); 66 | edges[num].w = diff(smImg3f, x, y, x+1, y-1); 67 | num++; 68 | } 69 | } 70 | } 71 | } 72 | 73 | // segment 74 | universe *u = segment_graph(width*height, num, edges, (float)c); 75 | 76 | // post process small components 77 | for (int i = 0; i < num; i++) { 78 | int a = u->find(edges[i].a); 79 | int b = u->find(edges[i].b); 80 | if ((a != b) && ((u->size(a) < min_size) || (u->size(b) < min_size))) 81 | u->join(a, b); 82 | } 83 | delete [] edges; 84 | 85 | // pick random colors for each component 86 | map marker; 87 | pImgInd.create(smImg3f.size(), CV_32S); 88 | 89 | int idxNum = 0; 90 | for (int y = 0; y < height; y++) { 91 | int *imgIdx = pImgInd.ptr(y); 92 | for (int x = 0; x < width; x++) { 93 | int comp = u->find(y * width + x); 94 | if (marker.find(comp) == marker.end()) 95 | marker[comp] = idxNum++; 96 | 97 | int idx = marker[comp]; 98 | imgIdx[x] = idx; 99 | } 100 | } 101 | delete u; 102 | 103 | return idxNum; 104 | } 105 | -------------------------------------------------------------------------------- /BasicImageSegmentation/EfficientGraphBased/segment-image.h: -------------------------------------------------------------------------------- 1 | /* 2 | Modified by Ming-Ming on Aug. 15th, 2010. 3 | 4 | Copyright (C) 2006 Pedro Felzenszwalb 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #ifndef SEGMENT_IMAGE 22 | #define SEGMENT_IMAGE 23 | 24 | #include "opencv2/core/core.hpp" 25 | #include "opencv2/highgui/highgui.hpp" 26 | #include "opencv2/imgproc/imgproc.hpp" 27 | using namespace cv; 28 | /* 29 | * Segment an image 30 | * 31 | * Returns a color image representing the segmentation. 32 | * 33 | * Input: 34 | * im: image to segment. 35 | * sigma: to smooth the image. 36 | * c: constant for threshold function. 37 | * min_size: minimum component size (enforced by post-processing stage). 38 | * nu_ccs: number of connected components in the segmentation. 39 | * Output: 40 | * colors: colors assigned to each components 41 | * pImgInd: index of each components 42 | */ 43 | 44 | //"Default: k = 500, sigma = 1.0, min_size = 1000\n") or k = 200, sigma = 0.5, min_size = 50 45 | int SegmentImage(Mat &_src3f, Mat &pImgInd, double sigma = 0.5, double c = 1, int min_size = 50); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /BasicImageSegmentation/GrabCutSegmentor.cpp: -------------------------------------------------------------------------------- 1 | #include "GrabCutSegmentor.h" 2 | 3 | //IMPLEMENT_DYNCRT_CLASS(GrabCutSegmentor); 4 | 5 | int GrabCutSegmentor::BGD_KEY = CV_EVENT_FLAG_CTRLKEY; 6 | int GrabCutSegmentor::FGD_KEY = CV_EVENT_FLAG_SHIFTKEY; 7 | 8 | GrabCutSegmentor::GrabCutSegmentor(void) 9 | { 10 | m_Name = "GrabCut"; 11 | 12 | m_WinName = "GrabCut Interactive"; 13 | isInitialized = false; 14 | 15 | m_argNum = 0; 16 | } 17 | 18 | 19 | GrabCutSegmentor::~GrabCutSegmentor(void) 20 | { 21 | } 22 | 23 | void GrabCutSegmentor::SetArgs(const vector _args) 24 | { 25 | //cout<<"["< iter ) 77 | { 78 | showImage(); 79 | cout << "Finished!" << endl; 80 | } 81 | else 82 | cout << "rect must be determined!" << endl; 83 | break; 84 | } 85 | } 86 | 87 | exit: 88 | m_Mask = m_Mask & 1; 89 | m_Mask.convertTo(m_Result, CV_32SC1); 90 | 91 | destroyWindow( m_WinName ); 92 | 93 | Segmentor::Run(); 94 | } 95 | 96 | void GrabCutSegmentor::onMouse(int event, int x, int y, int flags, void* param) 97 | { 98 | //left mouse button - set rectangle 99 | //CTRL+left mouse button - set GC_BGD pixels 100 | //SHIFT+left mouse button - set CG_FGD pixels 101 | //CTRL+right mouse button - set GC_PR_BGD pixels 102 | //SHIFT+right mouse button - set CG_PR_FGD pixels 103 | 104 | GrabCutSegmentor* s = (GrabCutSegmentor*)param; 105 | if (s == NULL) 106 | { 107 | cout<<"--Error: Failed to get GrabCut Entity!"<rectState == NOT_SET && !isb && !isf ) 117 | { 118 | s->rectState = IN_PROCESS; 119 | s->rect = Rect( x, y, 1, 1 ); 120 | } 121 | if ( (isb || isf) && s->rectState == SET ) 122 | s->lblsState = IN_PROCESS; 123 | } 124 | break; 125 | case CV_EVENT_RBUTTONDOWN: // set GC_PR_BGD(GC_PR_FGD) labels 126 | { 127 | bool isb = (flags & BGD_KEY) != 0, 128 | isf = (flags & FGD_KEY) != 0; 129 | if ( (isb || isf) && s->rectState == SET ) 130 | s->prLblsState = IN_PROCESS; 131 | } 132 | break; 133 | case CV_EVENT_LBUTTONUP: 134 | if( s->rectState == IN_PROCESS ) 135 | { 136 | s->rect = Rect( Point(s->rect.x, s->rect.y), Point(x,y) ); 137 | s->rectState = SET; 138 | s->setRectInMask(); 139 | assert( s->bgdPxls.empty() && s->fgdPxls.empty() && s->prBgdPxls.empty() && s->prFgdPxls.empty() ); 140 | s->showImage(); 141 | } 142 | if( s->lblsState == IN_PROCESS ) 143 | { 144 | s->setLblsInMask(flags, Point(x,y), false); 145 | s->lblsState = SET; 146 | s->showImage(); 147 | } 148 | break; 149 | case CV_EVENT_RBUTTONUP: 150 | if( s->prLblsState == IN_PROCESS ) 151 | { 152 | s->setLblsInMask(flags, Point(x,y), true); 153 | s->prLblsState = SET; 154 | s->showImage(); 155 | } 156 | break; 157 | case CV_EVENT_MOUSEMOVE: 158 | if( s->rectState == IN_PROCESS ) 159 | { 160 | s->rect = Rect( Point(s->rect.x, s->rect.y), Point(x,y) ); 161 | assert( s->bgdPxls.empty() && s->fgdPxls.empty() && s->prBgdPxls.empty() && s->prFgdPxls.empty() ); 162 | s->showImage(); 163 | } 164 | else if( s->lblsState == IN_PROCESS ) 165 | { 166 | s->setLblsInMask(flags, Point(x,y), false); 167 | s->showImage(); 168 | } 169 | else if( s->prLblsState == IN_PROCESS ) 170 | { 171 | s->setLblsInMask(flags, Point(x,y), true); 172 | s->showImage(); 173 | } 174 | break; 175 | } 176 | } 177 | 178 | void GrabCutSegmentor::doSegment() 179 | { 180 | 181 | } 182 | 183 | void GrabCutSegmentor::setRectInMask() 184 | { 185 | assert( !m_Mask.empty() ); 186 | m_Mask.setTo( GC_BGD ); 187 | rect.x = max(0, rect.x); 188 | rect.y = max(0, rect.y); 189 | rect.width = min(rect.width, m_Img.cols-rect.x); 190 | rect.height = min(rect.height, m_Img.rows-rect.y); 191 | (m_Mask(rect)).setTo( Scalar(GC_PR_FGD) ); 192 | } 193 | 194 | void GrabCutSegmentor::setLblsInMask( int flags, Point p, bool isPr ) 195 | { 196 | vector *bpxls, *fpxls; 197 | uchar bvalue, fvalue; 198 | if( !isPr ) 199 | { 200 | bpxls = &bgdPxls; 201 | fpxls = &fgdPxls; 202 | bvalue = GC_BGD; 203 | fvalue = GC_FGD; 204 | } 205 | else 206 | { 207 | bpxls = &prBgdPxls; 208 | fpxls = &prFgdPxls; 209 | bvalue = GC_PR_BGD; 210 | fvalue = GC_PR_FGD; 211 | } 212 | if( flags & BGD_KEY ) 213 | { 214 | bpxls->push_back(p); 215 | circle( m_Mask, p, 2, bvalue, -1 ); 216 | } 217 | if( flags & FGD_KEY ) 218 | { 219 | fpxls->push_back(p); 220 | circle( m_Mask, p, 2, fvalue, -1 ); 221 | } 222 | } 223 | 224 | const Scalar RED = Scalar(0,0,255); 225 | const Scalar PINK = Scalar(230,130,255); 226 | const Scalar BLUE = Scalar(255,0,0); 227 | const Scalar LIGHTBLUE = Scalar(255,255,160); 228 | const Scalar GREEN = Scalar(0,255,0); 229 | void GrabCutSegmentor::showImage() 230 | { 231 | if( m_Img.empty()) 232 | return; 233 | 234 | Mat res; 235 | Mat binMask; 236 | if( !isInitialized ) 237 | m_Img.copyTo( res ); 238 | else 239 | { 240 | if( m_Mask.empty() || m_Mask.type()!=CV_8UC1 ) 241 | CV_Error( CV_StsBadArg, "comMask is empty or has incorrect type (not CV_8UC1)" ); 242 | if( binMask.empty() || binMask.rows!=m_Mask.rows || binMask.cols!=m_Mask.cols ) 243 | binMask.create( m_Mask.size(), CV_8UC1 ); 244 | binMask = m_Mask & 1; 245 | m_Img.copyTo( res, binMask ); 246 | } 247 | 248 | vector::const_iterator it; 249 | for( it = bgdPxls.begin(); it != bgdPxls.end(); ++it ) 250 | circle( res, *it, 2, BLUE, -1 ); 251 | for( it = fgdPxls.begin(); it != fgdPxls.end(); ++it ) 252 | circle( res, *it, 2, RED, -1 ); 253 | for( it = prBgdPxls.begin(); it != prBgdPxls.end(); ++it ) 254 | circle( res, *it, 2, LIGHTBLUE, -1 ); 255 | for( it = prFgdPxls.begin(); it != prFgdPxls.end(); ++it ) 256 | circle( res, *it, 2, PINK, -1 ); 257 | 258 | if( rectState == IN_PROCESS || rectState == SET ) 259 | rectangle( res, Point( rect.x, rect.y ), Point(rect.x + rect.width, rect.y + rect.height ), GREEN, 2); 260 | 261 | imshow( m_WinName, res ); 262 | } 263 | 264 | int GrabCutSegmentor::nextIter() 265 | { 266 | if( isInitialized ) 267 | grabCut( m_Img, m_Mask, rect, m_BgdModel, m_FgdModel, 1 ); 268 | else 269 | { 270 | if( rectState != SET ) 271 | return iterCount; 272 | 273 | if( lblsState == SET || prLblsState == SET ) 274 | grabCut( m_Img, m_Mask, rect, m_BgdModel, m_FgdModel, 1, GC_INIT_WITH_MASK ); 275 | else 276 | grabCut( m_Img, m_Mask, rect, m_BgdModel, m_FgdModel, 1 , GC_INIT_WITH_RECT ); 277 | 278 | isInitialized = true; 279 | } 280 | iterCount++; 281 | 282 | bgdPxls.clear(); fgdPxls.clear(); 283 | prBgdPxls.clear(); prFgdPxls.clear(); 284 | 285 | return iterCount; 286 | } 287 | 288 | void GrabCutSegmentor::reset() 289 | { 290 | if( !m_Mask.empty() ) 291 | m_Mask.setTo(Scalar::all(GC_BGD)); 292 | bgdPxls.clear(); fgdPxls.clear(); 293 | prBgdPxls.clear(); prFgdPxls.clear(); 294 | 295 | isInitialized = false; 296 | rectState = NOT_SET; 297 | lblsState = NOT_SET; 298 | prLblsState = NOT_SET; 299 | iterCount = 0; 300 | } -------------------------------------------------------------------------------- /BasicImageSegmentation/GrabCutSegmentor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "segmentor.h" 4 | 5 | #define max(x,y) (x)>(y) ? (x) : (y) 6 | #define min(x,y) (x)<(y) ? (x) : (y) 7 | 8 | class GrabCutSegmentor : 9 | public Segmentor 10 | { 11 | DECLARE_DYNCRT_CLASS(GrabCutSegmentor, Segmentor); 12 | 13 | public: 14 | GrabCutSegmentor(void); 15 | ~GrabCutSegmentor(void); 16 | 17 | virtual void SetArgs(const vector _args); 18 | 19 | virtual void Run(); 20 | 21 | void SetImage(const Mat& _img); 22 | 23 | private: 24 | static void onMouse(int event, int x, int y, int flags, void* param); 25 | static int BGD_KEY; 26 | static int FGD_KEY; 27 | 28 | void doSegment(); 29 | void setRectInMask(); 30 | void setLblsInMask( int flags, Point p, bool isPr ); 31 | void showImage(); 32 | int nextIter(); 33 | void reset(); 34 | 35 | enum{ NOT_SET = 0, IN_PROCESS = 1, SET = 2 }; 36 | 37 | Mat m_Mask; 38 | Mat m_BgdModel, m_FgdModel; 39 | string m_WinName; 40 | 41 | int iterCount; 42 | uchar rectState, lblsState, prLblsState; 43 | Rect rect; 44 | vector fgdPxls, bgdPxls, prFgdPxls, prBgdPxls; 45 | bool isInitialized; 46 | }; 47 | 48 | -------------------------------------------------------------------------------- /BasicImageSegmentation/GraphBasedSegmentor.cpp: -------------------------------------------------------------------------------- 1 | #include "GraphBasedSegmentor.h" 2 | 3 | 4 | GraphBasedSegmentor::GraphBasedSegmentor(void) 5 | { 6 | m_Name = "GraphBased"; 7 | 8 | m_Sigma=0.5; 9 | m_Threshold=30; 10 | m_MinSize=30; 11 | 12 | m_argNum = 3; 13 | } 14 | 15 | GraphBasedSegmentor::~GraphBasedSegmentor(void) 16 | { 17 | } 18 | 19 | void GraphBasedSegmentor::SetArgs(const vector _args) 20 | { 21 | cout<<"["<m_argNum ? m_argNum : _args.size())<<" argument(s)"; 26 | int i = 0; 27 | for ( ; i < _args.size(); i++) 28 | { 29 | cout<<", "<<"setting "< _args); 16 | 17 | virtual void Run(); 18 | 19 | private: 20 | float m_Sigma; 21 | float m_Threshold; 22 | int m_MinSize; 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShift/Example.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/MeanShift/Example.cpp -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShift/RAList.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************* 2 | 3 | Mean Shift Analysis Library 4 | ============================================= 5 | 6 | The mean shift library is a collection of routines 7 | that use the mean shift algorithm. Using this algorithm, 8 | the necessary output will be generated needed 9 | to analyze a given input set of data. 10 | 11 | Region Adjacency List: 12 | ===================== 13 | 14 | The Region Adjacency List class is used by the Image 15 | Processor class in the construction of a Region Adjacency 16 | Matrix, used by this class to applying transitive closure 17 | and to prune spurious regions during image segmentation. 18 | 19 | The definition of the RAList class is provided below. Its 20 | prototype is provided in "RAList.h". 21 | 22 | The theory is described in the papers: 23 | 24 | D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature 25 | space analysis. 26 | 27 | C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. 28 | 29 | and they are is available at: 30 | http://www.caip.rutgers.edu/riul/research/papers/ 31 | 32 | Implemented by Chris M. Christoudias, Bogdan Georgescu 33 | ********************************************************/ 34 | //include Region Adjacency List class prototype 35 | #include "RAList.h" 36 | 37 | //include needed libraries 38 | #include 39 | #include 40 | #include 41 | using namespace SEG; 42 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 43 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 44 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUBLIC METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 45 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 46 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 47 | 48 | /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 49 | /* Class Constructor and Destructor */ 50 | /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ 51 | 52 | /*******************************************************/ 53 | /*Class Constructor */ 54 | /*******************************************************/ 55 | /*Constructs a RAList object. */ 56 | /*******************************************************/ 57 | /*Post: */ 58 | /* - a RAlist object has been properly constru- */ 59 | /* cted. */ 60 | /*******************************************************/ 61 | 62 | RAList::RAList( void ) 63 | { 64 | //initialize label and link 65 | label = -1; 66 | next = NULL; 67 | 68 | //initialize edge strenght weight and count 69 | edgeStrength = 0; 70 | edgePixelCount = 0; 71 | } 72 | 73 | /*******************************************************/ 74 | /*Class Destructor */ 75 | /*******************************************************/ 76 | /*Destructrs a RAList object. */ 77 | /*******************************************************/ 78 | /*Post: */ 79 | /* - the RAList object has been properly dest- */ 80 | /* ructed. */ 81 | /*******************************************************/ 82 | 83 | RAList::~RAList( void ) 84 | { 85 | //do nothing 86 | } 87 | 88 | /*******************************************************/ 89 | /*Insert */ 90 | /*******************************************************/ 91 | /*Insert a region node into the region adjacency list. */ 92 | /*******************************************************/ 93 | /*Pre: */ 94 | /* - entry is a node representing a connected re- */ 95 | /* gion */ 96 | /*Post: */ 97 | /* - entry has been inserted into the region adj- */ 98 | /* acency list if it does not already exist */ 99 | /* there. */ 100 | /* - if the entry already exists in the region */ 101 | /* adjacency list 1 is returned otherwise 0 is */ 102 | /* returned. */ 103 | /*******************************************************/ 104 | 105 | int RAList::Insert(RAList *entry) 106 | { 107 | 108 | //if the list contains only one element 109 | //then insert this element into next 110 | if(!next) 111 | { 112 | //insert entry 113 | next = entry; 114 | entry->next = NULL; 115 | 116 | //done 117 | return 0; 118 | } 119 | 120 | //traverse the list until either: 121 | 122 | //(a) entry's label already exists - do nothing 123 | //(b) the list ends or the current label is 124 | // greater than entry's label, thus insert the entry 125 | // at this location 126 | 127 | //check first entry 128 | if(next->label > entry->label) 129 | { 130 | //insert entry into the list at this location 131 | entry->next = next; 132 | next = entry; 133 | 134 | //done 135 | return 0; 136 | } 137 | 138 | //check the rest of the list... 139 | exists = 0; 140 | cur = next; 141 | while(cur) 142 | { 143 | if(entry->label == cur->label) 144 | { 145 | //node already exists 146 | exists = 1; 147 | break; 148 | } 149 | else if((!(cur->next))||(cur->next->label > entry->label)) 150 | { 151 | //insert entry into the list at this location 152 | entry->next = cur->next; 153 | cur->next = entry; 154 | break; 155 | } 156 | 157 | //traverse the region adjacency list 158 | cur = cur->next; 159 | } 160 | 161 | //done. Return exists indicating whether or not a new node was 162 | // actually inserted into the region adjacency list. 163 | return (int)(exists); 164 | 165 | } 166 | 167 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 168 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 169 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 170 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 171 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 172 | -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShift/RAList.h: -------------------------------------------------------------------------------- 1 | /******************************************************* 2 | 3 | Mean Shift Analysis Library 4 | ============================================= 5 | 6 | The mean shift library is a collection of routines 7 | that use the mean shift algorithm. Using this algorithm, 8 | the necessary output will be generated needed 9 | to analyze a given input set of data. 10 | 11 | Region Adjacency List: 12 | ===================== 13 | 14 | The Region Adjacency List class is used by the Image 15 | Processor class in the construction of a Region Adjacency 16 | Matrix, used by this class to applying transitive closure 17 | and to prune spurious regions during image segmentation. 18 | 19 | The prototype for the RAList class is provided below. Its 20 | defition is provided in "RAList.cc". 21 | 22 | The theory is described in the papers: 23 | 24 | D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature 25 | space analysis. 26 | 27 | C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. 28 | 29 | and they are is available at: 30 | http://www.caip.rutgers.edu/riul/research/papers/ 31 | 32 | Implemented by Chris M. Christoudias, Bogdan Georgescu 33 | ********************************************************/ 34 | 35 | 36 | #ifndef RALIST_H 37 | #define RALIST_H 38 | 39 | namespace SEG{ 40 | //define Region Adjacency List class prototype 41 | class RAList { 42 | 43 | public: 44 | 45 | //============================ 46 | // *** Public Data Members *** 47 | //============================ 48 | 49 | ////////////RAM Label////////// 50 | int label; 51 | 52 | ////////////RAM Weight///////// 53 | float edgeStrength; 54 | int edgePixelCount; 55 | 56 | ////////////RAM Link/////////// 57 | RAList *next; 58 | 59 | //======================= 60 | // *** Public Methods *** 61 | //======================= 62 | 63 | /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 64 | /* Class Constructor and Destructor */ 65 | /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ 66 | 67 | //***Class Constrcutor*** 68 | RAList( void ); 69 | 70 | //***Class Destructor*** 71 | ~RAList( void ); 72 | 73 | /*/\/\/\/\/\/\/\/\/\/\/\/\*/ 74 | /* RAM List Manipulation */ 75 | /*\/\/\/\/\/\/\/\/\/\/\/\/*/ 76 | 77 | //Usage: Insert(entry) 78 | int Insert(RAList*); //Insert a region node into the region adjecency list 79 | 80 | private: 81 | 82 | //============================= 83 | // *** Private Data Members *** 84 | //============================= 85 | 86 | ///////current and previous pointer///// 87 | RAList *cur, *prev; 88 | 89 | ////////flag/////////// 90 | unsigned char exists; 91 | 92 | }; 93 | 94 | #endif 95 | } -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShift/ReadMe.md: -------------------------------------------------------------------------------- 1 | Paper 2 | ====================== 3 | Comaniciu D, Meer P. Mean shift: A robust approach toward feature space analysis[J]. Pattern Analysis and Machine Intelligence, IEEE Transactions on, 2002, 24(5): 603-619. 4 | 5 | SourceCode 6 | ====================== 7 | http://coewww.rutgers.edu/riul/research/code/EDISON/index.html -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShift/msSys.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************* 2 | Mean Shift Analysis Library 3 | ============================================= 4 | 5 | The mean shift library is a collection of routines 6 | that use the mean shift algorithm. Using this algorithm, 7 | the necessary output will be generated needed 8 | to analyze a given input set of data. 9 | 10 | Mean Shift System: 11 | ================== 12 | 13 | The Mean Shift System class provides a mechanism for the 14 | mean shift library classes to prompt progress and to 15 | time its computations. When porting the mean shift library 16 | to an application the methods of this class may be changed 17 | such that the output of the mean shift class prompts 18 | will be given to whatever hardware or software device that 19 | is desired. 20 | 21 | The definition for the mean shift system class is provided 22 | below. Its prototype is provided in "msSys.cc". 23 | 24 | The theory is described in the papers: 25 | 26 | D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature 27 | space analysis. 28 | 29 | C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. 30 | 31 | and they are is available at: 32 | http://www.caip.rutgers.edu/riul/research/papers/ 33 | 34 | Implemented by Chris M. Christoudias, Bogdan Georgescu 35 | ********************************************************/ 36 | 37 | //include the msSystem class prototype 38 | #include "msSys.h" 39 | 40 | //include needed system libraries 41 | #include 42 | #include 43 | #include 44 | #include 45 | using namespace SEG; 46 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 47 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 48 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUBLIC METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 49 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 50 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 51 | 52 | /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 53 | /*** Class Constructor and Destructor ***/ 54 | /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ 55 | 56 | /*******************************************************/ 57 | /*Class Constructor */ 58 | /*******************************************************/ 59 | /*Constructs a mean shift system object. */ 60 | /*******************************************************/ 61 | /*Post: */ 62 | /* - an msSystem object has been properly init- */ 63 | /* ialized. */ 64 | /*******************************************************/ 65 | 66 | msSystem::msSystem( void ) 67 | { 68 | //initialize currentTime 69 | currentTime = clock(); 70 | //done. 71 | } 72 | 73 | /*******************************************************/ 74 | /*Class Destructor */ 75 | /*******************************************************/ 76 | /*Destroys a mean shift system object. */ 77 | /*******************************************************/ 78 | /*Post: */ 79 | /* - an msSystem object has been properly dest- */ 80 | /* royed. */ 81 | /*******************************************************/ 82 | 83 | msSystem::~msSystem( void ) 84 | { 85 | /* do nothing */ 86 | } 87 | 88 | /*/\/\/\/\/\/\/\/\/\*/ 89 | /*** System Timer ***/ 90 | /*\/\/\/\/\/\/\/\/\/*/ 91 | 92 | /*******************************************************/ 93 | /*Start Timer */ 94 | /*******************************************************/ 95 | /*Sets the mean shift system time to the current */ 96 | /*system time. */ 97 | /*******************************************************/ 98 | /*Post: */ 99 | /* - the mean shift system time has been set to */ 100 | /* the current system time. */ 101 | /*******************************************************/ 102 | 103 | void msSystem::StartTimer( void ) 104 | { 105 | //set msSystem time to system time 106 | currentTime = clock(); 107 | 108 | //done. 109 | return; 110 | } 111 | 112 | /*******************************************************/ 113 | /*Elapsed Time */ 114 | /*******************************************************/ 115 | /*Returns the amount of time in seconds since the */ 116 | /*mean shift system time was last set. */ 117 | /*******************************************************/ 118 | /*Post: */ 119 | /* - the amount of time in seconds since the mean */ 120 | /* shift system time was last set is returned. */ 121 | /*******************************************************/ 122 | 123 | double msSystem::ElapsedTime( void ) 124 | { 125 | //return the amount of time elapsed in seconds 126 | //since the msSystem time was last set... 127 | return ((double) (clock() - currentTime))/(CLOCKS_PER_SEC); 128 | } 129 | 130 | /*/\/\/\/\/\/\/\/\/\/\*/ 131 | /*** System Output ***/ 132 | /*\/\/\/\/\/\/\/\/\/\/*/ 133 | 134 | /*******************************************************/ 135 | /*Prompt */ 136 | /*******************************************************/ 137 | /*Output a text message to the user. */ 138 | /*******************************************************/ 139 | /*Pre: */ 140 | /* - PromptStr is a string containing delimeters */ 141 | /* that is to be output to the user. */ 142 | /* - a variable set of arguments is also passed */ 143 | /* to this method that are used to replace */ 144 | /* the delimeters contained by PromptStr */ 145 | /*Post: */ 146 | /* - the delimeters of PromptStr have been */ 147 | /* replaced accordingly using the variable */ 148 | /* set of arguments and the resulting string */ 149 | /* has been output to the user. */ 150 | /*******************************************************/ 151 | 152 | /////////////////////////////////////////////////////////////void msSystem::bgLogVar(const char *, va_list); 153 | 154 | void msSystem::Prompt(const char *PromptStr, ...) 155 | { 156 | //obtain argument list using ANSI standard... 157 | va_list argList; 158 | va_start(argList, PromptStr); 159 | 160 | //print the output string to stderr using 161 | //vfprintf 162 | ///////////////////////////////////////////////////////////////bgLogVar(PromptStr, argList); 163 | va_end(argList); 164 | 165 | //done. 166 | return; 167 | } 168 | 169 | /*******************************************************/ 170 | /*Progress */ 171 | /*******************************************************/ 172 | /*The progress of a specific algorithm of the mean */ 173 | /*shift library is output to the user. */ 174 | /*******************************************************/ 175 | /*Pre: */ 176 | /* - percentComplete indicates the percentage */ 177 | /* of the algorithm that has executed and is */ 178 | /* a floating point number from zero to one */ 179 | /*Post: */ 180 | /* - the percentComplete has been noted by the */ 181 | /* interface (possibly to update a progress */ 182 | /* bar). */ 183 | /* - if the thread executing the mean shift code */ 184 | /* must halt execution msSYS_HALT is returned, */ 185 | /* msSYS_OK is returned otherwise */ 186 | /*******************************************************/ 187 | 188 | /////////////////////////////////////////////////////////////////// 189 | //NOTE: This implementation is specific to EDISON. In order 190 | // for one to port the mean shift class to another project 191 | // or program one must re-implement this method. 192 | /////////////////////////////////////////////////////////////////// 193 | 194 | //is set by the GUI when the user presses the Cancel button 195 | //on the wxWindows progress modal window; this flag indicates 196 | //to the mean shift library that it is to halt execution. 197 | //This parameter is used and checked in the method 198 | //BgMdiSegmentChild::OnSegment. 199 | 200 | /////////////////////////////////////////////////////////////////////extern bool stop_flag; 201 | 202 | //is updated in the msSystem::Progress method and indicates to 203 | //the wxWindows progress modal window the percent complete, such 204 | //that it may update its progress bar accordingly; This parameter 205 | //is used and checked in the method BgMdiSegmentChild::OnSegment. 206 | /////////////////////////////////////////////////////////////////////extern int percentDone; 207 | 208 | ErrorLevel msSystem::Progress(float percentComplete) 209 | { 210 | int percentDone = (int)(percentComplete*100); 211 | 212 | //check stop flag and return appropriate system state 213 | ErrorLevel myState = EL_OKAY; 214 | bool stop_flag=false; 215 | if(stop_flag) myState = EL_HALT; 216 | 217 | //done. 218 | return myState; 219 | } 220 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 221 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 222 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 223 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 224 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 225 | 226 | -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShift/msSys.h: -------------------------------------------------------------------------------- 1 | /******************************************************* 2 | 3 | Mean Shift Analysis Library 4 | ============================================= 5 | 6 | The mean shift library is a collection of routines 7 | that use the mean shift algorithm. Using this algorithm, 8 | the necessary output will be generated needed 9 | to analyze a given input set of data. 10 | 11 | Mean Shift System: 12 | ================== 13 | 14 | The Mean Shift System class provides a mechanism for the 15 | mean shift library classes to prompt progress and to 16 | time its computations. When porting the mean shift library 17 | to an application the methods of this class may be changed 18 | such that the output of the mean shift class prompts 19 | will be given to whatever hardware or software device that 20 | is desired. 21 | 22 | The prototype for the mean shift system class is provided 23 | below. Its defition is provided in "msSys.cc". 24 | 25 | The theory is described in the papers: 26 | 27 | D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature 28 | space analysis. 29 | 30 | C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. 31 | 32 | and they are is available at: 33 | http://www.caip.rutgers.edu/riul/research/papers/ 34 | 35 | Implemented by Chris M. Christoudias, Bogdan Georgescu 36 | ********************************************************/ 37 | 38 | 39 | 40 | #ifndef MSSYS_H 41 | #define MSSYS_H 42 | 43 | //Include standard mean shift library type definitions 44 | #include "tdef.h" 45 | 46 | //Include standard libraries needed for msSystem prototype 47 | #include 48 | 49 | using namespace SEG; 50 | 51 | namespace SEG{ 52 | 53 | extern void bgLogFile(const char*, ...); 54 | 55 | //Mean Shify System class prototype 56 | class msSystem { 57 | 58 | public: 59 | 60 | /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 61 | /* Class Constructor and Destructor */ 62 | /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ 63 | 64 | msSystem( void ); //Default Constructor 65 | ~msSystem( void ); //Class Destructor 66 | 67 | /*/\/\/\/\/\/\/\*/ 68 | /* System Timer */ 69 | /*\/\/\/\/\/\/\/*/ 70 | 71 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 72 | //<--------------------------------------------------->|// 73 | //| |// 74 | //| Method Name: |// 75 | //| ============ |// 76 | //| * Start Timer * |// 77 | //| |// 78 | //<--------------------------------------------------->|// 79 | //| |// 80 | //| Description: |// 81 | //| ============ |// 82 | //| |// 83 | //| Initializes the system timer. The timer object |// 84 | //| synthesized by this class is initialized during |// 85 | //| construction of the msSystem class to be the |// 86 | //| current time during construction. |// 87 | //| |// 88 | //<--------------------------------------------------->|// 89 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 90 | 91 | void StartTimer( void ); 92 | 93 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 94 | //<--------------------------------------------------->|// 95 | //| |// 96 | //| Method Name: |// 97 | //| ============ |// 98 | //| * Elapsed Time * |// 99 | //| |// 100 | //<--------------------------------------------------->|// 101 | //| |// 102 | //| Description: |// 103 | //| ============ |// 104 | //| |// 105 | //| Returns the amount of time elapsed in seconds |// 106 | //| from when StartTimer() was called. If |// 107 | //| StartTimer() was not called, the time returned |// 108 | //| is the time elapsed from the construction of the |// 109 | //| msSystem object. |// 110 | //| |// 111 | //| In order to create a valid kernel the following |// 112 | //| argumens must be provided this method: |// 113 | //| |// 114 | //<--------------------------------------------------->|// 115 | //| |// 116 | //| Usage: |// 117 | //| ====== |// 118 | //| TimeInSeconds = ElapsedTime() |// 119 | //| |// 120 | //<--------------------------------------------------->|// 121 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 122 | 123 | double ElapsedTime( void ); 124 | 125 | /*/\/\/\/\/\/\/\/\*/ 126 | /* System Output */ 127 | /*\/\/\/\/\/\/\/\/*/ 128 | 129 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 130 | //<--------------------------------------------------->|// 131 | //| |// 132 | //| Method Name: |// 133 | //| ============ |// 134 | //| * Prompt * |// 135 | //| |// 136 | //<--------------------------------------------------->|// 137 | //| |// 138 | //| Description: |// 139 | //| ============ |// 140 | //| |// 141 | //| Outputs to a device a character message contain- |// 142 | //| ing delimeters. These delimeters are replaced by |// 143 | //| the variable input parameters passed to prompt. |// 144 | //| (Like printf.) |// 145 | //| |// 146 | //| This method should be altered if a special |// 147 | //| device either than stderr is desired to be used |// 148 | //| as an output prompt. |// 149 | //| |// 150 | //| The arguments to this method are: |// 151 | //| |// 152 | //| <* PromptStr *> |// 153 | //| A string possibly containing delimeters that |// 154 | //| is to be output to the user. |// 155 | //| |// 156 | //| <* varArgs *> |// 157 | //| A variable set of arguments to be placed into |// 158 | //| the prompt string. |// 159 | //| |// 160 | //<--------------------------------------------------->|// 161 | //| |// 162 | //| Usage: |// 163 | //| ====== |// 164 | //| Prompt(PromptStr, varArgs) |// 165 | //| |// 166 | //<--------------------------------------------------->|// 167 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 168 | 169 | void Prompt(const char*, ...); 170 | 171 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 172 | //<--------------------------------------------------->|// 173 | //| |// 174 | //| Method Name: |// 175 | //| ============ |// 176 | //| * Progress * |// 177 | //| |// 178 | //<--------------------------------------------------->|// 179 | //| |// 180 | //| Description: |// 181 | //| ============ |// 182 | //| |// 183 | //| This method is called by the mean shift library |// 184 | //| methods during the application of a specific |// 185 | //| algorithm in which the progress of the algorithm |// 186 | //| is indicated. Its main use is for a multi-thre- |// 187 | //| aded programming envioronment. Namely, it is |// 188 | //| called fairly frequently by the mean shift |// 189 | //| library methods. It then can be used to grace- |// 190 | //| fully halt the algorithm, or to simply update |// 191 | //| a progress bar. |// 192 | //| |// 193 | //| This method depends strongly on the interface |// 194 | //| and therefore must be re-implemented to accom- |// 195 | //| odate ones needs. |// 196 | //| |// 197 | //| To facilitate a multi-threaded enviornment |// 198 | //| the prompt function returns a value that |// 199 | //| indicates to the mean shift method whether |// 200 | //| to continue execution. EL_HALT is returned |// 201 | //| when the mean shift procedure is to stop |// 202 | //| execution and EL_OKAY is returned otherwise. |// 203 | //| |// 204 | //| The arguments to this method are: |// 205 | //| |// 206 | //| <* PercentComplete *> |// 207 | //| A floating point number that indicates the perc- |// 208 | //| ent complete of the algorithm. PercentComplete |// 209 | //| takes a value between zero and one. |// 210 | //| |// 211 | //| <* SystemState *> |// 212 | //| Indicates the system state. It is EL_HALT |// 213 | //| when the mean shift method is to halt execution |// 214 | //| and it is EL_OKAY otherwise. |// 215 | //| |// 216 | //<--------------------------------------------------->|// 217 | //| |// 218 | //| Usage: |// 219 | //| ====== |// 220 | //| SystemState = Progress(PercentComplete) |// 221 | //| |// 222 | //<--------------------------------------------------->|// 223 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 224 | 225 | ErrorLevel Progress(float); 226 | 227 | 228 | 229 | private: 230 | 231 | //Timer object... 232 | time_t currentTime; 233 | 234 | }; 235 | 236 | #endif 237 | } -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShift/rlist.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************* 2 | 3 | Mean Shift Analysis Library 4 | ============================================= 5 | 6 | 7 | The mean shift library is a collection of routines 8 | that use the mean shift algorithm. Using this algorithm, 9 | the necessary output will be generated needed 10 | to analyze a given input set of data. 11 | 12 | Region List Class: 13 | ================= 14 | 15 | During segmentation, data regions are defined. The 16 | RegionList class provides a mechanism for doing so, as 17 | well as defines some basic operations, such as region 18 | growing or small region pruning, on the defined regions. 19 | It is defined below. Its prototype is given in "region.h". 20 | 21 | The theory is described in the papers: 22 | 23 | D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature 24 | space analysis. 25 | 26 | C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. 27 | 28 | and they are is available at: 29 | http://www.caip.rutgers.edu/riul/research/papers/ 30 | 31 | Implemented by Chris M. Christoudias, Bogdan Georgescu 32 | ********************************************************/ 33 | 34 | 35 | #include "rlist.h" 36 | #include 37 | #include 38 | using namespace SEG; 39 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 40 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 41 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUBLIC METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 42 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 43 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 44 | 45 | /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 46 | /*** Class Constructor and Destructor ***/ 47 | /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ 48 | 49 | /*******************************************************/ 50 | /*Constructor */ 51 | /*******************************************************/ 52 | /*Constructor */ 53 | /*******************************************************/ 54 | /*Pre: */ 55 | /* - modesPtr is a pointer to an array of modes */ 56 | /* - maxRegions_ is the maximum number of regions */ 57 | /* that can be defined */ 58 | /* - L_ is the number of data points being class- */ 59 | /* ified by the region list class */ 60 | /* - N is the dimension of the data set being cl- */ 61 | /* assified by the region list class */ 62 | /*Post: */ 63 | /* - a region list object has been properly init- */ 64 | /* ialized. */ 65 | /*******************************************************/ 66 | 67 | RegionList::RegionList(int maxRegions_, int L_, int N_) 68 | { 69 | 70 | //Obtain maximum number of regions that can be 71 | //defined by user 72 | if((maxRegions = maxRegions_) <= 0) 73 | ErrorHandler("RegionList", "Maximum number of regions is zero or negative.", FATAL); 74 | 75 | //Obtain dimension of data set being classified by 76 | //region list class 77 | if((N = N_) <= 0) 78 | ErrorHandler("RegionList", "Dimension is zero or negative.", FATAL); 79 | 80 | //Obtain length of input data set... 81 | if((L = L_) <= 0) 82 | ErrorHandler("RegionList", "Length of data set is zero or negative.", FATAL); 83 | 84 | //Allocate memory for index table 85 | if(!(indexTable = new int [L])) 86 | ErrorHandler("RegionList", "Not enough memory.", FATAL); 87 | 88 | //Allocate memory for region list array 89 | if(!(regionList = new REGION [maxRegions])) 90 | ErrorHandler("RegionList", "Not enough memory.", FATAL); 91 | 92 | //Initialize region list... 93 | numRegions = freeRegion = 0; 94 | 95 | //Initialize indexTable 96 | freeBlockLoc = 0; 97 | 98 | //done. 99 | return; 100 | 101 | } 102 | 103 | /*******************************************************/ 104 | /*Destructor */ 105 | /*******************************************************/ 106 | /*Destroys region list object. */ 107 | /*******************************************************/ 108 | /*Post: */ 109 | /* - region list object has been properly dest- */ 110 | /* oyed. */ 111 | /*******************************************************/ 112 | 113 | RegionList::~RegionList( void ) 114 | { 115 | //de-allocate memory... 116 | delete [] regionList; 117 | delete [] indexTable; 118 | 119 | //done. 120 | return; 121 | } 122 | 123 | /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 124 | /*** Region List Manipulation ***/ 125 | /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ 126 | 127 | /*******************************************************/ 128 | /*Add Region */ 129 | /*******************************************************/ 130 | /*Adds a region to the region list. */ 131 | /*******************************************************/ 132 | /*Pre: */ 133 | /* - label is a positive integer used to uniquely */ 134 | /* identify a region */ 135 | /* - pointCount is the number of N-dimensional */ 136 | /* data points that exist in the region being */ 137 | /* classified. */ 138 | /* - indeces is a set of indeces specifying the */ 139 | /* data points contained within this region */ 140 | /* - pointCount must be > 0 */ 141 | /*Post: */ 142 | /* - a new region labeled using label and contai- */ 143 | /* ning pointCount number of points has been */ 144 | /* added to the region list. */ 145 | /*******************************************************/ 146 | void RegionList::AddRegion(int label, int pointCount, int *indeces) 147 | { 148 | //make sure that there is enough room for this new region 149 | //in the region list array... 150 | if(numRegions >= maxRegions) 151 | ErrorHandler("AddRegion", "Not enough memory allocated.", FATAL); 152 | 153 | //make sure that label is positive and point Count > 0... 154 | if((label < 0)||(pointCount <= 0)) 155 | ErrorHandler("AddRegion", "Label is negative or number of points in region is invalid.", FATAL); 156 | 157 | //make sure that there is enough memory in the indexTable 158 | //for this region... 159 | if((freeBlockLoc + pointCount) > L) 160 | ErrorHandler("AddRegion", "Adding more points than what is contained in data set.", FATAL); 161 | 162 | //place new region into region list array using 163 | //freeRegion index 164 | regionList[freeRegion].label = label; 165 | regionList[freeRegion].pointCount = pointCount; 166 | regionList[freeRegion].region = freeBlockLoc; 167 | 168 | //copy indeces into indexTable using freeBlock... 169 | int i; 170 | for(i = 0; i < pointCount; i++) 171 | indexTable[freeBlockLoc+i] = indeces[i]; 172 | 173 | //increment freeBlock to point to the next free 174 | //block 175 | freeBlockLoc += pointCount; 176 | 177 | //increment freeRegion to point to the next free region 178 | //also, increment numRegions to indicate that another 179 | //region has been added to the region list 180 | freeRegion++; 181 | numRegions++; 182 | 183 | //done. 184 | return; 185 | 186 | } 187 | 188 | /*******************************************************/ 189 | /*Reset */ 190 | /*******************************************************/ 191 | /*Resets the region list. */ 192 | /*******************************************************/ 193 | /*Post: */ 194 | /* - the region list has been reset. */ 195 | /*******************************************************/ 196 | 197 | void RegionList::Reset( void ) 198 | { 199 | 200 | //reset region list 201 | freeRegion = numRegions = freeBlockLoc = 0; 202 | 203 | //done. 204 | return; 205 | 206 | } 207 | 208 | /*/\/\/\/\/\/\/\/\/\/\*/ 209 | /* Query Region List */ 210 | /*\/\/\/\/\/\/\/\/\/\/*/ 211 | 212 | /*******************************************************/ 213 | /*Get Number Regions */ 214 | /*******************************************************/ 215 | /*Returns the number of regions stored by region list. */ 216 | /*******************************************************/ 217 | /*Post: */ 218 | /* - the number of regions stored by the region */ 219 | /* list is returned. */ 220 | /*******************************************************/ 221 | 222 | int RegionList::GetNumRegions( void ) 223 | { 224 | // return region count 225 | return numRegions; 226 | } 227 | 228 | /*******************************************************/ 229 | /*Get Label */ 230 | /*******************************************************/ 231 | /*Returns the label of a specified region. */ 232 | /*******************************************************/ 233 | /*Pre: */ 234 | /* - regionNum is an index into the region list */ 235 | /* array. */ 236 | /*Post: */ 237 | /* - the label of the region having region index */ 238 | /* specified by regionNum has been returned. */ 239 | /*******************************************************/ 240 | 241 | int RegionList::GetLabel(int regionNum) 242 | { 243 | //return the label of a specified region 244 | return regionList[regionNum].label; 245 | } 246 | 247 | /*******************************************************/ 248 | /*Get Region Count */ 249 | /*******************************************************/ 250 | /*Returns the point count of a specified region. */ 251 | /*******************************************************/ 252 | /*Pre: */ 253 | /* - regionNum is an index into the region list */ 254 | /* array. */ 255 | /*Post: */ 256 | /* - the number of points that classify the */ 257 | /* region whose index is specified by regionNum */ 258 | /* is returned. */ 259 | /*******************************************************/ 260 | 261 | int RegionList::GetRegionCount(int regionNum) 262 | { 263 | //return the region count of a specified region 264 | return regionList[regionNum].pointCount; 265 | } 266 | 267 | /*******************************************************/ 268 | /*Get Region Indeces */ 269 | /*******************************************************/ 270 | /*Returns the point indeces specifying a region. */ 271 | /*******************************************************/ 272 | /*Pre: */ 273 | /* - regionNum is an index into the region list */ 274 | /* array. */ 275 | /*Post: */ 276 | /* - the region indeces specifying the points */ 277 | /* contained by the region specified by region- */ 278 | /* Num are returned. */ 279 | /*******************************************************/ 280 | 281 | int *RegionList::GetRegionIndeces(int regionNum) 282 | { 283 | //return point indeces using regionNum 284 | return &indexTable[regionList[regionNum].region]; 285 | } 286 | 287 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 288 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 289 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PRIVATE METHODS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 290 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 291 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 292 | 293 | /*/\/\/\/\/\/\/\/\/\/\/\*/ 294 | /* Class Error Handler */ 295 | /*\/\/\/\/\/\/\/\/\/\/\/*/ 296 | 297 | /*******************************************************/ 298 | /*Error Handler */ 299 | /*******************************************************/ 300 | /*Class error handler. */ 301 | /*******************************************************/ 302 | /*Pre: */ 303 | /* - functName is the name of the function that */ 304 | /* caused an error */ 305 | /* - errmsg is the error message given by the */ 306 | /* calling function */ 307 | /* - status is the error status: FATAL or NON- */ 308 | /* FATAL */ 309 | /*Post: */ 310 | /* - the error message errmsg is flagged on beh- */ 311 | /* ave of function functName. */ 312 | /* - if the error status is FATAL then the program*/ 313 | /* is halted, otherwise execution is continued, */ 314 | /* error recovery is assumed to be handled by */ 315 | /* the calling function. */ 316 | /*******************************************************/ 317 | 318 | void RegionList::ErrorHandler(char *functName, char* errmsg, ErrorType status) 319 | { 320 | 321 | //flag error message on behalf of calling function, error format 322 | //specified by the error status... 323 | if(status == NONFATAL) 324 | fprintf(stderr, "\n%s Error: %s\n", functName, errmsg); 325 | else 326 | { 327 | fprintf(stderr, "\n%s Fatal Error: %s\n\nAborting Program.\n\n", functName, errmsg); 328 | exit(1); 329 | } 330 | 331 | } 332 | 333 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 334 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 335 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 336 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 337 | /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ 338 | -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShift/rlist.h: -------------------------------------------------------------------------------- 1 | /******************************************************* 2 | 3 | Mean Shift Analysis Library 4 | ============================================= 5 | 6 | 7 | The mean shift library is a collection of routines 8 | that use the mean shift algorithm. Using this algorithm, 9 | the necessary output will be generated needed 10 | to analyze a given input set of data. 11 | 12 | Region List Class: 13 | ================= 14 | 15 | During segmentation, data regions are defined. The 16 | RegionList class provides a mechanism for doing so, as 17 | well as defines some basic operations, such as region 18 | growing or small region pruning, on the defined regions. 19 | The prototype for the RegionList class is provided below. It 20 | is defined in "region.cc". 21 | 22 | The theory is described in the papers: 23 | 24 | D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature 25 | space analysis. 26 | 27 | C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. 28 | 29 | and they are is available at: 30 | http://www.caip.rutgers.edu/riul/research/papers/ 31 | 32 | Implemented by Chris M. Christoudias, Bogdan Georgescu 33 | ********************************************************/ 34 | 35 | 36 | 37 | #ifndef RLIST_H 38 | #define RLIST_H 39 | 40 | //include global type definitions 41 | #include "tdef.h" 42 | 43 | using namespace SEG; 44 | 45 | namespace SEG{ 46 | //define region structure 47 | struct REGION { 48 | int label; 49 | int pointCount; 50 | int region; 51 | 52 | }; 53 | 54 | //region class prototype... 55 | class RegionList { 56 | 57 | public: 58 | 59 | /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 60 | /* Class Constructor and Destructor */ 61 | /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ 62 | 63 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 64 | //<--------------------------------------------------->|// 65 | //| |// 66 | //| Method Name: |// 67 | //| ============ |// 68 | //| * Class Constructor * |// 69 | //| |// 70 | //<--------------------------------------------------->|// 71 | //| |// 72 | //| Description: |// 73 | //| ============ |// 74 | //| |// 75 | //| Constructs a region list object. |// 76 | //| |// 77 | //| Its arguments are: |// 78 | //| |// 79 | //| <* maxRegions *> |// 80 | //| The maximum amount of regions that can be class- |// 81 | //| ified by the region list. |// 82 | //| |// 83 | //| <* L *> |// 84 | //| The length of the input data set being class- |// 85 | //| ified by the region list object. |// 86 | //| |// 87 | //| <* N *> |// 88 | //| The dimension of the input data set being class- |// 89 | //| ified by the region list object. |// 90 | //| |// 91 | //<--------------------------------------------------->|// 92 | //| |// 93 | //| Usage: |// 94 | //| ====== |// 95 | //| RegionList(maxRegions, L, N) |// 96 | //| |// 97 | //<--------------------------------------------------->|// 98 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 99 | 100 | RegionList(int, int, int); 101 | 102 | // Class Destructor 103 | ~RegionList( void ); 104 | 105 | /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 106 | /* Region List Manipulation */ 107 | /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/ 108 | 109 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 110 | //<--------------------------------------------------->|// 111 | //| |// 112 | //| Method Name: |// 113 | //| ============ |// 114 | //| * Add Region * |// 115 | //| |// 116 | //<--------------------------------------------------->|// 117 | //| |// 118 | //| Description: |// 119 | //| ============ |// 120 | //| |// 121 | //| Adds a region to the region list. |// 122 | //| |// 123 | //| Its arguments are: |// 124 | //| |// 125 | //| <* label *> |// 126 | //| |// 127 | //| A positive integer used to uniquely identify |// 128 | //| a region. |// 129 | //| |// 130 | //| <* pointCount *> |// 131 | //| A positive integer that specifies the number of |// 132 | //| N-dimensional data points that exist in the re- |// 133 | //| gion being classified. |// 134 | //| |// 135 | //| <* indeces *> |// 136 | //| An integer array that specifies the set of ind- |// 137 | //| eces of the data points that are contianed with- |// 138 | //| in this region. |// 139 | //| |// 140 | //<--------------------------------------------------->|// 141 | //| |// 142 | //| Usage: |// 143 | //| ====== |// 144 | //| AddRegion(label, pointCount, indeces) |// 145 | //| |// 146 | //<--------------------------------------------------->|// 147 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 148 | 149 | void AddRegion(int, int, int*); 150 | 151 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 152 | //<--------------------------------------------------->|// 153 | //| |// 154 | //| Method Name: |// 155 | //| ============ |// 156 | //| * Reset * |// 157 | //| |// 158 | //<--------------------------------------------------->|// 159 | //| |// 160 | //| Description: |// 161 | //| ============ |// 162 | //| |// 163 | //| Resets the region list for re-use (for new |// 164 | //| classification). |// 165 | //| |// 166 | //<--------------------------------------------------->|// 167 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 168 | 169 | void Reset( void ); 170 | 171 | /*/\/\/\/\/\/\/\/\/\/\*/ 172 | /* Query Region List */ 173 | /*\/\/\/\/\/\/\/\/\/\/*/ 174 | 175 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 176 | //<--------------------------------------------------->|// 177 | //| |// 178 | //| Method Name: |// 179 | //| ============ |// 180 | //| * Get Number of Regions * |// 181 | //| |// 182 | //<--------------------------------------------------->|// 183 | //| |// 184 | //| Description: |// 185 | //| ============ |// 186 | //| |// 187 | //| Returns the number of regions stored by the |// 188 | //| region list. |// 189 | //| |// 190 | //<--------------------------------------------------->|// 191 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 192 | 193 | int GetNumRegions ( void ); 194 | 195 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 196 | //<--------------------------------------------------->|// 197 | //| |// 198 | //| Method Name: |// 199 | //| ============ |// 200 | //| * Get Label * |// 201 | //| |// 202 | //<--------------------------------------------------->|// 203 | //| |// 204 | //| Description: |// 205 | //| ============ |// 206 | //| |// 207 | //| Returns the label of a specified region. |// 208 | //| |// 209 | //| Its arguments are: |// 210 | //| |// 211 | //| <* regionNumber *> |// 212 | //| The index of the region in the region list |// 213 | //| array. |// 214 | //| |// 215 | //<--------------------------------------------------->|// 216 | //| |// 217 | //| Usage: |// 218 | //| ====== |// 219 | //| label = GetLabel(regionNumber) |// 220 | //| |// 221 | //<--------------------------------------------------->|// 222 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 223 | 224 | int GetLabel(int); 225 | 226 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 227 | //<--------------------------------------------------->|// 228 | //| |// 229 | //| Method Name: |// 230 | //| ============ |// 231 | //| * Get Region Count * |// 232 | //| |// 233 | //<--------------------------------------------------->|// 234 | //| |// 235 | //| Description: |// 236 | //| ============ |// 237 | //| |// 238 | //| Returns number of data points contained by a sp- |// 239 | //| ecified region. |// 240 | //| |// 241 | //| Its arguments are: |// 242 | //| |// 243 | //| <* regionNumber *> |// 244 | //| The index of the region in the region list |// 245 | //| array. |// 246 | //| |// 247 | //<--------------------------------------------------->|// 248 | //| |// 249 | //| Usage: |// 250 | //| ====== |// 251 | //| pointCount = GetRegionCount(regionNumber) |// 252 | //| |// 253 | //<--------------------------------------------------->|// 254 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 255 | 256 | int GetRegionCount(int); 257 | 258 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 259 | //<--------------------------------------------------->|// 260 | //| |// 261 | //| Method Name: |// 262 | //| ============ |// 263 | //| * Get Region Indeces * |// 264 | //| |// 265 | //<--------------------------------------------------->|// 266 | //| |// 267 | //| Description: |// 268 | //| ============ |// 269 | //| |// 270 | //| Returns a pointer to a set of grid location ind- |// 271 | //| eces specifying the data points belonging to a |// 272 | //| specified region. |// 273 | //| |// 274 | //| Its arguments are: |// 275 | //| |// 276 | //| <* regionNumber *> |// 277 | //| The index of the region in the region list |// 278 | //| array. |// 279 | //| |// 280 | //<--------------------------------------------------->|// 281 | //| |// 282 | //| Usage: |// 283 | //| ====== |// 284 | //| indeces = GetRegionIndeces(regionNumber) |// 285 | //| |// 286 | //<--------------------------------------------------->|// 287 | //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||// 288 | 289 | int*GetRegionIndeces(int); 290 | 291 | private: 292 | 293 | /*/\/\/\/\/\/\/\/\/\/\/\*/ 294 | /* Class Error Handler */ 295 | /*\/\/\/\/\/\/\/\/\/\/\/*/ 296 | 297 | void ErrorHandler(char*, char*, ErrorType); 298 | 299 | //============================= 300 | // *** Private Data Members *** 301 | //============================= 302 | 303 | //##################################### 304 | //### REGION LIST PARTITIONED ARRAY ### 305 | //##################################### 306 | 307 | REGION *regionList; //array of maxRegions regions 308 | int minRegion; 309 | 310 | int maxRegions; //defines the number maximum number of regions 311 | //allowed (determined by user during class construction) 312 | int numRegions; //the number of regions currently stored by the 313 | //region list 314 | int freeRegion; //an index into the regionList pointing to the next 315 | //available region in the regionList 316 | 317 | //##################################### 318 | //### INDEX TABLE ### 319 | //##################################### 320 | 321 | int *indexTable; //an array of indexes that point into an external structure 322 | //specifying which points belong to a region 323 | int freeBlockLoc; //points to the next free block of memory in the indexTable 324 | 325 | //##################################### 326 | //### INPUT DATA PARAMETERS ### 327 | //##################################### 328 | 329 | //Dimension of data set 330 | int N; //dimension of data set being classified by region list 331 | //class 332 | 333 | //Length of the data set 334 | int L; //number of points contained by the data set being classified by 335 | //region list class 336 | 337 | }; 338 | 339 | #endif 340 | 341 | } 342 | 343 | -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShift/tdef.h: -------------------------------------------------------------------------------- 1 | /******************************************************* 2 | 3 | Mean Shift Analysis Library 4 | ============================================= 5 | 6 | The mean shift library is a collection of routines 7 | that use the mean shift algorithm. Using this algorithm, 8 | the necessary output will be generated needed 9 | to analyze a given input set of data. 10 | 11 | Type Defintions: 12 | =============== 13 | 14 | This header file contains the type defintions and 15 | enumerations shared among the various classes of the mean 16 | shift library. 17 | 18 | The theory is described in the papers: 19 | 20 | D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature 21 | space analysis. 22 | 23 | C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision. 24 | 25 | and they are is available at: 26 | http://www.caip.rutgers.edu/riul/research/papers/ 27 | 28 | Implemented by Chris M. Christoudias, Bogdan Georgescu 29 | ********************************************************/ 30 | 31 | namespace SEG{ 32 | 33 | 34 | #ifndef TDEF_H 35 | #define TDEF_H 36 | 37 | /*/\/\/\/\/\/\/\/\/\/\/\*/ 38 | /* Define Enumerations */ 39 | /*\/\/\/\/\/\/\/\/\/\/\/*/ 40 | 41 | //Kernel 42 | enum kernelType {Uniform, Gaussian, UserDefined}; 43 | 44 | // kd-Tree 45 | enum childType {LEFT, RIGHT}; 46 | 47 | // Speed Up Level 48 | enum SpeedUpLevel {NO_SPEEDUP, MED_SPEEDUP, HIGH_SPEEDUP}; 49 | 50 | // Error Handler 51 | enum ErrorLevel {EL_OKAY, EL_ERROR, EL_HALT}; 52 | enum ErrorType {NONFATAL, FATAL}; 53 | 54 | #endif 55 | } -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShiftSegmentor.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/MeanShiftSegmentor.cpp -------------------------------------------------------------------------------- /BasicImageSegmentation/MeanShiftSegmentor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "segmentor.h" 4 | #include "MeanShift/msImageProcessor.h" 5 | 6 | 7 | 8 | class MeanShiftSegmentor : 9 | public Segmentor 10 | { 11 | DECLARE_DYNCRT_CLASS(MeanShiftSegmentor, Segmentor); 12 | 13 | public: 14 | MeanShiftSegmentor(void); 15 | ~MeanShiftSegmentor(void); 16 | 17 | virtual void SetArgs(const vector _args); 18 | 19 | virtual void Run(); 20 | 21 | private: 22 | int m_SigmaS; 23 | float m_SigmaR; 24 | int m_MinRegion; 25 | SpeedUpLevel m_SpeedUpLevel; 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /BasicImageSegmentation/OneCutSegmentor.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/OneCutSegmentor.cpp -------------------------------------------------------------------------------- /BasicImageSegmentation/OneCutSegmentor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "segmentor.h" 4 | #include "multi-labelGraphCut/graph.h" 5 | 6 | const float INT32_CONST = 1000; 7 | const float HARD_CONSTRAINT_CONST = 1000; 8 | 9 | #define NEIGHBORHOOD_8_TYPE 1; 10 | #define NEIGHBORHOOD_25_TYPE 2; 11 | 12 | const int NEIGHBORHOOD = NEIGHBORHOOD_8_TYPE; 13 | 14 | class OneCutSegmentor : 15 | public Segmentor 16 | { 17 | DECLARE_DYNCRT_CLASS(OneCutSegmentor, Segmentor); 18 | 19 | public: 20 | OneCutSegmentor(void); 21 | ~OneCutSegmentor(void); 22 | 23 | virtual void SetArgs(const vector _args); 24 | 25 | virtual void Run(); 26 | 27 | private: 28 | static void onMouse(int event, int x, int y, int flags, void* param); 29 | 30 | void showImage(); 31 | 32 | string m_WinName; 33 | string m_ResultWinName; 34 | void init(); 35 | void getBinPerPixel(); 36 | void getEdgeVariance(); 37 | void doSegmente(); 38 | void releaseAll(); 39 | 40 | 41 | Mat showImg, binPerPixelImg, segMask, segShowImg; 42 | Mat scribbleMask; 43 | 44 | bool m_isDrawing; 45 | bool m_isForeground; 46 | Point m_PrevPoint; 47 | 48 | int numUsedBins; 49 | float varianceSquared; 50 | 51 | // default arguments 52 | float bha_slope; 53 | int numBinsPerChannel; 54 | 55 | GraphType *myGraph; 56 | }; 57 | 58 | -------------------------------------------------------------------------------- /BasicImageSegmentation/SEEDS/README.txt: -------------------------------------------------------------------------------- 1 | http://www.mvdblive.org/seeds/ 2 | This is the source code to SEEDS superpixels, as described in M. Van den Bergh, X. Boix, G. Roig, B. de Capitani and L. Van Gool, "SEEDS: Superpixels Extracted via Energy-Driven Sampling", ECCV 2012. 3 | 4 | The SEEDS class is defined in seeds.h and seeds2.cpp. The method can be run on an RGB image (stored in an UINT* array) by using the following constructor, initialization and iteration methods: 5 | 6 | SEEDS(int width, int height, int nr_channels, int nr_bins, int min_size); 7 | void initialize(UINT* image, int seeds_w, int seeds_h, int nr_levels); 8 | void iterate(); 9 | 10 | The initial size of the superpixels is independent from the image size, and defined by the following 3 parameters: , and . The first two define the minimum block size in the SEEDS algorithm. The defines the number of times this block size is doubled to reach the superpixel size. The superpixel size (width x height) is defined as follows: (seed_width*2^(nr_levels-1) x seed_height*2^(nr_levels-1)). 11 | 12 | For example, if (seed_width x seed_height) = (3x4) and nr_levels = 4, then the initial superpixels will be rectangular and of size (3*2^3 x 4*2^3) = (24x32). Provided an image of size (480x320), this results in 20*10 = 200 superpixels. 13 | 14 | 15 | Furthermore, a mex file is provided for use in Matlab. 16 | 17 | 18 | Disclaimer: the author of the code or ETH Zurich are not responsible for any damages that may result from using this code. 19 | Copyright (c) 2012 Michael Van den Bergh (ETH Zurich). All rights reserved. 20 | -------------------------------------------------------------------------------- /BasicImageSegmentation/SEEDS/ReadMe.md: -------------------------------------------------------------------------------- 1 | Paper 2 | ====================== 3 | M. Van den Bergh, X. Boix, G. Roig, B. de Capitani and L. Van Gool, "SEEDS: Superpixels Extracted via Energy-Driven Sampling", ECCV 2012. 4 | 5 | SourceCode 6 | ====================== 7 | http://www.mvdblive.org/seeds/ -------------------------------------------------------------------------------- /BasicImageSegmentation/SEEDS/seeds2.h: -------------------------------------------------------------------------------- 1 | // ****************************************************************************** 2 | // SEEDS Superpixels 3 | // ****************************************************************************** 4 | // Author: Beat Kueng based on Michael Van den Bergh's code 5 | // Contact: vamichae@vision.ee.ethz.ch 6 | // 7 | // This code implements the superpixel method described in: 8 | // M. Van den Bergh, X. Boix, G. Roig, B. de Capitani and L. Van Gool, 9 | // "SEEDS: Superpixels Extracted via Energy-Driven Sampling", 10 | // ECCV 2012 11 | // 12 | // Copyright (c) 2012 Michael Van den Bergh (ETH Zurich). All rights reserved. 13 | // ****************************************************************************** 14 | 15 | #if !defined(_SEEDS_H_INCLUDED_) 16 | #define _SEEDS_H_INCLUDED_ 17 | 18 | #include 19 | 20 | using namespace std; 21 | 22 | typedef unsigned int UINT; 23 | 24 | 25 | class SEEDS 26 | { 27 | public: 28 | SEEDS(int width, int height, int nr_channels, int nr_bins); 29 | ~SEEDS(); 30 | 31 | // initialize. this needs to be called only once 32 | //the number of superpixels is: 33 | // (image_width/seeds_w/(2^(nr_levels-1))) * (image_height/seeds_h/(2^(nr_levels-1))) 34 | void initialize(int seeds_w, int seeds_h, int nr_levels); 35 | 36 | //set a new image in YCbCr format 37 | //image must have the same size as in the constructor was given 38 | void update_image_ycbcr(UINT* image); 39 | 40 | // go through iterations 41 | void iterate(); 42 | 43 | UINT* get_labels() { return labels[seeds_top_level]; } 44 | // output labels 45 | UINT** labels; //[level][y * width + x] 46 | 47 | // evaluation 48 | int count_superpixels(); 49 | void SaveLabels_Text(string filename); 50 | 51 | // mean colors 52 | void compute_mean_map(); 53 | UINT* means; 54 | 55 | private: 56 | void deinitialize(); 57 | 58 | bool initialized; 59 | 60 | // seeds 61 | int seeds_w; 62 | int seeds_h; 63 | int seeds_nr_levels; 64 | int seeds_top_level; // == seeds_nr_levels-1 (const) 65 | int seeds_current_level; //start with level seeds_top_level-1, then go down 66 | 67 | // image processing 68 | float* image_l; //input image 69 | float* image_a; 70 | float* image_b; 71 | UINT* image_bins; //bin index (histogram) of each image pixel [y*width + x] 72 | float* bin_cutoff1; //for each bin: define upper limit of L value used to calc bin index from color value 73 | float* bin_cutoff2; //for each bin: define upper limit of a value 74 | float* bin_cutoff3; //for each bin: define upper limit of b value 75 | 76 | // keep one labeling for each level 77 | UINT* nr_labels; //[level] 78 | UINT** parent; //[level][label] = corresponding label of block with level+1 79 | UINT** nr_partitions; //[level][label] how many partitions label has on level-1 80 | int** T; //[level][label] how many pixels with this label 81 | int go_down_one_level(); 82 | 83 | // initialization 84 | void assign_labels(); 85 | void compute_histograms(int until_level = -1); 86 | void compute_means(); 87 | //void lab_get_histogram_cutoff_values(const Image& image); 88 | 89 | // color conversion and histograms 90 | int RGB2HSV(const int& r, const int& g, const int& b, float* hval, float* sval, float* vval); 91 | int RGB2LAB(const int& r, const int& g, const int& b, float* lval, float* aval, float* bval); 92 | int LAB2bin(float l, float a, float b); 93 | int RGB2LAB_special(int r, int g, int b, float* lval, float* aval, float* bval); 94 | int RGB2LAB_special(int r, int g, int b, int* bin_l, int* bin_a, int* bin_b); 95 | void LAB2RGB(float L, float a, float b, int* R, int* G, int* B); 96 | 97 | int histogram_size; //= nr_bins ^ 3 (3 channels) 98 | int*** histogram; //[level][label][j < histogram_size] 99 | 100 | 101 | void update(int level, int label_new, int x, int y); 102 | void add_pixel(int level, int label, int x, int y); 103 | void add_pixel_m(int level, int label, int x, int y); 104 | void delete_pixel(int level, int label, int x, int y); 105 | void delete_pixel_m(int level, int label, int x, int y); 106 | void add_block(int level, int label, int sublevel, int sublabel); 107 | void delete_block(int level, int label, int sublevel, int sublabel); 108 | void update_labels(int level); 109 | 110 | 111 | // probability computation 112 | bool probability(int color, int label1, int label2, int prior1, int prior2); 113 | bool probability_means(float L, float a, float b, int label1, int label2, int prior1, int prior2); 114 | 115 | int threebythree(int x, int y, UINT label); 116 | int threebyfour(int x, int y, UINT label); 117 | int fourbythree(int x, int y, UINT label); 118 | 119 | 120 | // block updating 121 | void update_blocks(int level, float req_confidence = 0.0); 122 | float intersection(int level1, int label1, int level2, int label2); 123 | 124 | // border updating 125 | void update_pixels(); 126 | void update_pixels_means(); 127 | bool forwardbackward; 128 | int threebythree_upperbound; 129 | int threebythree_lowerbound; 130 | 131 | inline bool check_split(int a11, int a12, int a13, int a21, int a22, 132 | int a23, int a31, int a32, int a33, bool horizontal, bool forward); 133 | 134 | int* nr_w; //[level] number of seeds in x-direction 135 | int* nr_h; 136 | 137 | float* L_channel; 138 | float* A_channel; 139 | float* B_channel; 140 | int width, height, nr_channels, nr_bins; 141 | }; 142 | 143 | 144 | 145 | 146 | #endif // !defined(_SEEDS_H_INCLUDED_) 147 | -------------------------------------------------------------------------------- /BasicImageSegmentation/SEEDSSegmentor.cpp: -------------------------------------------------------------------------------- 1 | #include "SEEDSSegmentor.h" 2 | 3 | //IMPLEMENT_DYNCRT_CLASS(SEEDSSegmentor); 4 | 5 | SEEDSSegmentor::SEEDSSegmentor(void) 6 | { 7 | m_Name = "SEEDS"; 8 | 9 | m_NumRegions = 266; 10 | 11 | m_argNum = 1; 12 | } 13 | 14 | SEEDSSegmentor::~SEEDSSegmentor(void) 15 | { 16 | } 17 | 18 | void SEEDSSegmentor::SetArgs(const vector _args) 19 | { 20 | cout<<"["<m_argNum ? m_argNum : _args.size())<<" argument(s)"; 25 | int i = 0; 26 | for ( ; i < _args.size(); i++) 27 | { 28 | cout<<", "<<"setting "<width; 51 | int height = img->height; 52 | int sz = height*width; 53 | 54 | UINT* ubuff = new UINT[sz]; 55 | for (int i = 0; i < img->height; i++) 56 | { 57 | for (int j = 0; j < img->width; j++) 58 | { 59 | cv::Vec3b bgr = m_Img.at(i, j); 60 | ubuff[i*img->width+j] = (bgr[2]<<16) | (bgr[1]<<8) | (bgr[0]); 61 | } 62 | } 63 | 64 | int NR_BINS = 5; // Number of bins in each histogram channel 65 | 66 | SEEDS seeds(width, height, 3, NR_BINS); 67 | 68 | int nr_superpixels = m_NumRegions; 69 | // NOTE: the following values are defined for images from the BSD300 or BSD500 data set. 70 | // If the input image size differs from 480x320, the following values might no longer be 71 | // accurate. 72 | // For more info on how to select the superpixel sizes, please refer to README.TXT. 73 | int seed_width = 3; int seed_height = 4; int nr_levels = 4; 74 | if (width >= height) 75 | { 76 | if (nr_superpixels == 600) {seed_width = 2; seed_height = 2; nr_levels = 4;} 77 | if (nr_superpixels == 400) {seed_width = 3; seed_height = 2; nr_levels = 4;} 78 | if (nr_superpixels == 266) {seed_width = 3; seed_height = 3; nr_levels = 4;} 79 | if (nr_superpixels == 200) {seed_width = 3; seed_height = 4; nr_levels = 4;} 80 | if (nr_superpixels == 150) {seed_width = 2; seed_height = 2; nr_levels = 5;} 81 | if (nr_superpixels == 100) {seed_width = 3; seed_height = 2; nr_levels = 5;} 82 | if (nr_superpixels == 50) {seed_width = 3; seed_height = 4; nr_levels = 5;} 83 | if (nr_superpixels == 25) {seed_width = 3; seed_height = 2; nr_levels = 6;} 84 | if (nr_superpixels == 17) {seed_width = 3; seed_height = 3; nr_levels = 6;} 85 | if (nr_superpixels == 12) {seed_width = 3; seed_height = 4; nr_levels = 6;} 86 | if (nr_superpixels == 9) {seed_width = 2; seed_height = 2; nr_levels = 7;} 87 | if (nr_superpixels == 6) {seed_width = 3; seed_height = 2; nr_levels = 7;} 88 | } 89 | else 90 | { 91 | if (nr_superpixels == 600) {seed_width = 2; seed_height = 2; nr_levels = 4;} 92 | if (nr_superpixels == 400) {seed_width = 2; seed_height = 3; nr_levels = 4;} 93 | if (nr_superpixels == 266) {seed_width = 3; seed_height = 3; nr_levels = 4;} 94 | if (nr_superpixels == 200) {seed_width = 4; seed_height = 3; nr_levels = 4;} 95 | if (nr_superpixels == 150) {seed_width = 2; seed_height = 2; nr_levels = 5;} 96 | if (nr_superpixels == 100) {seed_width = 2; seed_height = 3; nr_levels = 5;} 97 | if (nr_superpixels == 50) {seed_width = 4; seed_height = 3; nr_levels = 5;} 98 | if (nr_superpixels == 25) {seed_width = 2; seed_height = 3; nr_levels = 6;} 99 | if (nr_superpixels == 17) {seed_width = 3; seed_height = 3; nr_levels = 6;} 100 | if (nr_superpixels == 12) {seed_width = 4; seed_height = 3; nr_levels = 6;} 101 | if (nr_superpixels == 9) {seed_width = 2; seed_height = 2; nr_levels = 7;} 102 | if (nr_superpixels == 6) {seed_width = 2; seed_height = 3; nr_levels = 7;} 103 | } 104 | seeds.initialize(seed_width, seed_height, nr_levels); 105 | seeds.update_image_ycbcr(ubuff); 106 | seeds.iterate(); 107 | //int n_Seeds = seeds.count_superpixels(); 108 | 109 | int* labels = (int*)seeds.get_labels(); 110 | 111 | for (int i = 0; i < img->height; i++) 112 | { 113 | int* ptr = m_Result.ptr(i); 114 | for (int j = 0; j < img->width; j++) 115 | { 116 | ptr[j] = labels[i*img->width+j]; 117 | } 118 | } 119 | 120 | delete[] ubuff; 121 | 122 | Segmentor::Run(); 123 | } -------------------------------------------------------------------------------- /BasicImageSegmentation/SEEDSSegmentor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "segmentor.h" 4 | #include "SEEDS/seeds2.h" 5 | 6 | class SEEDSSegmentor : 7 | public Segmentor 8 | { 9 | DECLARE_DYNCRT_CLASS(SEEDSSegmentor, Segmentor); 10 | 11 | public: 12 | SEEDSSegmentor(void); 13 | ~SEEDSSegmentor(void); 14 | 15 | virtual void SetArgs(const vector _args); 16 | 17 | virtual void Run(); 18 | 19 | private: 20 | int m_NumRegions; 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /BasicImageSegmentation/SLIC/README.md: -------------------------------------------------------------------------------- 1 | Paper 2 | ====================== 3 | Achanta R, Shaji A, Smith K, et al. SLIC superpixels compared to state-of-the-art superpixel methods[J]. Pattern Analysis and Machine Intelligence, IEEE Transactions on, 2012, 34(11): 2274-2282. 4 | 5 | SourceCode 6 | ====================== 7 | http://ivrg.epfl.ch/research/superpixels -------------------------------------------------------------------------------- /BasicImageSegmentation/SLIC/SLIC.h: -------------------------------------------------------------------------------- 1 | // SLIC.h: interface for the SLIC class. 2 | //=========================================================================== 3 | // This code implements the zero parameter superpixel segmentation technique 4 | // described in: 5 | // 6 | // 7 | // 8 | // "SLIC Superpixels Compared to State-of-the-art Superpixel Methods" 9 | // 10 | // Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi, Pascal Fua, 11 | // and Sabine Susstrunk, 12 | // 13 | // IEEE TPAMI, Volume 34, Issue 11, Pages 2274-2282, November 2012. 14 | // 15 | // 16 | //=========================================================================== 17 | // Copyright (c) 2013 Radhakrishna Achanta. 18 | // 19 | // For commercial use please contact the author: 20 | // 21 | // Email: firstname.lastname@epfl.ch 22 | //=========================================================================== 23 | 24 | #if !defined(_SLIC_H_INCLUDED_) 25 | #define _SLIC_H_INCLUDED_ 26 | 27 | 28 | #include 29 | #include 30 | #include 31 | using namespace std; 32 | 33 | 34 | class SLIC 35 | { 36 | public: 37 | SLIC(); 38 | virtual ~SLIC(); 39 | //============================================================================ 40 | // Superpixel segmentation for a given step size (superpixel size ~= step*step) 41 | //============================================================================ 42 | void PerformSLICO_ForGivenStepSize( 43 | const unsigned int* ubuff,//Each 32 bit unsigned int contains ARGB pixel values. 44 | const int width, 45 | const int height, 46 | int* klabels, 47 | int& numlabels, 48 | const int& STEP, 49 | const double& m); 50 | //============================================================================ 51 | // Superpixel segmentation for a given number of superpixels 52 | //============================================================================ 53 | void PerformSLICO_ForGivenK( 54 | const unsigned int* ubuff,//Each 32 bit unsigned int contains ARGB pixel values. 55 | const int width, 56 | const int height, 57 | int* klabels, 58 | int& numlabels, 59 | const int& K, 60 | const double& m); 61 | 62 | //============================================================================ 63 | // Save superpixel labels in a text file in raster scan order 64 | //============================================================================ 65 | void SaveSuperpixelLabels( 66 | const int* labels, 67 | const int& width, 68 | const int& height, 69 | const string& filename, 70 | const string& path); 71 | //============================================================================ 72 | // Function to draw boundaries around superpixels of a given 'color'. 73 | // Can also be used to draw boundaries around supervoxels, i.e layer by layer. 74 | //============================================================================ 75 | void DrawContoursAroundSegments( 76 | unsigned int* segmentedImage, 77 | const int* labels, 78 | const int& width, 79 | const int& height, 80 | const unsigned int& color ); 81 | 82 | void DrawContoursAroundSegmentsTwoColors( 83 | unsigned int* ubuff, 84 | const int* labels, 85 | const int& width, 86 | const int& height); 87 | 88 | private: 89 | 90 | //============================================================================ 91 | // Magic SLIC. No need to set M (compactness factor) and S (step size). 92 | // SLICO (SLIC Zero) varies only M dynamicaly, not S. 93 | //============================================================================ 94 | void PerformSuperpixelSegmentation_VariableSandM( 95 | vector& kseedsl, 96 | vector& kseedsa, 97 | vector& kseedsb, 98 | vector& kseedsx, 99 | vector& kseedsy, 100 | int* klabels, 101 | const int& STEP, 102 | const int& NUMITR); 103 | //============================================================================ 104 | // Pick seeds for superpixels when step size of superpixels is given. 105 | //============================================================================ 106 | void GetLABXYSeeds_ForGivenStepSize( 107 | vector& kseedsl, 108 | vector& kseedsa, 109 | vector& kseedsb, 110 | vector& kseedsx, 111 | vector& kseedsy, 112 | const int& STEP, 113 | const bool& perturbseeds, 114 | const vector& edgemag); 115 | //============================================================================ 116 | // Pick seeds for superpixels when number of superpixels is input. 117 | //============================================================================ 118 | void GetLABXYSeeds_ForGivenK( 119 | vector& kseedsl, 120 | vector& kseedsa, 121 | vector& kseedsb, 122 | vector& kseedsx, 123 | vector& kseedsy, 124 | const int& STEP, 125 | const bool& perturbseeds, 126 | const vector& edges); 127 | 128 | //============================================================================ 129 | // Move the seeds to low gradient positions to avoid putting seeds at region boundaries. 130 | //============================================================================ 131 | void PerturbSeeds( 132 | vector& kseedsl, 133 | vector& kseedsa, 134 | vector& kseedsb, 135 | vector& kseedsx, 136 | vector& kseedsy, 137 | const vector& edges); 138 | //============================================================================ 139 | // Detect color edges, to help PerturbSeeds() 140 | //============================================================================ 141 | void DetectLabEdges( 142 | const double* lvec, 143 | const double* avec, 144 | const double* bvec, 145 | const int& width, 146 | const int& height, 147 | vector& edges); 148 | //============================================================================ 149 | // xRGB to XYZ conversion; helper for RGB2LAB() 150 | //============================================================================ 151 | void RGB2XYZ( 152 | const int& sR, 153 | const int& sG, 154 | const int& sB, 155 | double& X, 156 | double& Y, 157 | double& Z); 158 | //============================================================================ 159 | // sRGB to CIELAB conversion 160 | //============================================================================ 161 | void RGB2LAB( 162 | const int& sR, 163 | const int& sG, 164 | const int& sB, 165 | double& lval, 166 | double& aval, 167 | double& bval); 168 | //============================================================================ 169 | // sRGB to CIELAB conversion for 2-D images 170 | //============================================================================ 171 | void DoRGBtoLABConversion( 172 | const unsigned int*& ubuff, 173 | double*& lvec, 174 | double*& avec, 175 | double*& bvec); 176 | //============================================================================ 177 | // sRGB to CIELAB conversion for 3-D volumes 178 | //============================================================================ 179 | void DoRGBtoLABConversion( 180 | const unsigned int**& ubuff, 181 | double**& lvec, 182 | double**& avec, 183 | double**& bvec); 184 | 185 | //============================================================================ 186 | // Post-processing of SLIC segmentation, to avoid stray labels. 187 | //============================================================================ 188 | void EnforceLabelConnectivity( 189 | const int* labels, 190 | const int& width, 191 | const int& height, 192 | int* nlabels,//input labels that need to be corrected to remove stray labels 193 | int& numlabels,//the number of labels changes in the end if segments are removed 194 | const int& K); //the number of superpixels desired by the user 195 | 196 | 197 | private: 198 | int m_width; 199 | int m_height; 200 | int m_depth; 201 | 202 | double* m_lvec; 203 | double* m_avec; 204 | double* m_bvec; 205 | 206 | double** m_lvecvec; 207 | double** m_avecvec; 208 | double** m_bvecvec; 209 | }; 210 | 211 | #endif // !defined(_SLIC_H_INCLUDED_) 212 | -------------------------------------------------------------------------------- /BasicImageSegmentation/SLIC/SLICO.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/SLIC/SLICO.exe -------------------------------------------------------------------------------- /BasicImageSegmentation/SLICSegmentor.cpp: -------------------------------------------------------------------------------- 1 | #include "SLICSegmentor.h" 2 | 3 | //IMPLEMENT_DYNCRT_CLASS(SLICSegmentor); 4 | 5 | SLICSegmentor::SLICSegmentor(void) 6 | { 7 | m_Name = "SLIC"; 8 | 9 | m_Step = 7; 10 | 11 | m_argNum = 1; 12 | } 13 | 14 | SLICSegmentor::~SLICSegmentor(void) 15 | { 16 | } 17 | 18 | void SLICSegmentor::SetArgs(const vector _args) 19 | { 20 | cout<<"["<m_argNum ? m_argNum : _args.size())<<" argument(s)"; 25 | int i = 0; 26 | for ( ; i < _args.size(); i++) 27 | { 28 | cout<<", "<<"setting "<(i, j); 57 | imgData[i*w+j] = (bgr[2]<<16) | (bgr[1]<<8) | (bgr[0]); 58 | } 59 | } 60 | 61 | int numLabels; 62 | int *klabels = new int[h*w]; 63 | slicsp.PerformSLICO_ForGivenStepSize(imgData, w, h, klabels, numLabels, m_Step, NULL); 64 | 65 | for (int i = 0; i < h; i++) 66 | { 67 | int* ptr = m_Result.ptr(i); 68 | for (int j = 0; j < w; j++) 69 | { 70 | ptr[j] = klabels[i*w+j]; 71 | } 72 | } 73 | 74 | delete[] klabels; 75 | delete[] imgData; 76 | 77 | Segmentor::Run(); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /BasicImageSegmentation/SLICSegmentor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "segmentor.h" 4 | #include "SLIC/SLIC.h" 5 | 6 | typedef unsigned int uint; 7 | 8 | class SLICSegmentor : 9 | public Segmentor 10 | { 11 | DECLARE_DYNCRT_CLASS(SLICSegmentor, Segmentor); 12 | 13 | public: 14 | SLICSegmentor(void); 15 | ~SLICSegmentor(void); 16 | 17 | virtual void SetArgs(const vector _args); 18 | 19 | virtual void Run(); 20 | 21 | private: 22 | int m_Step; 23 | }; 24 | -------------------------------------------------------------------------------- /BasicImageSegmentation/Timer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Author: hujiagao@gmail.com 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | class Timer{ 12 | public: 13 | Timer(const string & name="Timer"):_title(name) {_start = false; _startTime = 0;}; 14 | ~Timer() {}; 15 | 16 | void Start() 17 | { 18 | if (! _start) 19 | _start = true; 20 | _startTime = clock(); 21 | }; 22 | 23 | float Stop() 24 | { 25 | if (! _start) 26 | { 27 | return 0; 28 | } 29 | float timecost = float(clock() - _startTime) / CLOCKS_PER_SEC; 30 | _start = false; 31 | cout<<"["<<_title<<"]"<<" Time cost: "< 68 | Andrew Delong 69 | 70 | This software and its modifications can be used and distributed for 71 | research purposes only. Publications resulting from use of this code 72 | must cite publications according to the rules given above. Only 73 | Olga Veksler has the right to redistribute this code, unless expressed 74 | permission is given otherwise. Commercial use of this code, any of 75 | its parts, or its modifications is not permited. The copyright notices 76 | must not be removed in case of any modifications. This Licence 77 | commences on the date it is electronically or physically delivered 78 | to you and continues in effect unless you fail to comply with any of 79 | the terms of the License and fail to cure such breach within 30 days 80 | of becoming aware of the breach, in which case the Licence automatically 81 | terminates. This Licence is governed by the laws of Canada and all 82 | disputes arising from or relating to this Licence must be brought 83 | in Toronto, Ontario. 84 | 85 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 86 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 87 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 88 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 89 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 90 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 91 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 92 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 93 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 94 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 95 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 96 | 97 | ################################################################## 98 | */ 99 | 100 | #ifndef __GCOPTIMIZATION_H__ 101 | #define __GCOPTIMIZATION_H__ 102 | // Due to quiet bugs in function template specialization, it is not 103 | // safe to use earlier MS compilers. 104 | #if defined(_MSC_VER) && _MSC_VER < 1400 105 | #error Requires Visual C++ 2005 (VC8) compiler or later. 106 | #endif 107 | 108 | #include "energy.h" 109 | #include "graph.cpp" 110 | #include "maxflow.cpp" 111 | 112 | ///////////////////////////////////////////////////////////////////// 113 | // Utility functions, classes, and macros 114 | ///////////////////////////////////////////////////////////////////// 115 | 116 | class GCException { 117 | public: 118 | const char* message; 119 | GCException( const char* m ): message(m) { } 120 | void Report(); 121 | }; 122 | 123 | #ifdef _WIN32 124 | typedef __int64 gcoclock_t; 125 | #else 126 | #include 127 | typedef clock_t gcoclock_t; 128 | #endif 129 | extern "C" gcoclock_t gcoclock(); // fairly high-resolution timer... better than clock() when available 130 | extern "C" gcoclock_t GCO_CLOCKS_PER_SEC; // this variable will stay 0 until gcoclock() is called for the first time 131 | 132 | #ifdef _MSC_EXTENSIONS 133 | #define OLGA_INLINE __forceinline 134 | #else 135 | #define OLGA_INLINE inline 136 | #endif 137 | 138 | #ifndef GCO_MAX_ENERGYTERM 139 | #define GCO_MAX_ENERGYTERM 10000000 // maximum safe coefficient to avoid integer overflow 140 | // if a data/smooth/label cost term is larger than this, 141 | // the library will raise an exception 142 | #endif 143 | 144 | 145 | ///////////////////////////////////////////////////////////////////// 146 | // GCoptimization class 147 | ///////////////////////////////////////////////////////////////////// 148 | class LinkedBlockList; 149 | 150 | class GCoptimization 151 | { 152 | public: 153 | #ifdef GCO_ENERGYTYPE32 154 | typedef float EnergyType; // 32-bit energy total 155 | #else 156 | typedef double EnergyType; // 64-bit energy total 157 | #endif 158 | typedef float EnergyTermType; // 32-bit energy terms 159 | typedef Energy EnergyT; 160 | typedef EnergyT::Var VarID; 161 | typedef int LabelID; // Type for labels 162 | typedef VarID SiteID; // Type for sites 163 | typedef EnergyTermType (*SmoothCostFn)(SiteID s1, SiteID s2, LabelID l1, LabelID l2); 164 | typedef EnergyTermType (*DataCostFn)(SiteID s, LabelID l); 165 | typedef EnergyTermType (*SmoothCostFnExtra)(SiteID s1, SiteID s2, LabelID l1, LabelID l2,void *); 166 | typedef EnergyTermType (*DataCostFnExtra)(SiteID s, LabelID l,void *); 167 | 168 | GCoptimization(SiteID num_sites, LabelID num_labels); 169 | virtual ~GCoptimization(); 170 | 171 | // Peforms expansion algorithm. Runs the number of iterations specified by max_num_iterations 172 | // If no input specified,runs until convergence. Returns total energy of labeling. 173 | EnergyType expansion(int max_num_iterations=-1); 174 | 175 | // Peforms expansion on one label, specified by the input parameter alpha_label 176 | bool alpha_expansion(LabelID alpha_label); 177 | 178 | // Peforms swap algorithm. Runs it the specified number of iterations. If no 179 | // input is specified,runs until convergence 180 | EnergyType swap(int max_num_iterations=-1); 181 | 182 | // Peforms swap on a pair of labels, specified by the input parameters alpha_label, beta_label 183 | void alpha_beta_swap(LabelID alpha_label, LabelID beta_label); 184 | 185 | // Peforms swap on a pair of labels, specified by the input parameters alpha_label, beta_label 186 | // only on the sitess in the specified arrays, alphaSites and betaSitess, and the array sizes 187 | // are, respectively, alpha_size and beta_size 188 | void alpha_beta_swap(LabelID alpha_label, LabelID beta_label, SiteID *alphaSites, 189 | SiteID alpha_size, SiteID *betaSites, SiteID beta_size); 190 | 191 | struct DataCostFunctor; // use this class to pass a functor to setDataCost 192 | struct SmoothCostFunctor; // use this class to pass a functor to setSmoothCost 193 | 194 | // Set cost for all (SiteID,LabelID) pairs. Default data cost is all zeros. 195 | void setDataCost(DataCostFn fn); 196 | void setDataCost(DataCostFnExtra fn, void *extraData); 197 | void setDataCost(EnergyTermType *dataArray); 198 | void setDataCost(SiteID s, LabelID l, EnergyTermType e); 199 | void setDataCostFunctor(DataCostFunctor* f); 200 | struct DataCostFunctor { 201 | virtual EnergyTermType compute(SiteID s, LabelID l) = 0; 202 | }; 203 | // Set cost of assigning 'l' to a specific subset of sites. 204 | // The sites are listed as (SiteID,cost) pairs. 205 | struct SparseDataCost { 206 | SiteID site; 207 | EnergyTermType cost; 208 | }; 209 | void setDataCost(LabelID l, SparseDataCost *costs, SiteID count); 210 | 211 | // Set cost for all (LabelID,LabelID) pairs; the actual smooth cost is then weighted 212 | // at each pair of on neighbors. Defaults to Potts model (0 if l1==l2, 1 otherwise) 213 | void setSmoothCost(SmoothCostFn fn); 214 | void setSmoothCost(SmoothCostFnExtra fn, void *extraData); 215 | void setSmoothCost(LabelID l1, LabelID l2, EnergyTermType e); 216 | void setSmoothCost(EnergyTermType *smoothArray); 217 | void setSmoothCostFunctor(SmoothCostFunctor* f); 218 | struct SmoothCostFunctor { 219 | virtual EnergyTermType compute(SiteID s1, SiteID s2, LabelID l1, LabelID l2) = 0; 220 | }; 221 | 222 | // Sets the cost of using label in the solution. 223 | // Set either as uniform cost, or an individual per-label cost. 224 | void setLabelCost(EnergyTermType cost); 225 | void setLabelCost(EnergyTermType* costArray); 226 | void setLabelSubsetCost(LabelID* labels, LabelID numLabels, EnergyTermType cost); 227 | 228 | // Returns current label assigned to input site 229 | LabelID whatLabel(SiteID site); 230 | void whatLabel(SiteID start, SiteID count, LabelID* labeling); 231 | 232 | // This function can be used to change the label of any site at any time 233 | void setLabel(SiteID site, LabelID label); 234 | 235 | // setLabelOrder(false) sets the order to be not random; setLabelOrder(true) 236 | // sets the order to random. By default, the labels are visited in non-random order 237 | // for both the swap and alpha-expansion moves 238 | // Note that srand() must be initialized with an appropriate seed in order for 239 | // random order to take effect! 240 | void setLabelOrder(bool isRandom); 241 | void setLabelOrder(const LabelID* order, LabelID size); 242 | 243 | // Returns total energy for the current labeling 244 | EnergyType compute_energy(); 245 | 246 | // Returns separate Data, Smooth, and Label energy of current labeling 247 | EnergyType giveDataEnergy(); 248 | EnergyType giveSmoothEnergy(); 249 | EnergyType giveLabelEnergy(); 250 | 251 | // Returns number of sites/labels as specified in the constructor 252 | SiteID numSites() const; 253 | LabelID numLabels() const; 254 | 255 | // Prints output to stdout during exansion/swap execution. 256 | // 0 => no output 257 | // 1 => cycle-level output (cycle number, current energy) 258 | // 2 => expansion-/swap-level output (label(s), current energy) 259 | void setVerbosity(int level) { m_verbosity = level; } 260 | 261 | protected: 262 | struct LabelCost { 263 | ~LabelCost() { delete [] labels; } 264 | EnergyTermType cost; 265 | bool active; // flag indicates if this particular labelcost is in effect (i.e. wrt m_labeling) 266 | VarID aux; 267 | LabelCost* next; // global list of LabelSetCost records 268 | LabelID numLabels; 269 | LabelID* labels; 270 | }; 271 | 272 | struct LabelCostIter { 273 | LabelCost* node; 274 | LabelCostIter* next; // local list of LabelSetCost records that contain this label 275 | }; 276 | 277 | LabelID m_num_labels; 278 | SiteID m_num_sites; 279 | LabelID *m_labeling; 280 | SiteID *m_lookupSiteVar; // holds index of variable corresponding to site participating in a move, 281 | // -1 for nonparticipating site 282 | LabelID *m_labelTable; // to figure out label order in which to do expansion/swaps 283 | int m_stepsThisCycle; 284 | int m_stepsThisCycleTotal; 285 | int m_random_label_order; 286 | EnergyTermType* m_datacostIndividual; 287 | EnergyTermType* m_smoothcostIndividual; 288 | EnergyTermType* m_labelingDataCosts; 289 | SiteID* m_labelCounts; 290 | SiteID* m_activeLabelCounts; 291 | LabelCost* m_labelcostsAll; 292 | LabelCostIter** m_labelcostsByLabel; 293 | int m_labelcostCount; 294 | bool m_labelingInfoDirty; 295 | int m_verbosity; 296 | 297 | void* m_datacostFn; 298 | void* m_smoothcostFn; 299 | EnergyType m_beforeExpansionEnergy; 300 | 301 | SiteID *m_numNeighbors; // holds num of neighbors for each site 302 | SiteID m_numNeighborsTotal; // holds total num of neighbor relationships 303 | 304 | EnergyType (GCoptimization::*m_giveSmoothEnergyInternal)(); 305 | SiteID (GCoptimization::*m_queryActiveSitesExpansion)(LabelID, SiteID*); 306 | void (GCoptimization::*m_setupDataCostsExpansion)(SiteID,LabelID,EnergyT*,SiteID*); 307 | void (GCoptimization::*m_setupSmoothCostsExpansion)(SiteID,LabelID,EnergyT*,SiteID*); 308 | void (GCoptimization::*m_setupDataCostsSwap)(SiteID,LabelID,LabelID,EnergyT*,SiteID*); 309 | void (GCoptimization::*m_setupSmoothCostsSwap)(SiteID,LabelID,LabelID,EnergyT*,SiteID*); 310 | void (GCoptimization::*m_applyNewLabeling)(EnergyT*,SiteID*,SiteID,LabelID); 311 | void (GCoptimization::*m_updateLabelingDataCosts)(); 312 | 313 | void (*m_datacostFnDelete)(void* f); 314 | void (*m_smoothcostFnDelete)(void* f); 315 | bool (GCoptimization::*m_solveSpecialCases)(EnergyType&); 316 | 317 | // returns a pointer to the neighbors of a site and the weights 318 | virtual void giveNeighborInfo(SiteID site, SiteID *numSites, SiteID **neighbors, EnergyTermType **weights)=0; 319 | virtual void finalizeNeighbors() = 0; 320 | 321 | struct DataCostFnFromArray { 322 | DataCostFnFromArray(EnergyTermType* theArray, LabelID num_labels) 323 | : m_array(theArray), m_num_labels(num_labels){} 324 | OLGA_INLINE EnergyTermType compute(SiteID s, LabelID l){return m_array[s*m_num_labels+l];} 325 | private: 326 | const EnergyTermType* const m_array; 327 | const LabelID m_num_labels; 328 | }; 329 | 330 | struct DataCostFnFromFunction { 331 | DataCostFnFromFunction(DataCostFn fn): m_fn(fn){} 332 | OLGA_INLINE EnergyTermType compute(SiteID s, LabelID l){return m_fn(s,l);} 333 | private: 334 | const DataCostFn m_fn; 335 | }; 336 | 337 | struct DataCostFnFromFunctionExtra { 338 | DataCostFnFromFunctionExtra(DataCostFnExtra fn,void *extraData): m_fn(fn),m_extraData(extraData){} 339 | OLGA_INLINE EnergyTermType compute(SiteID s, LabelID l){return m_fn(s,l,m_extraData);} 340 | private: 341 | const DataCostFnExtra m_fn; 342 | void *m_extraData; 343 | }; 344 | 345 | struct SmoothCostFnFromArray { 346 | SmoothCostFnFromArray(EnergyTermType* theArray, LabelID num_labels) 347 | : m_array(theArray), m_num_labels(num_labels){} 348 | OLGA_INLINE EnergyTermType compute(SiteID s1, SiteID s2, LabelID l1, LabelID l2){return m_array[l1*m_num_labels+l2];} 349 | private: 350 | const EnergyTermType* const m_array; 351 | const LabelID m_num_labels; 352 | }; 353 | 354 | struct SmoothCostFnFromFunction { 355 | SmoothCostFnFromFunction(SmoothCostFn fn) 356 | : m_fn(fn){} 357 | OLGA_INLINE EnergyTermType compute(SiteID s1, SiteID s2, LabelID l1, LabelID l2){return m_fn(s1,s2,l1,l2);} 358 | private: 359 | const SmoothCostFn m_fn; 360 | }; 361 | 362 | struct SmoothCostFnFromFunctionExtra { 363 | SmoothCostFnFromFunctionExtra(SmoothCostFnExtra fn,void *extraData) 364 | : m_fn(fn),m_extraData(extraData){} 365 | OLGA_INLINE EnergyTermType compute(SiteID s1, SiteID s2, LabelID l1, LabelID l2){return m_fn(s1,s2,l1,l2,m_extraData);} 366 | private: 367 | const SmoothCostFnExtra m_fn; 368 | void *m_extraData; 369 | }; 370 | 371 | struct SmoothCostFnPotts { 372 | OLGA_INLINE EnergyTermType compute(SiteID, SiteID, LabelID l1, LabelID l2){return l1 != l2 ? 1 : 0;} 373 | }; 374 | 375 | ///////////////////////////////////////////////////////////////////// 376 | // DataCostFnSparse 377 | // This data cost functor maintains a simple sparse structure 378 | // to quickly find the cost associated with any (site,label) pair. 379 | ///////////////////////////////////////////////////////////////////// 380 | class DataCostFnSparse { 381 | // cLogSitesPerBucket basically controls the compression ratio 382 | // of the sparse structure: 1 => a dense array, num_sites => a single sparse list. 383 | // The amount (cLogSitesPerBucket - cLinearSearchSize) determines the maximum 384 | // number of binary search steps taken for a cost lookup for specific (site,label). 385 | // 386 | static const int cLogSitesPerBucket = 9; 387 | static const int cSitesPerBucket = (1 << cLogSitesPerBucket); 388 | static const size_t cDataCostPtrMask = ~(sizeof(SparseDataCost)-1); 389 | static const ptrdiff_t cLinearSearchSize = 64/sizeof(SparseDataCost); 390 | 391 | struct DataCostBucket { 392 | const SparseDataCost* begin; 393 | const SparseDataCost* end; // one-past-the-last item in the range 394 | const SparseDataCost* predict; // predicts the next cost to be needed 395 | }; 396 | 397 | public: 398 | DataCostFnSparse(SiteID num_sites, LabelID num_labels); 399 | DataCostFnSparse(const DataCostFnSparse& src); 400 | ~DataCostFnSparse(); 401 | 402 | void set(LabelID l, const SparseDataCost* costs, SiteID count); 403 | EnergyTermType compute(SiteID s, LabelID l); 404 | SiteID queryActiveSitesExpansion(LabelID alpha_label, const LabelID* labeling, SiteID* activeSites); 405 | 406 | class iterator { 407 | public: 408 | OLGA_INLINE iterator(): m_ptr(0) { } 409 | OLGA_INLINE iterator& operator++() { m_ptr++; return *this; } 410 | OLGA_INLINE SiteID site() const { return m_ptr->site; } 411 | OLGA_INLINE EnergyTermType cost() const { return m_ptr->cost; } 412 | OLGA_INLINE bool operator==(const iterator& b) const { return m_ptr == b.m_ptr; } 413 | OLGA_INLINE bool operator!=(const iterator& b) const { return m_ptr != b.m_ptr; } 414 | OLGA_INLINE ptrdiff_t operator- (const iterator& b) const { return m_ptr - b.m_ptr; } 415 | private: 416 | OLGA_INLINE iterator(const SparseDataCost* ptr): m_ptr(ptr) { } 417 | const SparseDataCost* m_ptr; 418 | friend class DataCostFnSparse; 419 | }; 420 | 421 | OLGA_INLINE iterator begin(LabelID label) const { return m_buckets[label*m_buckets_per_label].begin; } 422 | OLGA_INLINE iterator end(LabelID label) const { return m_buckets[label*m_buckets_per_label + m_buckets_per_label-1].end; } 423 | 424 | private: 425 | EnergyTermType search(DataCostBucket& b, SiteID s); 426 | const SiteID m_num_sites; 427 | const LabelID m_num_labels; 428 | const int m_buckets_per_label; 429 | mutable DataCostBucket* m_buckets; 430 | }; 431 | 432 | template SiteID queryActiveSitesExpansion(LabelID alpha_label, SiteID* activeSites); 433 | template void setupDataCostsExpansion(SiteID size,LabelID alpha_label,EnergyT *e,SiteID *activeSites); 434 | template void setupDataCostsSwap(SiteID size,LabelID alpha_label,LabelID beta_label,EnergyT *e,SiteID *activeSites); 435 | template void setupSmoothCostsExpansion(SiteID size,LabelID alpha_label,EnergyT *e,SiteID *activeSites); 436 | template void setupSmoothCostsSwap(SiteID size,LabelID alpha_label,LabelID beta_label,EnergyT *e,SiteID *activeSites); 437 | template void applyNewLabeling(EnergyT *e,SiteID *activeSites,SiteID size,LabelID alpha_label); 438 | template void updateLabelingDataCosts(); 439 | template void specializeDataCostFunctor(const UserFunctor f); 440 | template void specializeSmoothCostFunctor(const UserFunctor f); 441 | 442 | EnergyType setupLabelCostsExpansion(SiteID size,LabelID alpha_label,EnergyT *e,SiteID *activeSites); 443 | void updateLabelingInfo(bool updateCounts=true,bool updateActive=true,bool updateCosts=true); 444 | 445 | // Check for overflow and submodularity issues when setting up binary graph cut 446 | void addterm1_checked(EnergyT *e,VarID i,EnergyTermType e0,EnergyTermType e1); 447 | void addterm1_checked(EnergyT *e,VarID i,EnergyTermType e0,EnergyTermType e1,EnergyTermType w); 448 | void addterm2_checked(EnergyT *e,VarID i,VarID j,EnergyTermType e00,EnergyTermType e01,EnergyTermType e10,EnergyTermType e11,EnergyTermType w); 449 | 450 | // Returns Smooth Energy of current labeling 451 | template EnergyType giveSmoothEnergyInternal(); 452 | template static void deleteFunctor(void* f) { delete reinterpret_cast(f); } 453 | 454 | static void handleError(const char *message); 455 | static void checkInterrupt(); 456 | 457 | private: 458 | // Peforms one iteration (one pass over all pairs of labels) of expansion/swap algorithm 459 | EnergyType oneExpansionIteration(); 460 | EnergyType oneSwapIteration(); 461 | void printStatus1(const char* extraMsg=0); 462 | void printStatus1(int cycle, bool isSwap, gcoclock_t ticks0); 463 | void printStatus2(int alpha, int beta, int numVars, gcoclock_t ticks0); 464 | 465 | void permuteLabelTable(); 466 | 467 | template bool solveSpecialCases(EnergyType& energy); 468 | template EnergyType solveGreedy(); 469 | 470 | ///////////////////////////////////////////////////////////////////// 471 | // GreedyIter 472 | // Lets solveGreedy efficiently traverse the datacosts when 473 | // searching for the next greedy move. 474 | ///////////////////////////////////////////////////////////////////// 475 | template 476 | class GreedyIter { 477 | public: 478 | GreedyIter(DataCostT& dc, SiteID numSites) 479 | : m_dc(dc), m_site(0), m_numSites(numSites), m_label(0), m_lbegin(0), m_lend(0) 480 | { } 481 | 482 | OLGA_INLINE void start(const LabelID* labels, LabelID labelCount=1) 483 | { 484 | m_site = labelCount ? 0 : m_numSites; 485 | m_label = m_lbegin = labels; 486 | m_lend = labels + labelCount; 487 | } 488 | OLGA_INLINE SiteID site() const { return m_site; } 489 | OLGA_INLINE SiteID label() const { return *m_label; } 490 | OLGA_INLINE bool done() const { return m_site == m_numSites; } 491 | OLGA_INLINE GreedyIter& operator++() 492 | { 493 | // The inner loop is over labels, not sites, to improve memory locality. 494 | // When dc() is pulling datacosts from an array (the typical format), this can 495 | // improve performance by a factor of 2x, often more like 4x. 496 | if (++m_label >= m_lend) { 497 | m_label = m_lbegin; 498 | ++m_site; 499 | } 500 | return *this; 501 | } 502 | OLGA_INLINE EnergyTermType compute() const { return m_dc.compute(m_site,*m_label); } 503 | OLGA_INLINE SiteID feasibleSites() const { return m_numSites; } 504 | 505 | private: 506 | SiteID m_site; 507 | DataCostT& m_dc; 508 | const SiteID m_numSites; 509 | const LabelID* m_label; 510 | const LabelID* m_lbegin; 511 | const LabelID* m_lend; 512 | }; 513 | }; 514 | 515 | 516 | ////////////////////////////////////////////////////////////////////////////////////////////////// 517 | // Use this derived class for grid graphs 518 | ////////////////////////////////////////////////////////////////////////////////////////////////// 519 | 520 | class GCoptimizationGridGraph: public GCoptimization 521 | { 522 | public: 523 | GCoptimizationGridGraph(SiteID width,SiteID height,LabelID num_labels); 524 | virtual ~GCoptimizationGridGraph(); 525 | 526 | void setSmoothCostVH(EnergyTermType *smoothArray, EnergyTermType *vCosts, EnergyTermType *hCosts); 527 | 528 | protected: 529 | virtual void giveNeighborInfo(SiteID site, SiteID *numSites, SiteID **neighbors, EnergyTermType **weights); 530 | virtual void finalizeNeighbors(); 531 | EnergyTermType m_unityWeights[4]; 532 | int m_weightedGraph; // true if spatially varying w_pq's are present. False otherwise. 533 | 534 | private: 535 | SiteID m_width; 536 | SiteID m_height; 537 | SiteID *m_neighbors; // holds neighbor indexes 538 | EnergyTermType *m_neighborsWeights; // holds neighbor weights 539 | 540 | void setupNeighbData(SiteID startY,SiteID endY,SiteID startX,SiteID endX,SiteID maxInd,SiteID *indexes); 541 | void computeNeighborWeights(EnergyTermType *vCosts,EnergyTermType *hCosts); 542 | }; 543 | 544 | ////////////////////////////////////////////////////////////////////////////////////////////////// 545 | 546 | class GCoptimizationGeneralGraph:public GCoptimization 547 | { 548 | public: 549 | // This is the constructor for non-grid graphs. Neighborhood structure must be specified by 550 | // setNeighbors() function 551 | GCoptimizationGeneralGraph(SiteID num_sites,LabelID num_labels); 552 | virtual ~GCoptimizationGeneralGraph(); 553 | 554 | // Makes site1 and site2 neighbors of each other. Can be called only 1 time for each 555 | // unordered pair of sites. Parameter weight can be used to set spacially varying terms 556 | // If the desired penalty for neighboring sites site1 and site2 is 557 | // V(label1,label2) = weight*SmoothnessPenalty(label1,label2), then 558 | // member function setLabel should be called as: setLabel(site1,site2,weight) 559 | void setNeighbors(SiteID site1, SiteID site2, EnergyTermType weight=1); 560 | 561 | // passes pointers to arrays storing neighbor information 562 | // numNeighbors[i] is the number of neighbors for site i 563 | // neighborsIndexes[i] is a pointer to the array storing the sites which are neighbors to site i 564 | // neighborWeights[i] is a pointer to array storing the weights between site i and its neighbors 565 | // in the same order as neighborIndexes[i] stores the indexes 566 | void setAllNeighbors(SiteID *numNeighbors,SiteID **neighborsIndexes,EnergyTermType **neighborsWeights); 567 | 568 | protected: 569 | virtual void giveNeighborInfo(SiteID site, SiteID *numSites, SiteID **neighbors, EnergyTermType **weights); 570 | virtual void finalizeNeighbors(); 571 | 572 | private: 573 | 574 | typedef struct NeighborStruct{ 575 | SiteID to_node; 576 | EnergyTermType weight; 577 | } Neighbor; 578 | 579 | LinkedBlockList *m_neighbors; 580 | bool m_needToFinishSettingNeighbors; 581 | SiteID **m_neighborsIndexes; 582 | EnergyTermType **m_neighborsWeights; 583 | bool m_needTodeleteNeighbors; 584 | }; 585 | 586 | 587 | //////////////////////////////////////////////////////////////////// 588 | // Methods 589 | //////////////////////////////////////////////////////////////////// 590 | 591 | 592 | OLGA_INLINE GCoptimization::SiteID GCoptimization::numSites() const 593 | { 594 | return m_num_sites; 595 | } 596 | 597 | OLGA_INLINE GCoptimization::LabelID GCoptimization::numLabels() const 598 | { 599 | return m_num_labels; 600 | } 601 | 602 | OLGA_INLINE void GCoptimization::setLabel(SiteID site, LabelID label) 603 | { 604 | assert(label >= 0 && label < m_num_labels && site >= 0 && site < m_num_sites); 605 | m_labeling[site] = label; 606 | m_labelingInfoDirty = true; 607 | } 608 | 609 | OLGA_INLINE GCoptimization::LabelID GCoptimization::whatLabel(SiteID site) 610 | { 611 | assert(site >= 0 && site < m_num_sites); 612 | return m_labeling[site]; 613 | } 614 | 615 | #endif 616 | -------------------------------------------------------------------------------- /BasicImageSegmentation/multi-labelGraphCut/LinkedBlockList.cpp: -------------------------------------------------------------------------------- 1 | #include "LinkedBlockList.h" 2 | #include 3 | #include 4 | 5 | /*********************************************************************/ 6 | 7 | void LinkedBlockList::addFront(ListType item) { 8 | 9 | if ( m_head_block_size == GCLL_BLOCK_SIZE ) 10 | { 11 | LLBlock *tmp = (LLBlock *) new LLBlock; 12 | if ( !tmp ) {printf("\nOut of memory");exit(1);} 13 | tmp -> m_next = m_head; 14 | m_head = tmp; 15 | m_head_block_size = 0; 16 | } 17 | 18 | m_head ->m_item[m_head_block_size] = item; 19 | m_head_block_size++; 20 | } 21 | 22 | /*********************************************************************/ 23 | 24 | ListType LinkedBlockList::next() 25 | { 26 | ListType toReturn = m_cursor -> m_item[m_cursor_ind]; 27 | 28 | m_cursor_ind++; 29 | 30 | if ( m_cursor == m_head && m_cursor_ind >= m_head_block_size ) 31 | { 32 | m_cursor = m_cursor ->m_next; 33 | m_cursor_ind = 0; 34 | } 35 | else if ( m_cursor_ind == GCLL_BLOCK_SIZE ) 36 | { 37 | m_cursor = m_cursor ->m_next; 38 | m_cursor_ind = 0; 39 | } 40 | return(toReturn); 41 | } 42 | 43 | /*********************************************************************/ 44 | 45 | bool LinkedBlockList::hasNext() 46 | { 47 | if ( m_cursor != 0 ) return (true); 48 | else return(false); 49 | } 50 | 51 | 52 | /*********************************************************************/ 53 | 54 | LinkedBlockList::~LinkedBlockList() 55 | { 56 | LLBlock *tmp; 57 | 58 | while ( m_head != 0 ) 59 | { 60 | tmp = m_head; 61 | m_head = m_head->m_next; 62 | delete tmp; 63 | } 64 | }; 65 | 66 | /*********************************************************************/ 67 | 68 | -------------------------------------------------------------------------------- /BasicImageSegmentation/multi-labelGraphCut/LinkedBlockList.h: -------------------------------------------------------------------------------- 1 | /* Singly Linked List of Blocks */ 2 | // This data structure should be used only for the GCoptimization class implementation 3 | // because it lucks some important general functions for general list, like remove_item() 4 | // The head block may be not full 5 | // For regular 2D grids, it's better to set GCLL_BLOCK_SIZE to 2 6 | // For other graphs, it should be set to the average expected number of neighbors 7 | // Data in linked list for the neighborhood system is allocated in blocks of size GCLL_BLOCK_SIZE 8 | 9 | #ifndef __LINKEDBLOCKLIST_H__ 10 | #define __LINKEDBLOCKLIST_H__ 11 | 12 | #define GCLL_BLOCK_SIZE 4 13 | // GCLL_BLOCKSIZE should "fit" into the type BlockType. That is 14 | // if GCLL_BLOCKSIZE is larger than 255 but smaller than largest short integer 15 | // then BlockType should be set to short 16 | typedef char BlockType; 17 | 18 | //The type of data stored in the linked list 19 | typedef void * ListType; 20 | 21 | class LinkedBlockList{ 22 | 23 | public: 24 | void addFront(ListType item); 25 | inline bool isEmpty(){if (m_head == 0) return(true); else return(false);}; 26 | inline LinkedBlockList(){m_head = 0; m_head_block_size = GCLL_BLOCK_SIZE;}; 27 | ~LinkedBlockList(); 28 | 29 | // Next three functins are for the linked list traversal 30 | inline void setCursorFront(){m_cursor = m_head; m_cursor_ind = 0;}; 31 | ListType next(); 32 | bool hasNext(); 33 | 34 | private: 35 | typedef struct LLBlockStruct{ 36 | ListType m_item[GCLL_BLOCK_SIZE]; 37 | struct LLBlockStruct *m_next; 38 | } LLBlock; 39 | 40 | LLBlock *m_head; 41 | // Remembers the number of elements in the head block, since it may not be full 42 | BlockType m_head_block_size; 43 | // For block traversal, points to current element in the current block 44 | BlockType m_cursor_ind; 45 | // For block traversal, points to current block in the linked list 46 | LLBlock *m_cursor; 47 | }; 48 | 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /BasicImageSegmentation/multi-labelGraphCut/ReadMe.md: -------------------------------------------------------------------------------- 1 | Paper 2 | ====================== 3 | [1] Fast Approximate Energy Minimization via Graph Cuts. Y. Boykov, O. Veksler, R.Zabih. IEEE TPAMI, 20(12):1222-1239, Nov 2001. 4 | 5 | [2] What Energy Functions can be Minimized via Graph Cuts? V. Kolmogorov, R.Zabih. IEEE TPAMI, 26(2):147-159, Feb 2004. 6 | 7 | [3] An Experimental Comparison of Min-Cut/Max-Flow Algorithms for Energy Minimization in Vision. Y. Boykov, V. Kolmogorov. IEEE TPAMI, 26(9):1124-1137, Sep 2004. 8 | 9 | [4] Fast Approximate Energy Minimization with Label Costs. A. Delong, A. Osokin, H. N. Isack, Y. Boykov. In CVPR, June 2010. 10 | 11 | SourceCode 12 | ====================== 13 | http://www.csd.uwo.ca/~olga/code.html -------------------------------------------------------------------------------- /BasicImageSegmentation/multi-labelGraphCut/block.h: -------------------------------------------------------------------------------- 1 | /* block.h */ 2 | /* 3 | Template classes GBlock and DBlock 4 | Implement adding and deleting items of the same type in blocks. 5 | 6 | If there there are many items then using GBlock or DBlock 7 | is more efficient than using 'new' and 'delete' both in terms 8 | of memory and time since 9 | (1) On some systems there is some minimum amount of memory 10 | that 'new' can allocate (e.g., 64), so if items are 11 | small that a lot of memory is wasted. 12 | (2) 'new' and 'delete' are designed for items of varying size. 13 | If all items has the same size, then an algorithm for 14 | adding and deleting can be made more efficient. 15 | (3) All GBlock and DBlock functions are inline, so there are 16 | no extra function calls. 17 | 18 | Differences between GBlock and DBlock: 19 | (1) DBlock allows both adding and deleting items, 20 | whereas GBlock allows only adding items. 21 | (2) GBlock has an additional operation of scanning 22 | items added so far (in the order in which they were added). 23 | (3) GBlock allows to allocate several consecutive 24 | items at a time, whereas DBlock can add only a single item. 25 | 26 | Note that no constructors or destructors are called for items. 27 | 28 | Example usage for items of type 'MyType': 29 | 30 | /////////////////////////////////////////////////// 31 | #include "block.h" 32 | #define BLOCK_SIZE 1024 33 | typedef struct { int a, b; } MyType; 34 | MyType *ptr, *array[10000]; 35 | 36 | ... 37 | 38 | GBlock *block = new GBlock(BLOCK_SIZE); 39 | 40 | // adding items 41 | for (int i=0; i New(); 44 | ptr -> a = ptr -> b = rand(); 45 | } 46 | 47 | // reading items 48 | for (ptr=block->ScanFirst(); ptr; ptr=block->ScanNext()) 49 | { 50 | printf("%d %d\n", ptr->a, ptr->b); 51 | } 52 | 53 | delete block; 54 | 55 | ... 56 | 57 | DBlock *dblock = new DBlock(BLOCK_SIZE); 58 | 59 | // adding items 60 | for (int i=0; i New(); 63 | } 64 | 65 | // deleting items 66 | for (int i=0; i Delete(array[i]); 69 | } 70 | 71 | // adding items 72 | for (int i=0; i New(); 75 | } 76 | 77 | delete dblock; 78 | 79 | /////////////////////////////////////////////////// 80 | 81 | Note that DBlock deletes items by marking them as 82 | empty (i.e., by adding them to the list of free items), 83 | so that this memory could be used for subsequently 84 | added items. Thus, at each moment the memory allocated 85 | is determined by the maximum number of items allocated 86 | simultaneously at earlier moments. All memory is 87 | deallocated only when the destructor is called. 88 | */ 89 | 90 | #ifndef __BLOCK_H__ 91 | #define __BLOCK_H__ 92 | 93 | #include 94 | 95 | /***********************************************************************/ 96 | /***********************************************************************/ 97 | /***********************************************************************/ 98 | 99 | template class GBlock 100 | { 101 | public: 102 | /* Constructor. Arguments are the block size and 103 | (optionally) the pointer to the function which 104 | will be called if allocation failed; the message 105 | passed to this function is "Not enough memory!" */ 106 | GBlock(int size, void (*err_function)(char *) = NULL) { first = last = NULL; block_size = size; error_function = err_function; } 107 | 108 | /* Destructor. Deallocates all items added so far */ 109 | ~GBlock() { while (first) { block *next = first -> next; delete first; first = next; } } 110 | 111 | /* Allocates 'num' consecutive items; returns pointer 112 | to the first item. 'num' cannot be greater than the 113 | block size since items must fit in one block */ 114 | Type *New(int num = 1) 115 | { 116 | Type *t; 117 | 118 | if (!last || last->current + num > last->last) 119 | { 120 | if (last && last->next) last = last -> next; 121 | else 122 | { 123 | block *next = (block *) new char [sizeof(block) + (block_size-1)*sizeof(Type)]; 124 | if (!next) { if (error_function) (*error_function)("Not enough memory!"); exit(1); } 125 | if (last) last -> next = next; 126 | else first = next; 127 | last = next; 128 | last -> current = & ( last -> data[0] ); 129 | last -> last = last -> current + block_size; 130 | last -> next = NULL; 131 | } 132 | } 133 | 134 | t = last -> current; 135 | last -> current += num; 136 | return t; 137 | } 138 | 139 | /* Returns the first item (or NULL, if no items were added) */ 140 | Type *ScanFirst() 141 | { 142 | for (scan_current_block=first; scan_current_block; scan_current_block = scan_current_block->next) 143 | { 144 | scan_current_data = & ( scan_current_block -> data[0] ); 145 | if (scan_current_data < scan_current_block -> current) return scan_current_data ++; 146 | } 147 | return NULL; 148 | } 149 | 150 | /* Returns the next item (or NULL, if all items have been read) 151 | Can be called only if previous ScanFirst() or ScanNext() 152 | call returned not NULL. */ 153 | Type *ScanNext() 154 | { 155 | while (scan_current_data >= scan_current_block -> current) 156 | { 157 | scan_current_block = scan_current_block -> next; 158 | if (!scan_current_block) return NULL; 159 | scan_current_data = & ( scan_current_block -> data[0] ); 160 | } 161 | return scan_current_data ++; 162 | } 163 | 164 | /* Marks all elements as empty */ 165 | void Reset() 166 | { 167 | block *b; 168 | if (!first) return; 169 | for (b=first; ; b=b->next) 170 | { 171 | b -> current = & ( b -> data[0] ); 172 | if (b == last) break; 173 | } 174 | last = first; 175 | } 176 | 177 | /***********************************************************************/ 178 | 179 | private: 180 | 181 | typedef struct block_st 182 | { 183 | Type *current, *last; 184 | struct block_st *next; 185 | Type data[1]; 186 | } block; 187 | 188 | int block_size; 189 | block *first; 190 | block *last; 191 | 192 | block *scan_current_block; 193 | Type *scan_current_data; 194 | 195 | void (*error_function)(char *); 196 | }; 197 | 198 | /***********************************************************************/ 199 | /***********************************************************************/ 200 | /***********************************************************************/ 201 | 202 | template class DBlock 203 | { 204 | public: 205 | /* Constructor. Arguments are the block size and 206 | (optionally) the pointer to the function which 207 | will be called if allocation failed; the message 208 | passed to this function is "Not enough memory!" */ 209 | DBlock(int size, void (*err_function)(char *) = NULL) { first = NULL; first_free = NULL; block_size = size; error_function = err_function; } 210 | 211 | /* Destructor. Deallocates all items added so far */ 212 | ~DBlock() { while (first) { block *next = first -> next; delete first; first = next; } } 213 | 214 | /* Allocates one item */ 215 | Type *New() 216 | { 217 | block_item *item; 218 | 219 | if (!first_free) 220 | { 221 | block *next = first; 222 | first = (block *) new char [sizeof(block) + (block_size-1)*sizeof(block_item)]; 223 | if (!first) { if (error_function) (*error_function)("Not enough memory!"); exit(1); } 224 | first_free = & (first -> data[0] ); 225 | for (item=first_free; item next_free = item + 1; 227 | item -> next_free = NULL; 228 | first -> next = next; 229 | } 230 | 231 | item = first_free; 232 | first_free = item -> next_free; 233 | return (Type *) item; 234 | } 235 | 236 | /* Deletes an item allocated previously */ 237 | void Delete(Type *t) 238 | { 239 | ((block_item *) t) -> next_free = first_free; 240 | first_free = (block_item *) t; 241 | } 242 | 243 | /***********************************************************************/ 244 | 245 | private: 246 | 247 | typedef union block_item_st 248 | { 249 | Type t; 250 | block_item_st *next_free; 251 | } block_item; 252 | 253 | typedef struct block_st 254 | { 255 | struct block_st *next; 256 | block_item data[1]; 257 | } block; 258 | 259 | int block_size; 260 | block *first; 261 | block_item *first_free; 262 | 263 | void (*error_function)(char *); 264 | }; 265 | 266 | 267 | #endif 268 | 269 | -------------------------------------------------------------------------------- /BasicImageSegmentation/multi-labelGraphCut/energy.h: -------------------------------------------------------------------------------- 1 | /* energy.h */ 2 | /* Vladimir Kolmogorov (vnk@cs.cornell.edu), 2003. */ 3 | 4 | /* 5 | This software implements an energy minimization technique described in 6 | 7 | What Energy Functions can be Minimized via Graph Cuts? 8 | Vladimir Kolmogorov and Ramin Zabih. 9 | To appear in IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI). 10 | Earlier version appeared in European Conference on Computer Vision (ECCV), May 2002. 11 | 12 | More specifically, it computes the global minimum of a function E of binary 13 | variables x_1, ..., x_n which can be written as a sum of terms involving 14 | at most three variables at a time: 15 | 16 | E(x_1, ..., x_n) = \sum_{i} E^{i} (x_i) 17 | + \sum_{i,j} E^{i,j} (x_i, x_j) 18 | + \sum_{i,j,k} E^{i,j,k}(x_i, x_j, x_k) 19 | 20 | The method works only if each term is "regular". Definitions of regularity 21 | for terms E^{i}, E^{i,j}, E^{i,j,k} are given below as comments to functions 22 | add_term1(), add_term2(), add_term3(). 23 | 24 | This software can be used only for research purposes. IF YOU USE THIS SOFTWARE, 25 | YOU SHOULD CITE THE AFOREMENTIONED PAPER IN ANY RESULTING PUBLICATION. 26 | 27 | In order to use it, you will also need a MAXFLOW software which can be 28 | obtained from http://www.cs.cornell.edu/People/vnk/software.html 29 | 30 | 31 | Example usage 32 | (Minimizes the following function of 3 binary variables: 33 | E(_features, i, z) = _features - 2*i + 3*(1-z) - 4*_features*i + 5*|i-z|): 34 | 35 | /////////////////////////////////////////////////// 36 | 37 | #include 38 | #include "energy.h" 39 | 40 | void main() 41 | { 42 | // Minimize the following function of 3 binary variables: 43 | // E(_features, i, z) = _features - 2*i + 3*(1-z) - 4*_features*i + 5*|i-z| 44 | 45 | Energy::Var varx, vary, varz; 46 | Energy *e = new Energy(); 47 | 48 | varx = e -> add_variable(); 49 | vary = e -> add_variable(); 50 | varz = e -> add_variable(); 51 | 52 | e -> add_term1(varx, 0, 1); // add term _features 53 | e -> add_term1(vary, 0, -2); // add term -2*i 54 | e -> add_term1(varz, 3, 0); // add term 3*(1-z) 55 | 56 | e -> add_term2(_features, i, 0, 0, 0, -4); // add term -4*_features*i 57 | e -> add_term2(i, z, 0, 5, 5, 0); // add term 5*|i-z| 58 | 59 | Energy::TotalValue Emin = e -> minimize(); 60 | 61 | printf("Minimum = %d\n", Emin); 62 | printf("Optimal solution:\n"); 63 | printf("_features = %d\n", e->get_var(varx)); 64 | printf("i = %d\n", e->get_var(vary)); 65 | printf("z = %d\n", e->get_var(varz)); 66 | 67 | delete e; 68 | } 69 | 70 | /////////////////////////////////////////////////// 71 | */ 72 | 73 | #ifndef __ENERGY_H__ 74 | #define __ENERGY_H__ 75 | 76 | #include 77 | #include "graph.h" 78 | 79 | template class Energy: public Graph 80 | { 81 | typedef Graph GraphT; 82 | public: 83 | typedef typename GraphT::node_id Var; 84 | 85 | /* Types of energy values. 86 | Value is a type of a value in a single term 87 | TotalValue is a type of a value of the total energy. 88 | By default Value = short, TotalValue = int. 89 | To change it, change the corresponding types in graph.h */ 90 | typedef captype Value; 91 | typedef flowtype TotalValue; 92 | 93 | /* interface functions */ 94 | 95 | /* Constructor. Optional argument is the pointer to the 96 | function which will be called if an error occurs; 97 | an error message is passed to this function. If this 98 | argument is omitted, exit(1) will be called. */ 99 | Energy(int var_num_max, int edge_num_max, void (*err_function)(char *) = NULL); 100 | 101 | /* Destructor */ 102 | ~Energy(); 103 | 104 | /* Adds a new binary variable */ 105 | Var add_variable(int num=1); 106 | 107 | /* Adds a constant E to the energy function */ 108 | void add_constant(Value E); 109 | 110 | /* Adds a new term E(_features) of one binary variable 111 | to the energy function, where 112 | E(0) = E0, E(1) = E1 113 | E0 and E1 can be arbitrary */ 114 | void add_term1(Var _features, 115 | Value E0, Value E1); 116 | 117 | /* Adds a new term E(_features,i) of two binary variables 118 | to the energy function, where 119 | E(0,0) = E00, E(0,1) = E01 120 | E(1,0) = E10, E(1,1) = E11 121 | The term must be regular, i.e. E00 + E11 <= E01 + E10 */ 122 | void add_term2(Var _features, Var i, 123 | Value E00, Value E01, 124 | Value E10, Value E11); 125 | 126 | /* Adds a new term E(_features,i,z) of three binary variables 127 | to the energy function, where 128 | E(0,0,0) = E000, E(0,0,1) = E001 129 | E(0,1,0) = E010, E(0,1,1) = E011 130 | E(1,0,0) = E100, E(1,0,1) = E101 131 | E(1,1,0) = E110, E(1,1,1) = E111 132 | The term must be regular. It means that if one 133 | of the variables is fixed (for example, i=1), then 134 | the resulting function of two variables must be regular. 135 | Since there are 6 ways to fix one variable 136 | (3 variables times 2 binary values - 0 and 1), 137 | this is equivalent to 6 inequalities */ 138 | void add_term3(Var _features, Var i, Var z, 139 | Value E000, Value E001, 140 | Value E010, Value E011, 141 | Value E100, Value E101, 142 | Value E110, Value E111); 143 | 144 | /* After the energy function has been constructed, 145 | call this function to minimize it. 146 | Returns the minimum of the function */ 147 | TotalValue minimize(); 148 | 149 | /* After 'minimize' has been called, this function 150 | can be used to determine the value of variable '_features' 151 | in the optimal solution. 152 | Returns either 0 or 1 */ 153 | int get_var(Var _features); 154 | 155 | /***********************************************************************/ 156 | /***********************************************************************/ 157 | /***********************************************************************/ 158 | 159 | private: 160 | /* internal variables and functions */ 161 | 162 | TotalValue Econst; 163 | void (*error_function)(char *); /* this function is called if a error occurs, 164 | with a corresponding error message 165 | (or exit(1) is called if it's NULL) */ 166 | }; 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | /***********************************************************************/ 183 | /************************ Implementation ******************************/ 184 | /***********************************************************************/ 185 | 186 | template 187 | inline Energy::Energy(int var_num_max, int edge_num_max, void (*err_function)(char *)) : Graph(var_num_max, edge_num_max, err_function) 188 | { 189 | Econst = 0; 190 | error_function = err_function; 191 | } 192 | 193 | template 194 | inline Energy::~Energy() {} 195 | 196 | template 197 | inline typename Energy::Var Energy::add_variable(int num) 198 | { return GraphT::add_node(num); } 199 | 200 | template 201 | inline void Energy::add_constant(Value A) { Econst += A; } 202 | 203 | template 204 | inline void Energy::add_term1(Var _features, 205 | Value A, Value B) 206 | { 207 | add_tweights(_features, B, A); 208 | } 209 | 210 | template 211 | inline void Energy::add_term2(Var _features, Var i, 212 | Value A, Value B, 213 | Value C, Value D) 214 | { 215 | /* 216 | E = A A + 0 B-A 217 | D D C-D 0 218 | Add edges for the first term 219 | */ 220 | add_tweights(_features, D, A); 221 | B -= A; C -= D; 222 | 223 | /* now need to represent 224 | 0 B 225 | C 0 226 | */ 227 | 228 | assert(B + C >= 0); /* check regularity */ 229 | if (B < 0) 230 | { 231 | /* Write it as 232 | B B + -B 0 + 0 0 233 | 0 0 -B 0 B+C 0 234 | */ 235 | add_tweights(_features, 0, B); /* first term */ 236 | add_tweights(i, 0, -B); /* second term */ 237 | add_edge(_features, i, 0, B+C); /* third term */ 238 | } 239 | else if (C < 0) 240 | { 241 | /* Write it as 242 | -C -C + C 0 + 0 B+C 243 | 0 0 C 0 0 0 244 | */ 245 | add_tweights(_features, 0, -C); /* first term */ 246 | add_tweights(i, 0, C); /* second term */ 247 | add_edge(_features, i, B+C, 0); /* third term */ 248 | } 249 | else /* B >= 0, C >= 0 */ 250 | { 251 | add_edge(_features, i, B, C); 252 | } 253 | } 254 | 255 | template 256 | inline void Energy::add_term3(Var _features, Var i, Var z, 257 | Value E000, Value E001, 258 | Value E010, Value E011, 259 | Value E100, Value E101, 260 | Value E110, Value E111) 261 | { 262 | register Value pi = (E000 + E011 + E101 + E110) - (E100 + E010 + E001 + E111); 263 | register Value delta; 264 | register Var u; 265 | 266 | if (pi >= 0) 267 | { 268 | Econst += E111 - (E011 + E101 + E110); 269 | 270 | add_tweights(_features, E101, E001); 271 | add_tweights(i, E110, E100); 272 | add_tweights(z, E011, E010); 273 | 274 | delta = (E010 + E001) - (E000 + E011); /* -pi(E[_features=0]) */ 275 | assert(delta >= 0); /* check regularity */ 276 | add_edge(i, z, delta, 0); 277 | 278 | delta = (E100 + E001) - (E000 + E101); /* -pi(E[i=0]) */ 279 | assert(delta >= 0); /* check regularity */ 280 | add_edge(z, _features, delta, 0); 281 | 282 | delta = (E100 + E010) - (E000 + E110); /* -pi(E[z=0]) */ 283 | assert(delta >= 0); /* check regularity */ 284 | add_edge(_features, i, delta, 0); 285 | 286 | if (pi > 0) 287 | { 288 | u = add_variable(); 289 | add_edge(_features, u, pi, 0); 290 | add_edge(i, u, pi, 0); 291 | add_edge(z, u, pi, 0); 292 | add_tweights(u, 0, pi); 293 | } 294 | } 295 | else 296 | { 297 | Econst += E000 - (E100 + E010 + E001); 298 | 299 | add_tweights(_features, E110, E010); 300 | add_tweights(i, E011, E001); 301 | add_tweights(z, E101, E100); 302 | 303 | delta = (E110 + E101) - (E100 + E111); /* -pi(E[_features=1]) */ 304 | assert(delta >= 0); /* check regularity */ 305 | add_edge(z, i, delta, 0); 306 | 307 | delta = (E110 + E011) - (E010 + E111); /* -pi(E[i=1]) */ 308 | assert(delta >= 0); /* check regularity */ 309 | add_edge(_features, z, delta, 0); 310 | 311 | delta = (E101 + E011) - (E001 + E111); /* -pi(E[z=1]) */ 312 | assert(delta >= 0); /* check regularity */ 313 | add_edge(i, _features, delta, 0); 314 | 315 | u = add_variable(); 316 | add_edge(u, _features, -pi, 0); 317 | add_edge(u, i, -pi, 0); 318 | add_edge(u, z, -pi, 0); 319 | add_tweights(u, -pi, 0); 320 | } 321 | } 322 | 323 | template 324 | inline typename Energy::TotalValue Energy::minimize() { 325 | return Econst + GraphT::maxflow(); } 326 | 327 | template 328 | inline int Energy::get_var(Var _features) { return (int) what_segment(_features); } 329 | 330 | #endif 331 | -------------------------------------------------------------------------------- /BasicImageSegmentation/multi-labelGraphCut/graph.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/multi-labelGraphCut/graph.cpp -------------------------------------------------------------------------------- /BasicImageSegmentation/multi-labelGraphCut/maxflow.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/multi-labelGraphCut/maxflow.cpp -------------------------------------------------------------------------------- /BasicImageSegmentation/segmentor.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/segmentor.cpp -------------------------------------------------------------------------------- /BasicImageSegmentation/segmentor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/BasicImageSegmentation/segmentor.h -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /OpenCV_248_x86.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | D:\dev\opencv\build\include;D:\dev\opencv\build\include\opencv;D:\dev\opencv\build\include\opencv2;$(IncludePath) 7 | D:\dev\opencv\build\x86\vc11\lib;$(LibraryPath) 8 | 9 | 10 | 11 | opencv_core248.lib;opencv_imgproc248.lib;opencv_highgui248.lib;opencv_ml248.lib;opencv_video248.lib;opencv_features2d248.lib;opencv_calib3d248.lib;opencv_objdetect248.lib;opencv_contrib248.lib;opencv_legacy248.lib;opencv_flann248.lib;%(AdditionalDependencies) 12 | D:\dev\opencv\build\x86\vc11\lib;%(AdditionalLibraryDirectories) 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /OpenCV_248d_x86.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | D:\dev\opencv\build\include;D:\dev\opencv\build\include\opencv;D:\dev\opencv\build\include\opencv2;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); 7 | D:\dev\opencv\build\x86\vc11\lib;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86); 8 | $(ExecutablePath) 9 | 10 | 11 | 12 | opencv_core248d.lib;opencv_imgproc248d.lib;opencv_highgui248d.lib;opencv_ml248d.lib;opencv_video248d.lib;opencv_features2d248d.lib;opencv_calib3d248d.lib;opencv_objdetect248d.lib;opencv_contrib248d.lib;opencv_legacy248d.lib;opencv_flann248d.lib;opencv_ocl248d.lib;%(AdditionalDependencies) 13 | D:\dev\opencv\build\x86\vc11\lib;%(AdditionalLibraryDirectories) 14 | 15 | 16 | D:\dev\opencv\build\include;D:\dev\opencv\build\include\opencv;D:\dev\opencv\build\include\opencv2;%(AdditionalIncludeDirectories) 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BasicImageSegmentation 2 | ====================== 3 | 4 | Some basic image segmentation algorithms, include mean-shift, graph-based, SLIC, SEEDS, GrabCut, OneCut, et al. 5 | 6 | Usage 7 | ====================== 8 | 1. Write the algorithms you need to the file "config.ini" 9 | 10 | 2. Use command "BasicImageSegmentation [ImageName]", or drag the image to the exe file directly. If you drag image to the exe, you need to ensure the config.ini and the image in the same directory. 11 | 12 | 3. For the interactive algorithms, such as GrabCut and OneCut, you need to scribble on the image and press 13 | keyboards according to the output tips. 14 | 15 | 4. After each algorithms, the program would output the segmentation result as a txt file. It's a two-dimensional matrix 16 | indicates the region id of each pixel. 17 | 18 | About the "config.ini" 19 | ====================== 20 | 1. The program can read this file and get the algorithm names and arguments want to use. 21 | 22 | 2. Each configuration item contains a algorithm name in a line and several arguments(can be zero) all in the following line. 23 | The algorithm name is surround by a bracket[]. 24 | 25 | 3. This file can contain multiple algorithms. 26 | 27 | 4. "config_example.ini" is an example. 28 | -------------------------------------------------------------------------------- /Release/1_11_s.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/Release/1_11_s.bmp -------------------------------------------------------------------------------- /Release/BasicImageSegmentation.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/Release/BasicImageSegmentation.exe -------------------------------------------------------------------------------- /Release/config.ini: -------------------------------------------------------------------------------- 1 | # comment 2 | [SEEDS] 3 | 128 4 | 5 | [GraphBased] 6 | 0.3 40 50 7 | 8 | [SLIC] 9 | 15 10 | 11 | [MeanShift] 12 | 10 6 30 2 13 | 14 | [OneCut] 15 | 16 | [GrabCut] 17 | -------------------------------------------------------------------------------- /Release/lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/Release/lena.jpg -------------------------------------------------------------------------------- /Release/lena_big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/Release/lena_big.jpg -------------------------------------------------------------------------------- /Release/opencv_core248.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/Release/opencv_core248.dll -------------------------------------------------------------------------------- /Release/opencv_highgui248.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/Release/opencv_highgui248.dll -------------------------------------------------------------------------------- /Release/opencv_imgproc248.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higherhu/BasicImageSegmentation/e1d1cece424185d8744ee67ec89c52ead8907031/Release/opencv_imgproc248.dll --------------------------------------------------------------------------------