Bug Summary

File:ccv_icf.c
Warning:line 1178, column 25
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ccv_icf.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model static -mthread-model posix -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fno-trapping-math -ffp-contract=fast -ffast-math -ffinite-math-only -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-feature +sse2 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -resource-dir /usr/local/lib/clang/8.0.0 -I . -I /usr/local/cuda/include -D HAVE_CBLAS -D HAVE_LIBPNG -D HAVE_LIBJPEG -D HAVE_FFTW3 -D HAVE_PTHREAD -D HAVE_UCONTEXT -D HAVE_LIBLINEAR -D HAVE_TESSERACT -D HAVE_AVCODEC -D HAVE_AVFORMAT -D HAVE_AVUTIL -D HAVE_SWSCALE -D USE_DISPATCH -D HAVE_SSE2 -D HAVE_GSL -D HAVE_CUDA -D HAVE_CUDNN -D HAVE_NCCL -I /usr/local/include -internal-isystem /usr/local/include -internal-isystem /usr/local/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -fdebug-compilation-dir /home/liu/buildslave/linux-x64-runtests/build/lib -ferror-limit 19 -fmessage-length 0 -fblocks -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -o /home/liu/buildslave/public_html/analyze/2019-05-04-163002-105371-1 -x c ccv_icf.c -faddrsig
1#include "ccv.h"
2#include "ccv_internal.h"
3#ifdef HAVE_GSL1
4#include <gsl/gsl_rng.h>
5#include <gsl/gsl_randist.h>
6#endif
7#ifdef USE_OPENMP
8#include <omp.h>
9#endif
10#ifdef USE_DISPATCH1
11#include <dispatch/dispatch.h>
12#endif
13
14const ccv_icf_param_t ccv_icf_default_params = {
15 .min_neighbors = 2,
16 .threshold = 0,
17 .step_through = 2,
18 .flags = 0,
19 .interval = 8,
20};
21
22// this uses a look up table for cubic root computation because rgb to luv only requires data within range of 0~1
23static inline float fast_cube_root(const float d)
24{
25 static const float cube_root[2048] = {
26 0.000000e+00, 7.875788e-02, 9.922871e-02, 1.135885e-01, 1.250203e-01, 1.346741e-01, 1.431126e-01, 1.506584e-01,
27 1.575158e-01, 1.638230e-01, 1.696787e-01, 1.751560e-01, 1.803105e-01, 1.851861e-01, 1.898177e-01, 1.942336e-01,
28 1.984574e-01, 2.025087e-01, 2.064040e-01, 2.101577e-01, 2.137818e-01, 2.172870e-01, 2.206827e-01, 2.239769e-01,
29 2.271770e-01, 2.302894e-01, 2.333199e-01, 2.362736e-01, 2.391553e-01, 2.419692e-01, 2.447191e-01, 2.474085e-01,
30 2.500407e-01, 2.526186e-01, 2.551450e-01, 2.576222e-01, 2.600528e-01, 2.624387e-01, 2.647821e-01, 2.670846e-01,
31 2.693482e-01, 2.715743e-01, 2.737645e-01, 2.759202e-01, 2.780428e-01, 2.801334e-01, 2.821933e-01, 2.842235e-01,
32 2.862251e-01, 2.881992e-01, 2.901465e-01, 2.920681e-01, 2.939647e-01, 2.958371e-01, 2.976862e-01, 2.995125e-01,
33 3.013168e-01, 3.030998e-01, 3.048621e-01, 3.066041e-01, 3.083267e-01, 3.100302e-01, 3.117152e-01, 3.133821e-01,
34 3.150315e-01, 3.166639e-01, 3.182795e-01, 3.198789e-01, 3.214625e-01, 3.230307e-01, 3.245837e-01, 3.261220e-01,
35 3.276460e-01, 3.291559e-01, 3.306521e-01, 3.321348e-01, 3.336045e-01, 3.350613e-01, 3.365056e-01, 3.379375e-01,
36 3.393574e-01, 3.407656e-01, 3.421622e-01, 3.435475e-01, 3.449216e-01, 3.462850e-01, 3.476377e-01, 3.489799e-01,
37 3.503119e-01, 3.516339e-01, 3.529460e-01, 3.542483e-01, 3.555412e-01, 3.568248e-01, 3.580992e-01, 3.593646e-01,
38 3.606211e-01, 3.618689e-01, 3.631082e-01, 3.643391e-01, 3.655617e-01, 3.667762e-01, 3.679827e-01, 3.691814e-01,
39 3.703723e-01, 3.715556e-01, 3.727314e-01, 3.738999e-01, 3.750610e-01, 3.762151e-01, 3.773621e-01, 3.785022e-01,
40 3.796354e-01, 3.807619e-01, 3.818818e-01, 3.829952e-01, 3.841021e-01, 3.852027e-01, 3.862970e-01, 3.873852e-01,
41 3.884673e-01, 3.895434e-01, 3.906136e-01, 3.916779e-01, 3.927365e-01, 3.937894e-01, 3.948367e-01, 3.958785e-01,
42 3.969149e-01, 3.979458e-01, 3.989714e-01, 3.999918e-01, 4.010071e-01, 4.020171e-01, 4.030222e-01, 4.040223e-01,
43 4.050174e-01, 4.060076e-01, 4.069931e-01, 4.079738e-01, 4.089499e-01, 4.099212e-01, 4.108880e-01, 4.118503e-01,
44 4.128081e-01, 4.137615e-01, 4.147105e-01, 4.156551e-01, 4.165955e-01, 4.175317e-01, 4.184637e-01, 4.193916e-01,
45 4.203153e-01, 4.212351e-01, 4.221508e-01, 4.230626e-01, 4.239704e-01, 4.248744e-01, 4.257746e-01, 4.266710e-01,
46 4.275636e-01, 4.284525e-01, 4.293377e-01, 4.302193e-01, 4.310973e-01, 4.319718e-01, 4.328427e-01, 4.337101e-01,
47 4.345741e-01, 4.354346e-01, 4.362918e-01, 4.371456e-01, 4.379961e-01, 4.388433e-01, 4.396872e-01, 4.405279e-01,
48 4.413654e-01, 4.421997e-01, 4.430309e-01, 4.438590e-01, 4.446840e-01, 4.455060e-01, 4.463249e-01, 4.471409e-01,
49 4.479539e-01, 4.487639e-01, 4.495711e-01, 4.503753e-01, 4.511767e-01, 4.519752e-01, 4.527710e-01, 4.535639e-01,
50 4.543541e-01, 4.551415e-01, 4.559263e-01, 4.567083e-01, 4.574877e-01, 4.582644e-01, 4.590385e-01, 4.598100e-01,
51 4.605789e-01, 4.613453e-01, 4.621091e-01, 4.628704e-01, 4.636292e-01, 4.643855e-01, 4.651394e-01, 4.658908e-01,
52 4.666398e-01, 4.673865e-01, 4.681307e-01, 4.688726e-01, 4.696122e-01, 4.703494e-01, 4.710843e-01, 4.718169e-01,
53 4.725473e-01, 4.732754e-01, 4.740013e-01, 4.747250e-01, 4.754464e-01, 4.761657e-01, 4.768828e-01, 4.775978e-01,
54 4.783106e-01, 4.790214e-01, 4.797300e-01, 4.804365e-01, 4.811410e-01, 4.818434e-01, 4.825437e-01, 4.832420e-01,
55 4.839384e-01, 4.846327e-01, 4.853250e-01, 4.860154e-01, 4.867038e-01, 4.873902e-01, 4.880748e-01, 4.887574e-01,
56 4.894381e-01, 4.901170e-01, 4.907939e-01, 4.914690e-01, 4.921423e-01, 4.928137e-01, 4.934832e-01, 4.941510e-01,
57 4.948170e-01, 4.954812e-01, 4.961436e-01, 4.968042e-01, 4.974631e-01, 4.981203e-01, 4.987757e-01, 4.994294e-01,
58 5.000814e-01, 5.007317e-01, 5.013803e-01, 5.020273e-01, 5.026726e-01, 5.033162e-01, 5.039582e-01, 5.045985e-01,
59 5.052372e-01, 5.058743e-01, 5.065099e-01, 5.071438e-01, 5.077761e-01, 5.084069e-01, 5.090362e-01, 5.096638e-01,
60 5.102900e-01, 5.109145e-01, 5.115376e-01, 5.121592e-01, 5.127792e-01, 5.133978e-01, 5.140148e-01, 5.146304e-01,
61 5.152445e-01, 5.158572e-01, 5.164684e-01, 5.170782e-01, 5.176865e-01, 5.182934e-01, 5.188988e-01, 5.195029e-01,
62 5.201056e-01, 5.207069e-01, 5.213068e-01, 5.219053e-01, 5.225024e-01, 5.230982e-01, 5.236927e-01, 5.242857e-01,
63 5.248775e-01, 5.254679e-01, 5.260570e-01, 5.266448e-01, 5.272312e-01, 5.278164e-01, 5.284002e-01, 5.289828e-01,
64 5.295641e-01, 5.301442e-01, 5.307229e-01, 5.313004e-01, 5.318767e-01, 5.324517e-01, 5.330254e-01, 5.335979e-01,
65 5.341693e-01, 5.347394e-01, 5.353082e-01, 5.358759e-01, 5.364423e-01, 5.370076e-01, 5.375717e-01, 5.381346e-01,
66 5.386963e-01, 5.392569e-01, 5.398163e-01, 5.403746e-01, 5.409316e-01, 5.414876e-01, 5.420424e-01, 5.425960e-01,
67 5.431486e-01, 5.437000e-01, 5.442503e-01, 5.447995e-01, 5.453476e-01, 5.458946e-01, 5.464405e-01, 5.469853e-01,
68 5.475290e-01, 5.480717e-01, 5.486133e-01, 5.491537e-01, 5.496932e-01, 5.502316e-01, 5.507689e-01, 5.513052e-01,
69 5.518404e-01, 5.523747e-01, 5.529078e-01, 5.534400e-01, 5.539711e-01, 5.545012e-01, 5.550303e-01, 5.555584e-01,
70 5.560855e-01, 5.566117e-01, 5.571368e-01, 5.576609e-01, 5.581840e-01, 5.587062e-01, 5.592273e-01, 5.597475e-01,
71 5.602668e-01, 5.607851e-01, 5.613024e-01, 5.618188e-01, 5.623342e-01, 5.628487e-01, 5.633622e-01, 5.638748e-01,
72 5.643865e-01, 5.648973e-01, 5.654072e-01, 5.659161e-01, 5.664241e-01, 5.669311e-01, 5.674374e-01, 5.679426e-01,
73 5.684470e-01, 5.689505e-01, 5.694531e-01, 5.699549e-01, 5.704557e-01, 5.709556e-01, 5.714548e-01, 5.719529e-01,
74 5.724503e-01, 5.729468e-01, 5.734424e-01, 5.739372e-01, 5.744311e-01, 5.749242e-01, 5.754164e-01, 5.759078e-01,
75 5.763984e-01, 5.768881e-01, 5.773770e-01, 5.778650e-01, 5.783523e-01, 5.788387e-01, 5.793243e-01, 5.798091e-01,
76 5.802931e-01, 5.807762e-01, 5.812586e-01, 5.817402e-01, 5.822210e-01, 5.827010e-01, 5.831801e-01, 5.836585e-01,
77 5.841362e-01, 5.846130e-01, 5.850891e-01, 5.855644e-01, 5.860389e-01, 5.865127e-01, 5.869856e-01, 5.874579e-01,
78 5.879294e-01, 5.884001e-01, 5.888700e-01, 5.893393e-01, 5.898077e-01, 5.902755e-01, 5.907425e-01, 5.912087e-01,
79 5.916742e-01, 5.921390e-01, 5.926031e-01, 5.930664e-01, 5.935290e-01, 5.939909e-01, 5.944521e-01, 5.949125e-01,
80 5.953723e-01, 5.958313e-01, 5.962896e-01, 5.967473e-01, 5.972042e-01, 5.976604e-01, 5.981160e-01, 5.985708e-01,
81 5.990250e-01, 5.994784e-01, 5.999312e-01, 6.003833e-01, 6.008347e-01, 6.012855e-01, 6.017355e-01, 6.021850e-01,
82 6.026337e-01, 6.030817e-01, 6.035291e-01, 6.039758e-01, 6.044219e-01, 6.048673e-01, 6.053120e-01, 6.057562e-01,
83 6.061996e-01, 6.066424e-01, 6.070846e-01, 6.075261e-01, 6.079670e-01, 6.084072e-01, 6.088468e-01, 6.092858e-01,
84 6.097241e-01, 6.101618e-01, 6.105989e-01, 6.110353e-01, 6.114712e-01, 6.119064e-01, 6.123410e-01, 6.127750e-01,
85 6.132084e-01, 6.136411e-01, 6.140732e-01, 6.145048e-01, 6.149357e-01, 6.153660e-01, 6.157957e-01, 6.162249e-01,
86 6.166534e-01, 6.170813e-01, 6.175086e-01, 6.179354e-01, 6.183616e-01, 6.187872e-01, 6.192122e-01, 6.196365e-01,
87 6.200604e-01, 6.204836e-01, 6.209063e-01, 6.213284e-01, 6.217499e-01, 6.221709e-01, 6.225913e-01, 6.230111e-01,
88 6.234304e-01, 6.238490e-01, 6.242672e-01, 6.246848e-01, 6.251017e-01, 6.255182e-01, 6.259341e-01, 6.263494e-01,
89 6.267643e-01, 6.271785e-01, 6.275922e-01, 6.280054e-01, 6.284180e-01, 6.288301e-01, 6.292416e-01, 6.296526e-01,
90 6.300631e-01, 6.304730e-01, 6.308824e-01, 6.312913e-01, 6.316996e-01, 6.321074e-01, 6.325147e-01, 6.329215e-01,
91 6.333277e-01, 6.337335e-01, 6.341386e-01, 6.345433e-01, 6.349475e-01, 6.353511e-01, 6.357543e-01, 6.361569e-01,
92 6.365590e-01, 6.369606e-01, 6.373618e-01, 6.377624e-01, 6.381625e-01, 6.385621e-01, 6.389612e-01, 6.393598e-01,
93 6.397579e-01, 6.401555e-01, 6.405526e-01, 6.409492e-01, 6.413454e-01, 6.417410e-01, 6.421362e-01, 6.425309e-01,
94 6.429250e-01, 6.433188e-01, 6.437120e-01, 6.441047e-01, 6.444970e-01, 6.448888e-01, 6.452801e-01, 6.456710e-01,
95 6.460613e-01, 6.464512e-01, 6.468406e-01, 6.472296e-01, 6.476181e-01, 6.480061e-01, 6.483937e-01, 6.487808e-01,
96 6.491674e-01, 6.495536e-01, 6.499393e-01, 6.503246e-01, 6.507094e-01, 6.510937e-01, 6.514776e-01, 6.518611e-01,
97 6.522441e-01, 6.526266e-01, 6.530087e-01, 6.533904e-01, 6.537716e-01, 6.541524e-01, 6.545327e-01, 6.549126e-01,
98 6.552920e-01, 6.556710e-01, 6.560495e-01, 6.564277e-01, 6.568054e-01, 6.571826e-01, 6.575595e-01, 6.579359e-01,
99 6.583118e-01, 6.586874e-01, 6.590625e-01, 6.594372e-01, 6.598114e-01, 6.601852e-01, 6.605586e-01, 6.609316e-01,
100 6.613042e-01, 6.616763e-01, 6.620481e-01, 6.624194e-01, 6.627903e-01, 6.631607e-01, 6.635308e-01, 6.639005e-01,
101 6.642697e-01, 6.646385e-01, 6.650070e-01, 6.653750e-01, 6.657426e-01, 6.661098e-01, 6.664766e-01, 6.668430e-01,
102 6.672090e-01, 6.675746e-01, 6.679398e-01, 6.683046e-01, 6.686690e-01, 6.690330e-01, 6.693966e-01, 6.697598e-01,
103 6.701226e-01, 6.704850e-01, 6.708471e-01, 6.712087e-01, 6.715700e-01, 6.719308e-01, 6.722913e-01, 6.726514e-01,
104 6.730111e-01, 6.733705e-01, 6.737294e-01, 6.740879e-01, 6.744461e-01, 6.748039e-01, 6.751614e-01, 6.755184e-01,
105 6.758750e-01, 6.762313e-01, 6.765872e-01, 6.769428e-01, 6.772979e-01, 6.776527e-01, 6.780071e-01, 6.783612e-01,
106 6.787149e-01, 6.790682e-01, 6.794212e-01, 6.797737e-01, 6.801260e-01, 6.804778e-01, 6.808293e-01, 6.811804e-01,
107 6.815312e-01, 6.818815e-01, 6.822316e-01, 6.825813e-01, 6.829306e-01, 6.832796e-01, 6.836282e-01, 6.839765e-01,
108 6.843244e-01, 6.846719e-01, 6.850191e-01, 6.853660e-01, 6.857125e-01, 6.860586e-01, 6.864043e-01, 6.867498e-01,
109 6.870949e-01, 6.874397e-01, 6.877841e-01, 6.881282e-01, 6.884719e-01, 6.888152e-01, 6.891583e-01, 6.895010e-01,
110 6.898433e-01, 6.901854e-01, 6.905270e-01, 6.908684e-01, 6.912094e-01, 6.915500e-01, 6.918904e-01, 6.922303e-01,
111 6.925700e-01, 6.929094e-01, 6.932484e-01, 6.935870e-01, 6.939254e-01, 6.942633e-01, 6.946011e-01, 6.949384e-01,
112 6.952754e-01, 6.956121e-01, 6.959485e-01, 6.962845e-01, 6.966202e-01, 6.969556e-01, 6.972907e-01, 6.976255e-01,
113 6.979599e-01, 6.982940e-01, 6.986278e-01, 6.989613e-01, 6.992944e-01, 6.996273e-01, 6.999598e-01, 7.002920e-01,
114 7.006239e-01, 7.009555e-01, 7.012867e-01, 7.016177e-01, 7.019483e-01, 7.022786e-01, 7.026086e-01, 7.029384e-01,
115 7.032678e-01, 7.035969e-01, 7.039256e-01, 7.042542e-01, 7.045823e-01, 7.049102e-01, 7.052377e-01, 7.055650e-01,
116 7.058919e-01, 7.062186e-01, 7.065449e-01, 7.068710e-01, 7.071967e-01, 7.075222e-01, 7.078474e-01, 7.081722e-01,
117 7.084967e-01, 7.088210e-01, 7.091449e-01, 7.094686e-01, 7.097920e-01, 7.101150e-01, 7.104378e-01, 7.107603e-01,
118 7.110825e-01, 7.114044e-01, 7.117260e-01, 7.120473e-01, 7.123684e-01, 7.126891e-01, 7.130095e-01, 7.133297e-01,
119 7.136496e-01, 7.139692e-01, 7.142885e-01, 7.146075e-01, 7.149262e-01, 7.152447e-01, 7.155629e-01, 7.158808e-01,
120 7.161984e-01, 7.165157e-01, 7.168328e-01, 7.171495e-01, 7.174660e-01, 7.177821e-01, 7.180981e-01, 7.184138e-01,
121 7.187291e-01, 7.190442e-01, 7.193590e-01, 7.196736e-01, 7.199879e-01, 7.203019e-01, 7.206156e-01, 7.209290e-01,
122 7.212422e-01, 7.215551e-01, 7.218677e-01, 7.221801e-01, 7.224922e-01, 7.228040e-01, 7.231156e-01, 7.234268e-01,
123 7.237378e-01, 7.240486e-01, 7.243591e-01, 7.246693e-01, 7.249793e-01, 7.252890e-01, 7.255983e-01, 7.259076e-01,
124 7.262164e-01, 7.265251e-01, 7.268335e-01, 7.271415e-01, 7.274494e-01, 7.277570e-01, 7.280643e-01, 7.283714e-01,
125 7.286782e-01, 7.289847e-01, 7.292911e-01, 7.295971e-01, 7.299029e-01, 7.302084e-01, 7.305137e-01, 7.308187e-01,
126 7.311234e-01, 7.314279e-01, 7.317322e-01, 7.320362e-01, 7.323400e-01, 7.326434e-01, 7.329467e-01, 7.332497e-01,
127 7.335525e-01, 7.338549e-01, 7.341572e-01, 7.344592e-01, 7.347609e-01, 7.350624e-01, 7.353637e-01, 7.356647e-01,
128 7.359655e-01, 7.362660e-01, 7.365662e-01, 7.368662e-01, 7.371660e-01, 7.374656e-01, 7.377649e-01, 7.380639e-01,
129 7.383628e-01, 7.386613e-01, 7.389597e-01, 7.392578e-01, 7.395556e-01, 7.398532e-01, 7.401506e-01, 7.404477e-01,
130 7.407446e-01, 7.410412e-01, 7.413377e-01, 7.416338e-01, 7.419298e-01, 7.422255e-01, 7.425209e-01, 7.428162e-01,
131 7.431112e-01, 7.434059e-01, 7.437005e-01, 7.439948e-01, 7.442889e-01, 7.445827e-01, 7.448763e-01, 7.451697e-01,
132 7.454628e-01, 7.457558e-01, 7.460485e-01, 7.463409e-01, 7.466331e-01, 7.469251e-01, 7.472169e-01, 7.475084e-01,
133 7.477998e-01, 7.480908e-01, 7.483817e-01, 7.486723e-01, 7.489627e-01, 7.492529e-01, 7.495428e-01, 7.498326e-01,
134 7.501221e-01, 7.504114e-01, 7.507005e-01, 7.509893e-01, 7.512779e-01, 7.515663e-01, 7.518545e-01, 7.521424e-01,
135 7.524302e-01, 7.527177e-01, 7.530050e-01, 7.532921e-01, 7.535789e-01, 7.538656e-01, 7.541520e-01, 7.544382e-01,
136 7.547241e-01, 7.550099e-01, 7.552955e-01, 7.555808e-01, 7.558660e-01, 7.561509e-01, 7.564356e-01, 7.567201e-01,
137 7.570043e-01, 7.572884e-01, 7.575722e-01, 7.578558e-01, 7.581393e-01, 7.584225e-01, 7.587055e-01, 7.589883e-01,
138 7.592708e-01, 7.595532e-01, 7.598354e-01, 7.601173e-01, 7.603990e-01, 7.606806e-01, 7.609619e-01, 7.612430e-01,
139 7.615239e-01, 7.618046e-01, 7.620851e-01, 7.623653e-01, 7.626454e-01, 7.629253e-01, 7.632049e-01, 7.634844e-01,
140 7.637637e-01, 7.640427e-01, 7.643216e-01, 7.646002e-01, 7.648786e-01, 7.651569e-01, 7.654349e-01, 7.657127e-01,
141 7.659904e-01, 7.662678e-01, 7.665451e-01, 7.668221e-01, 7.670989e-01, 7.673756e-01, 7.676520e-01, 7.679282e-01,
142 7.682042e-01, 7.684801e-01, 7.687557e-01, 7.690312e-01, 7.693064e-01, 7.695814e-01, 7.698563e-01, 7.701310e-01,
143 7.704054e-01, 7.706797e-01, 7.709538e-01, 7.712276e-01, 7.715013e-01, 7.717748e-01, 7.720481e-01, 7.723212e-01,
144 7.725941e-01, 7.728668e-01, 7.731394e-01, 7.734116e-01, 7.736838e-01, 7.739558e-01, 7.742275e-01, 7.744991e-01,
145 7.747704e-01, 7.750416e-01, 7.753126e-01, 7.755834e-01, 7.758540e-01, 7.761245e-01, 7.763947e-01, 7.766647e-01,
146 7.769346e-01, 7.772043e-01, 7.774737e-01, 7.777431e-01, 7.780122e-01, 7.782811e-01, 7.785498e-01, 7.788184e-01,
147 7.790868e-01, 7.793550e-01, 7.796230e-01, 7.798908e-01, 7.801584e-01, 7.804259e-01, 7.806932e-01, 7.809603e-01,
148 7.812271e-01, 7.814939e-01, 7.817604e-01, 7.820268e-01, 7.822930e-01, 7.825589e-01, 7.828248e-01, 7.830904e-01,
149 7.833558e-01, 7.836211e-01, 7.838862e-01, 7.841511e-01, 7.844158e-01, 7.846804e-01, 7.849448e-01, 7.852090e-01,
150 7.854730e-01, 7.857369e-01, 7.860005e-01, 7.862641e-01, 7.865273e-01, 7.867905e-01, 7.870535e-01, 7.873163e-01,
151 7.875788e-01, 7.878413e-01, 7.881036e-01, 7.883657e-01, 7.886276e-01, 7.888893e-01, 7.891509e-01, 7.894123e-01,
152 7.896735e-01, 7.899345e-01, 7.901954e-01, 7.904561e-01, 7.907166e-01, 7.909770e-01, 7.912372e-01, 7.914972e-01,
153 7.917571e-01, 7.920167e-01, 7.922763e-01, 7.925356e-01, 7.927948e-01, 7.930537e-01, 7.933126e-01, 7.935712e-01,
154 7.938297e-01, 7.940881e-01, 7.943462e-01, 7.946042e-01, 7.948620e-01, 7.951197e-01, 7.953772e-01, 7.956345e-01,
155 7.958916e-01, 7.961487e-01, 7.964054e-01, 7.966621e-01, 7.969186e-01, 7.971749e-01, 7.974311e-01, 7.976871e-01,
156 7.979429e-01, 7.981986e-01, 7.984541e-01, 7.987095e-01, 7.989646e-01, 7.992196e-01, 7.994745e-01, 7.997292e-01,
157 7.999837e-01, 8.002381e-01, 8.004923e-01, 8.007463e-01, 8.010002e-01, 8.012539e-01, 8.015075e-01, 8.017609e-01,
158 8.020141e-01, 8.022672e-01, 8.025202e-01, 8.027729e-01, 8.030255e-01, 8.032780e-01, 8.035302e-01, 8.037823e-01,
159 8.040344e-01, 8.042861e-01, 8.045378e-01, 8.047893e-01, 8.050406e-01, 8.052918e-01, 8.055428e-01, 8.057937e-01,
160 8.060444e-01, 8.062950e-01, 8.065454e-01, 8.067956e-01, 8.070457e-01, 8.072957e-01, 8.075454e-01, 8.077950e-01,
161 8.080446e-01, 8.082938e-01, 8.085430e-01, 8.087921e-01, 8.090409e-01, 8.092896e-01, 8.095381e-01, 8.097866e-01,
162 8.100348e-01, 8.102829e-01, 8.105308e-01, 8.107786e-01, 8.110263e-01, 8.112738e-01, 8.115211e-01, 8.117683e-01,
163 8.120154e-01, 8.122622e-01, 8.125089e-01, 8.127556e-01, 8.130020e-01, 8.132483e-01, 8.134944e-01, 8.137404e-01,
164 8.139862e-01, 8.142319e-01, 8.144775e-01, 8.147229e-01, 8.149682e-01, 8.152133e-01, 8.154582e-01, 8.157030e-01,
165 8.159477e-01, 8.161922e-01, 8.164365e-01, 8.166808e-01, 8.169249e-01, 8.171688e-01, 8.174126e-01, 8.176562e-01,
166 8.178997e-01, 8.181431e-01, 8.183863e-01, 8.186293e-01, 8.188722e-01, 8.191150e-01, 8.193576e-01, 8.196001e-01,
167 8.198425e-01, 8.200847e-01, 8.203267e-01, 8.205686e-01, 8.208104e-01, 8.210521e-01, 8.212935e-01, 8.215349e-01,
168 8.217760e-01, 8.220171e-01, 8.222581e-01, 8.224988e-01, 8.227395e-01, 8.229799e-01, 8.232203e-01, 8.234605e-01,
169 8.237006e-01, 8.239405e-01, 8.241804e-01, 8.244200e-01, 8.246595e-01, 8.248989e-01, 8.251381e-01, 8.253772e-01,
170 8.256162e-01, 8.258550e-01, 8.260937e-01, 8.263323e-01, 8.265706e-01, 8.268089e-01, 8.270471e-01, 8.272851e-01,
171 8.275229e-01, 8.277607e-01, 8.279983e-01, 8.282357e-01, 8.284730e-01, 8.287102e-01, 8.289472e-01, 8.291842e-01,
172 8.294209e-01, 8.296576e-01, 8.298941e-01, 8.301305e-01, 8.303667e-01, 8.306028e-01, 8.308387e-01, 8.310746e-01,
173 8.313103e-01, 8.315458e-01, 8.317813e-01, 8.320166e-01, 8.322517e-01, 8.324867e-01, 8.327217e-01, 8.329564e-01,
174 8.331911e-01, 8.334256e-01, 8.336599e-01, 8.338942e-01, 8.341283e-01, 8.343623e-01, 8.345962e-01, 8.348299e-01,
175 8.350635e-01, 8.352969e-01, 8.355302e-01, 8.357634e-01, 8.359964e-01, 8.362294e-01, 8.364622e-01, 8.366948e-01,
176 8.369274e-01, 8.371598e-01, 8.373921e-01, 8.376243e-01, 8.378563e-01, 8.380882e-01, 8.383200e-01, 8.385516e-01,
177 8.387831e-01, 8.390145e-01, 8.392458e-01, 8.394769e-01, 8.397079e-01, 8.399388e-01, 8.401695e-01, 8.404002e-01,
178 8.406307e-01, 8.408611e-01, 8.410913e-01, 8.413214e-01, 8.415514e-01, 8.417813e-01, 8.420110e-01, 8.422406e-01,
179 8.424702e-01, 8.426995e-01, 8.429288e-01, 8.431579e-01, 8.433869e-01, 8.436158e-01, 8.438445e-01, 8.440731e-01,
180 8.443016e-01, 8.445300e-01, 8.447582e-01, 8.449863e-01, 8.452144e-01, 8.454422e-01, 8.456700e-01, 8.458977e-01,
181 8.461251e-01, 8.463526e-01, 8.465798e-01, 8.468069e-01, 8.470340e-01, 8.472609e-01, 8.474877e-01, 8.477143e-01,
182 8.479409e-01, 8.481673e-01, 8.483936e-01, 8.486198e-01, 8.488458e-01, 8.490717e-01, 8.492976e-01, 8.495233e-01,
183 8.497488e-01, 8.499743e-01, 8.501996e-01, 8.504249e-01, 8.506500e-01, 8.508750e-01, 8.510998e-01, 8.513246e-01,
184 8.515491e-01, 8.517737e-01, 8.519981e-01, 8.522223e-01, 8.524465e-01, 8.526706e-01, 8.528944e-01, 8.531182e-01,
185 8.533419e-01, 8.535655e-01, 8.537889e-01, 8.540123e-01, 8.542355e-01, 8.544586e-01, 8.546816e-01, 8.549044e-01,
186 8.551272e-01, 8.553498e-01, 8.555723e-01, 8.557947e-01, 8.560170e-01, 8.562392e-01, 8.564612e-01, 8.566832e-01,
187 8.569050e-01, 8.571267e-01, 8.573483e-01, 8.575698e-01, 8.577912e-01, 8.580124e-01, 8.582336e-01, 8.584546e-01,
188 8.586755e-01, 8.588963e-01, 8.591169e-01, 8.593375e-01, 8.595580e-01, 8.597783e-01, 8.599985e-01, 8.602186e-01,
189 8.604387e-01, 8.606585e-01, 8.608783e-01, 8.610980e-01, 8.613176e-01, 8.615370e-01, 8.617563e-01, 8.619756e-01,
190 8.621947e-01, 8.624136e-01, 8.626326e-01, 8.628513e-01, 8.630700e-01, 8.632885e-01, 8.635070e-01, 8.637253e-01,
191 8.639436e-01, 8.641617e-01, 8.643796e-01, 8.645976e-01, 8.648154e-01, 8.650330e-01, 8.652506e-01, 8.654680e-01,
192 8.656853e-01, 8.659026e-01, 8.661197e-01, 8.663368e-01, 8.665537e-01, 8.667705e-01, 8.669872e-01, 8.672037e-01,
193 8.674202e-01, 8.676366e-01, 8.678529e-01, 8.680690e-01, 8.682851e-01, 8.685010e-01, 8.687168e-01, 8.689325e-01,
194 8.691481e-01, 8.693637e-01, 8.695791e-01, 8.697944e-01, 8.700095e-01, 8.702246e-01, 8.704396e-01, 8.706545e-01,
195 8.708693e-01, 8.710839e-01, 8.712984e-01, 8.715129e-01, 8.717272e-01, 8.719414e-01, 8.721556e-01, 8.723696e-01,
196 8.725836e-01, 8.727974e-01, 8.730111e-01, 8.732247e-01, 8.734382e-01, 8.736516e-01, 8.738649e-01, 8.740780e-01,
197 8.742912e-01, 8.745041e-01, 8.747170e-01, 8.749298e-01, 8.751425e-01, 8.753550e-01, 8.755675e-01, 8.757799e-01,
198 8.759921e-01, 8.762043e-01, 8.764163e-01, 8.766283e-01, 8.768401e-01, 8.770519e-01, 8.772635e-01, 8.774751e-01,
199 8.776865e-01, 8.778979e-01, 8.781091e-01, 8.783202e-01, 8.785312e-01, 8.787422e-01, 8.789530e-01, 8.791637e-01,
200 8.793744e-01, 8.795849e-01, 8.797953e-01, 8.800057e-01, 8.802159e-01, 8.804260e-01, 8.806360e-01, 8.808460e-01,
201 8.810558e-01, 8.812655e-01, 8.814751e-01, 8.816847e-01, 8.818941e-01, 8.821034e-01, 8.823127e-01, 8.825217e-01,
202 8.827308e-01, 8.829397e-01, 8.831486e-01, 8.833573e-01, 8.835659e-01, 8.837745e-01, 8.839829e-01, 8.841912e-01,
203 8.843995e-01, 8.846076e-01, 8.848156e-01, 8.850236e-01, 8.852314e-01, 8.854392e-01, 8.856469e-01, 8.858544e-01,
204 8.860618e-01, 8.862692e-01, 8.864765e-01, 8.866837e-01, 8.868908e-01, 8.870977e-01, 8.873046e-01, 8.875114e-01,
205 8.877181e-01, 8.879247e-01, 8.881311e-01, 8.883376e-01, 8.885438e-01, 8.887501e-01, 8.889562e-01, 8.891622e-01,
206 8.893681e-01, 8.895739e-01, 8.897797e-01, 8.899853e-01, 8.901908e-01, 8.903963e-01, 8.906016e-01, 8.908069e-01,
207 8.910121e-01, 8.912171e-01, 8.914221e-01, 8.916270e-01, 8.918318e-01, 8.920364e-01, 8.922410e-01, 8.924455e-01,
208 8.926499e-01, 8.928543e-01, 8.930585e-01, 8.932626e-01, 8.934667e-01, 8.936706e-01, 8.938744e-01, 8.940782e-01,
209 8.942819e-01, 8.944854e-01, 8.946889e-01, 8.948923e-01, 8.950956e-01, 8.952988e-01, 8.955019e-01, 8.957049e-01,
210 8.959078e-01, 8.961107e-01, 8.963134e-01, 8.965160e-01, 8.967186e-01, 8.969210e-01, 8.971235e-01, 8.973257e-01,
211 8.975279e-01, 8.977300e-01, 8.979320e-01, 8.981339e-01, 8.983358e-01, 8.985375e-01, 8.987392e-01, 8.989407e-01,
212 8.991421e-01, 8.993436e-01, 8.995448e-01, 8.997460e-01, 8.999471e-01, 9.001482e-01, 9.003491e-01, 9.005499e-01,
213 9.007506e-01, 9.009513e-01, 9.011519e-01, 9.013523e-01, 9.015527e-01, 9.017531e-01, 9.019532e-01, 9.021534e-01,
214 9.023534e-01, 9.025534e-01, 9.027532e-01, 9.029530e-01, 9.031526e-01, 9.033523e-01, 9.035518e-01, 9.037512e-01,
215 9.039505e-01, 9.041498e-01, 9.043489e-01, 9.045479e-01, 9.047469e-01, 9.049459e-01, 9.051446e-01, 9.053434e-01,
216 9.055420e-01, 9.057405e-01, 9.059390e-01, 9.061373e-01, 9.063356e-01, 9.065338e-01, 9.067319e-01, 9.069299e-01,
217 9.071279e-01, 9.073257e-01, 9.075235e-01, 9.077212e-01, 9.079187e-01, 9.081162e-01, 9.083136e-01, 9.085110e-01,
218 9.087082e-01, 9.089054e-01, 9.091024e-01, 9.092994e-01, 9.094964e-01, 9.096932e-01, 9.098899e-01, 9.100866e-01,
219 9.102831e-01, 9.104796e-01, 9.106760e-01, 9.108723e-01, 9.110685e-01, 9.112647e-01, 9.114607e-01, 9.116567e-01,
220 9.118526e-01, 9.120483e-01, 9.122441e-01, 9.124397e-01, 9.126353e-01, 9.128307e-01, 9.130261e-01, 9.132214e-01,
221 9.134166e-01, 9.136118e-01, 9.138068e-01, 9.140018e-01, 9.141967e-01, 9.143915e-01, 9.145862e-01, 9.147808e-01,
222 9.149753e-01, 9.151698e-01, 9.153642e-01, 9.155585e-01, 9.157528e-01, 9.159469e-01, 9.161409e-01, 9.163349e-01,
223 9.165288e-01, 9.167226e-01, 9.169164e-01, 9.171100e-01, 9.173036e-01, 9.174970e-01, 9.176905e-01, 9.178838e-01,
224 9.180770e-01, 9.182702e-01, 9.184632e-01, 9.186562e-01, 9.188492e-01, 9.190420e-01, 9.192348e-01, 9.194274e-01,
225 9.196200e-01, 9.198125e-01, 9.200049e-01, 9.201973e-01, 9.203895e-01, 9.205818e-01, 9.207739e-01, 9.209659e-01,
226 9.211578e-01, 9.213497e-01, 9.215415e-01, 9.217332e-01, 9.219248e-01, 9.221163e-01, 9.223078e-01, 9.224992e-01,
227 9.226905e-01, 9.228818e-01, 9.230729e-01, 9.232640e-01, 9.234550e-01, 9.236459e-01, 9.238367e-01, 9.240275e-01,
228 9.242182e-01, 9.244088e-01, 9.245993e-01, 9.247897e-01, 9.249801e-01, 9.251704e-01, 9.253606e-01, 9.255507e-01,
229 9.257408e-01, 9.259307e-01, 9.261206e-01, 9.263105e-01, 9.265002e-01, 9.266899e-01, 9.268795e-01, 9.270689e-01,
230 9.272584e-01, 9.274477e-01, 9.276370e-01, 9.278262e-01, 9.280154e-01, 9.282044e-01, 9.283934e-01, 9.285822e-01,
231 9.287710e-01, 9.289598e-01, 9.291484e-01, 9.293370e-01, 9.295255e-01, 9.297140e-01, 9.299023e-01, 9.300906e-01,
232 9.302788e-01, 9.304669e-01, 9.306549e-01, 9.308429e-01, 9.310308e-01, 9.312186e-01, 9.314064e-01, 9.315941e-01,
233 9.317816e-01, 9.319692e-01, 9.321566e-01, 9.323440e-01, 9.325313e-01, 9.327185e-01, 9.329057e-01, 9.330927e-01,
234 9.332797e-01, 9.334666e-01, 9.336535e-01, 9.338402e-01, 9.340270e-01, 9.342135e-01, 9.344001e-01, 9.345866e-01,
235 9.347730e-01, 9.349593e-01, 9.351455e-01, 9.353317e-01, 9.355178e-01, 9.357038e-01, 9.358898e-01, 9.360756e-01,
236 9.362615e-01, 9.364472e-01, 9.366328e-01, 9.368184e-01, 9.370039e-01, 9.371893e-01, 9.373747e-01, 9.375600e-01,
237 9.377452e-01, 9.379303e-01, 9.381154e-01, 9.383004e-01, 9.384854e-01, 9.386702e-01, 9.388550e-01, 9.390397e-01,
238 9.392243e-01, 9.394089e-01, 9.395934e-01, 9.397778e-01, 9.399621e-01, 9.401464e-01, 9.403306e-01, 9.405147e-01,
239 9.406988e-01, 9.408827e-01, 9.410667e-01, 9.412505e-01, 9.414343e-01, 9.416180e-01, 9.418016e-01, 9.419851e-01,
240 9.421686e-01, 9.423520e-01, 9.425353e-01, 9.427186e-01, 9.429018e-01, 9.430850e-01, 9.432680e-01, 9.434510e-01,
241 9.436339e-01, 9.438167e-01, 9.439995e-01, 9.441822e-01, 9.443648e-01, 9.445474e-01, 9.447299e-01, 9.449123e-01,
242 9.450946e-01, 9.452769e-01, 9.454591e-01, 9.456412e-01, 9.458233e-01, 9.460053e-01, 9.461872e-01, 9.463691e-01,
243 9.465508e-01, 9.467326e-01, 9.469142e-01, 9.470958e-01, 9.472773e-01, 9.474587e-01, 9.476401e-01, 9.478214e-01,
244 9.480026e-01, 9.481838e-01, 9.483649e-01, 9.485459e-01, 9.487268e-01, 9.489077e-01, 9.490886e-01, 9.492693e-01,
245 9.494500e-01, 9.496306e-01, 9.498111e-01, 9.499916e-01, 9.501719e-01, 9.503523e-01, 9.505326e-01, 9.507128e-01,
246 9.508929e-01, 9.510729e-01, 9.512529e-01, 9.514329e-01, 9.516127e-01, 9.517925e-01, 9.519722e-01, 9.521519e-01,
247 9.523315e-01, 9.525110e-01, 9.526904e-01, 9.528698e-01, 9.530491e-01, 9.532284e-01, 9.534075e-01, 9.535866e-01,
248 9.537657e-01, 9.539447e-01, 9.541236e-01, 9.543024e-01, 9.544812e-01, 9.546599e-01, 9.548386e-01, 9.550171e-01,
249 9.551957e-01, 9.553741e-01, 9.555525e-01, 9.557307e-01, 9.559090e-01, 9.560872e-01, 9.562653e-01, 9.564433e-01,
250 9.566213e-01, 9.567992e-01, 9.569771e-01, 9.571549e-01, 9.573326e-01, 9.575102e-01, 9.576878e-01, 9.578653e-01,
251 9.580427e-01, 9.582201e-01, 9.583974e-01, 9.585747e-01, 9.587519e-01, 9.589290e-01, 9.591061e-01, 9.592831e-01,
252 9.594600e-01, 9.596368e-01, 9.598137e-01, 9.599904e-01, 9.601671e-01, 9.603436e-01, 9.605201e-01, 9.606966e-01,
253 9.608730e-01, 9.610494e-01, 9.612256e-01, 9.614019e-01, 9.615780e-01, 9.617541e-01, 9.619301e-01, 9.621060e-01,
254 9.622819e-01, 9.624578e-01, 9.626336e-01, 9.628092e-01, 9.629849e-01, 9.631604e-01, 9.633359e-01, 9.635113e-01,
255 9.636867e-01, 9.638621e-01, 9.640373e-01, 9.642125e-01, 9.643876e-01, 9.645627e-01, 9.647377e-01, 9.649126e-01,
256 9.650874e-01, 9.652622e-01, 9.654370e-01, 9.656116e-01, 9.657863e-01, 9.659608e-01, 9.661353e-01, 9.663097e-01,
257 9.664841e-01, 9.666584e-01, 9.668326e-01, 9.670068e-01, 9.671809e-01, 9.673550e-01, 9.675289e-01, 9.677029e-01,
258 9.678767e-01, 9.680505e-01, 9.682242e-01, 9.683979e-01, 9.685715e-01, 9.687451e-01, 9.689186e-01, 9.690920e-01,
259 9.692653e-01, 9.694387e-01, 9.696119e-01, 9.697851e-01, 9.699582e-01, 9.701312e-01, 9.703043e-01, 9.704772e-01,
260 9.706500e-01, 9.708228e-01, 9.709955e-01, 9.711683e-01, 9.713409e-01, 9.715135e-01, 9.716859e-01, 9.718584e-01,
261 9.720308e-01, 9.722031e-01, 9.723753e-01, 9.725475e-01, 9.727197e-01, 9.728917e-01, 9.730637e-01, 9.732357e-01,
262 9.734076e-01, 9.735794e-01, 9.737512e-01, 9.739228e-01, 9.740945e-01, 9.742661e-01, 9.744377e-01, 9.746091e-01,
263 9.747805e-01, 9.749519e-01, 9.751231e-01, 9.752944e-01, 9.754655e-01, 9.756366e-01, 9.758077e-01, 9.759787e-01,
264 9.761496e-01, 9.763204e-01, 9.764913e-01, 9.766620e-01, 9.768327e-01, 9.770033e-01, 9.771739e-01, 9.773444e-01,
265 9.775148e-01, 9.776852e-01, 9.778556e-01, 9.780258e-01, 9.781960e-01, 9.783661e-01, 9.785362e-01, 9.787063e-01,
266 9.788762e-01, 9.790462e-01, 9.792160e-01, 9.793859e-01, 9.795555e-01, 9.797252e-01, 9.798949e-01, 9.800645e-01,
267 9.802339e-01, 9.804034e-01, 9.805728e-01, 9.807421e-01, 9.809114e-01, 9.810806e-01, 9.812497e-01, 9.814188e-01,
268 9.815878e-01, 9.817568e-01, 9.819257e-01, 9.820946e-01, 9.822634e-01, 9.824321e-01, 9.826008e-01, 9.827695e-01,
269 9.829381e-01, 9.831066e-01, 9.832750e-01, 9.834434e-01, 9.836118e-01, 9.837800e-01, 9.839482e-01, 9.841164e-01,
270 9.842845e-01, 9.844526e-01, 9.846206e-01, 9.847885e-01, 9.849564e-01, 9.851242e-01, 9.852920e-01, 9.854597e-01,
271 9.856274e-01, 9.857950e-01, 9.859625e-01, 9.861299e-01, 9.862974e-01, 9.864647e-01, 9.866320e-01, 9.867993e-01,
272 9.869665e-01, 9.871337e-01, 9.873008e-01, 9.874678e-01, 9.876347e-01, 9.878017e-01, 9.879685e-01, 9.881353e-01,
273 9.883021e-01, 9.884688e-01, 9.886354e-01, 9.888020e-01, 9.889685e-01, 9.891350e-01, 9.893014e-01, 9.894677e-01,
274 9.896340e-01, 9.898003e-01, 9.899665e-01, 9.901326e-01, 9.902986e-01, 9.904646e-01, 9.906306e-01, 9.907965e-01,
275 9.909624e-01, 9.911281e-01, 9.912939e-01, 9.914596e-01, 9.916252e-01, 9.917908e-01, 9.919563e-01, 9.921218e-01,
276 9.922872e-01, 9.924526e-01, 9.926178e-01, 9.927831e-01, 9.929483e-01, 9.931134e-01, 9.932785e-01, 9.934435e-01,
277 9.936085e-01, 9.937734e-01, 9.939383e-01, 9.941031e-01, 9.942678e-01, 9.944325e-01, 9.945971e-01, 9.947617e-01,
278 9.949263e-01, 9.950907e-01, 9.952552e-01, 9.954196e-01, 9.955838e-01, 9.957481e-01, 9.959123e-01, 9.960765e-01,
279 9.962406e-01, 9.964046e-01, 9.965686e-01, 9.967325e-01, 9.968964e-01, 9.970602e-01, 9.972240e-01, 9.973878e-01,
280 9.975514e-01, 9.977150e-01, 9.978786e-01, 9.980421e-01, 9.982055e-01, 9.983689e-01, 9.985323e-01, 9.986956e-01,
281 9.988588e-01, 9.990220e-01, 9.991851e-01, 9.993482e-01, 9.995112e-01, 9.996742e-01, 9.998372e-01, 1.000000e+00,
282 };
283 int i = (int)(d * 2047);
284 assert(i >= 0 && i < 2048)((void) sizeof ((i >= 0 && i < 2048) ? 1 : 0), __extension__
({ if (i >= 0 && i < 2048) ; else __assert_fail
("i >= 0 && i < 2048", "ccv_icf.c", 284, __extension__
__PRETTY_FUNCTION__); }))
;
285 return cube_root[i];
286}
287
288static inline void _ccv_rgb_to_luv(const float r, const float g, const float b, float* pl, float* pu, float* pv)
289{
290 const float x = 0.412453f * r + 0.35758f * g + 0.180423f * b;
291 const float y = 0.212671f * r + 0.71516f * g + 0.072169f * b;
292 const float z = 0.019334f * r + 0.119193f * g + 0.950227f * b;
293
294 const float x_n = 0.312713f, y_n = 0.329016f;
295 const float uv_n_divisor = -2.f * x_n + 12.f * y_n + 3.f;
296 const float u_n = 4.f * x_n / uv_n_divisor;
297 const float v_n = 9.f * y_n / uv_n_divisor;
298
299 const float uv_divisor = ccv_max((x + 15.f * y + 3.f * z), FLT_EPSILON)({ typeof ((x + 15.f * y + 3.f * z)) _a = ((x + 15.f * y + 3.f
* z)); typeof (1.19209290e-7F) _b = (1.19209290e-7F); (_a >
_b) ? _a : _b; })
;
300 const float u = 4.f * x / uv_divisor;
301 const float v = 9.f * y / uv_divisor;
302
303 const float y_cube_root = fast_cube_root(y);
304
305 const float l_value = ccv_max(0.f, ((116.f * y_cube_root) - 16.f))({ typeof (0.f) _a = (0.f); typeof (((116.f * y_cube_root) - 16.f
)) _b = (((116.f * y_cube_root) - 16.f)); (_a > _b) ? _a :
_b; })
;
306 const float u_value = 13.f * l_value * (u - u_n);
307 const float v_value = 13.f * l_value * (v - v_n);
308
309 // L in [0, 100], U in [-134, 220], V in [-140, 122]
310 *pl = l_value * (255.f / 100.f);
311 *pu = (u_value + 134.f) * (255.f / (220.f + 134.f));
312 *pv = (v_value + 140.f) * (255.f / (122.f + 140.f));
313}
314
315// generating the integrate channels features (which combines the grayscale, gradient magnitude, and 6-direction HOG)
316void ccv_icf(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type)
317{
318 int ch = CCV_GET_CHANNEL(a->type)((a->type) & 0xFFF);
319 assert(ch == 1 || ch == 3)((void) sizeof ((ch == 1 || ch == 3) ? 1 : 0), __extension__ (
{ if (ch == 1 || ch == 3) ; else __assert_fail ("ch == 1 || ch == 3"
, "ccv_icf.c", 319, __extension__ __PRETTY_FUNCTION__); }))
;
320 int nchr = (ch == 1) ? 8 : 10;
321 ccv_declare_derived_signature(sig, a->sig != 0, ccv_sign_with_literal("ccv_icf"), a->sig, CCV_EOF_SIGN)char _ccv_identifier_321[] = ("ccv_icf"); size_t _ccv_string_size_321
= sizeof(_ccv_identifier_321);; uint64_t sig = (a->sig !=
0) ? ccv_cache_generate_signature(_ccv_identifier_321, _ccv_string_size_321
, a->sig, ((uint64_t)0)) : 0;
;
322 ccv_dense_matrix_t* db = *b = ccv_dense_matrix_renew(*b, a->rows, a->cols, CCV_32F | nchr, CCV_32F | nchr, sig);
323 ccv_object_return_if_cached(, db){ if ((!(db) || (((int*)(db))[0] & CCV_GARBAGE)) &&
(!(0) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0
) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (
((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int
*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0)
)[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] &
CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE
)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE)) &&
(!(0) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0
) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (
((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int
*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0)
)[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] &
CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE
)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE)) &&
(!(0) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0
) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (
((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int
*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0)
)[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] &
CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE
)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE)) &&
(!(0) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0
) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (
((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int
*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0)
)[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] &
CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE
)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE)) &&
(!(0) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0
) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (
((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int
*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0)
)[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] &
CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE
)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE)) &&
(!(0) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0
) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (
((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int
*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0)
)[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] &
CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE
)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE)) &&
(!(0) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0
) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (
((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int
*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0)
)[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] &
CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE
)) && (!(0) || (((int*)(0))[0] & CCV_GARBAGE)) &&
(!(0) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0
) || (((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (
((int*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int
*)(0))[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0)
)[0] & CCV_GARBAGE)) && (!(0) || (((int*)(0))[0] &
CCV_GARBAGE))) { (void)((db) && (((int*)(db))[0] &=
~CCV_GARBAGE));(void)((0) && (((int*)(0))[0] &= ~
CCV_GARBAGE));(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE
));(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE)
);(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE))
;(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));
(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(
void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void
)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)
((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)(
(0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)((
0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0
) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0)
&& (((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) &&
(((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (
((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && ((
(int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((
int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int
*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*
)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)
(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(
0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0
))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0)
)[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0))
[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0))[
0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0))[0
] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0))[0]
&= ~CCV_GARBAGE));(void)((0) && (((int*)(0))[0] &=
~CCV_GARBAGE));(void)((0) && (((int*)(0))[0] &= ~
CCV_GARBAGE));(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE
));(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE)
);(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE))
;(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));
(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(
void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void
)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)
((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)(
(0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)((
0) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0
) && (((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0)
&& (((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) &&
(((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (
((int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && ((
(int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((
int*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int
*)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*
)(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)
(0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(
0))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0
))[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0)
)[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0))
[0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0))[
0] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0))[0
] &= ~CCV_GARBAGE));(void)((0) && (((int*)(0))[0]
&= ~CCV_GARBAGE));(void)((0) && (((int*)(0))[0] &=
~CCV_GARBAGE));(void)((0) && (((int*)(0))[0] &= ~
CCV_GARBAGE));(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE
));(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE)
);(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE))
;(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));
(void)((0) && (((int*)(0))[0] &= ~CCV_GARBAGE));;
; return ; } }
;
324 ccv_dense_matrix_t* ag = 0;
325 ccv_dense_matrix_t* mg = 0;
326 ccv_gradient(a, &ag, 0, &mg, 0, 1, 1);
327 float* agp = ag->data.f32;
328 float* mgp = mg->data.f32;
329 float* dbp = db->data.f32;
330 ccv_zero(db);
331 int i, j, k;
332 unsigned char* a_ptr = a->data.u8;
333 float magnitude_scaling = 1 / sqrtf(2); // regularize it to 0~1
334 if (ch == 1)
335 {
336#define for_block(_, _for_get) \
337 for (i = 0; i < a->rows; i++) \
338 { \
339 for (j = 0; j < a->cols; j++) \
340 { \
341 dbp[0] = _for_get(a_ptr, j, 0); \
342 dbp[1] = mgp[j] * magnitude_scaling; \
343 float agr = (ccv_clamp(agp[j] <= 180 ? agp[j] : agp[j] - 180, 0, 179.99)({ typeof (0) _a = (0); typeof (179.99) _b = (179.99); typeof
(agp[j] <= 180 ? agp[j] : agp[j] - 180) _x = (agp[j] <=
180 ? agp[j] : agp[j] - 180); (_x < _a) ? _a : ((_x > _b
) ? _b : _x); })
/ 180.0) * 6; \
344 int ag0 = (int)agr; \
345 int ag1 = ag0 < 5 ? ag0 + 1 : 0; \
346 agr = agr - ag0; \
347 dbp[2 + ag0] = dbp[1] * (1 - agr); \
348 dbp[2 + ag1] = dbp[1] * agr; \
349 dbp += 8; \
350 } \
351 a_ptr += a->step; \
352 agp += a->cols; \
353 mgp += a->cols; \
354 }
355 ccv_matrix_getter(a->type, for_block){ switch (((a->type) & 0xFF000)) { case CCV_32S: { for_block
(, _ccv_get_32s_value); break; } case CCV_32F: { for_block(, _ccv_get_32f_value
); break; } case CCV_64S: { for_block(, _ccv_get_64s_value); break
; } case CCV_64F: { for_block(, _ccv_get_64f_value); break; }
default: { for_block(, _ccv_get_8u_value); } } }
;
356#undef for_block
357 } else {
358 // color one, luv, gradient magnitude, and 6-direction HOG
359#define for_block(_, _for_get) \
360 for (i = 0; i < a->rows; i++) \
361 { \
362 for (j = 0; j < a->cols; j++) \
363 { \
364 _ccv_rgb_to_luv(_for_get(a_ptr, j * ch, 0) / 255.0, \
365 _for_get(a_ptr, j * ch + 1, 0) / 255.0, \
366 _for_get(a_ptr, j * ch + 2, 0) / 255.0, \
367 dbp, dbp + 1, dbp + 2); \
368 float agv = agp[j * ch]; \
369 float mgv = mgp[j * ch]; \
370 for (k = 1; k < ch; k++) \
371 { \
372 if (mgp[j * ch + k] > mgv) \
373 { \
374 mgv = mgp[j * ch + k]; \
375 agv = agp[j * ch + k]; \
376 } \
377 } \
378 dbp[3] = mgv * magnitude_scaling; \
379 float agr = (ccv_clamp(agv <= 180 ? agv : agv - 180, 0, 179.99)({ typeof (0) _a = (0); typeof (179.99) _b = (179.99); typeof
(agv <= 180 ? agv : agv - 180) _x = (agv <= 180 ? agv :
agv - 180); (_x < _a) ? _a : ((_x > _b) ? _b : _x); })
/ 180.0) * 6; \
380 int ag0 = (int)agr; \
381 int ag1 = ag0 < 5 ? ag0 + 1 : 0; \
382 agr = agr - ag0; \
383 dbp[4 + ag0] = dbp[3] * (1 - agr); \
384 dbp[4 + ag1] = dbp[3] * agr; \
385 dbp += 10; \
386 } \
387 a_ptr += a->step; \
388 agp += a->cols * ch; \
389 mgp += a->cols * ch; \
390 }
391 ccv_matrix_getter(a->type, for_block){ switch (((a->type) & 0xFF000)) { case CCV_32S: { for_block
(, _ccv_get_32s_value); break; } case CCV_32F: { for_block(, _ccv_get_32f_value
); break; } case CCV_64S: { for_block(, _ccv_get_64s_value); break
; } case CCV_64F: { for_block(, _ccv_get_64f_value); break; }
default: { for_block(, _ccv_get_8u_value); } } }
;
392#undef for_block
393 }
394 ccv_matrix_free(ag);
395 ccv_matrix_free(mg);
396}
397
398static inline float _ccv_icf_run_feature(ccv_icf_feature_t* feature, float* ptr, int cols, int ch, int x, int y)
399{
400 float c = feature->beta;
401 int q;
402 for (q = 0; q < feature->count; q++)
403 c += (ptr[(feature->sat[q * 2 + 1].x + x + 1 + (feature->sat[q * 2 + 1].y + y + 1) * cols) * ch + feature->channel[q]] - ptr[(feature->sat[q * 2].x + x + (feature->sat[q * 2 + 1].y + y + 1) * cols) * ch + feature->channel[q]] + ptr[(feature->sat[q * 2].x + x + (feature->sat[q * 2].y + y) * cols) * ch + feature->channel[q]] - ptr[(feature->sat[q * 2 + 1].x + x + 1 + (feature->sat[q * 2].y + y) * cols) * ch + feature->channel[q]]) * feature->alpha[q];
404 return c;
405}
406
407static inline int _ccv_icf_run_weak_classifier(ccv_icf_decision_tree_t* weak_classifier, float* ptr, int cols, int ch, int x, int y)
408{
409 float c = _ccv_icf_run_feature(weak_classifier->features, ptr, cols, ch, x, y);
410 if (c > 0)
411 {
412 if (!(weak_classifier->pass & 0x1))
413 return 1;
414 return _ccv_icf_run_feature(weak_classifier->features + 2, ptr, cols, ch, x, y) > 0;
415 } else {
416 if (!(weak_classifier->pass & 0x2))
417 return 0;
418 return _ccv_icf_run_feature(weak_classifier->features + 1, ptr, cols, ch, x, y) > 0;
419 }
420}
421
422#ifdef HAVE_GSL1
423static void _ccv_icf_randomize_feature(gsl_rng* rng, ccv_size_t size, int minimum, ccv_icf_feature_t* feature, int grayscale)
424{
425 feature->count = gsl_rng_uniform_int(rng, CCV_ICF_SAT_MAX(2)) + 1;
426 assert(feature->count <= CCV_ICF_SAT_MAX)((void) sizeof ((feature->count <= (2)) ? 1 : 0), __extension__
({ if (feature->count <= (2)) ; else __assert_fail ("feature->count <= CCV_ICF_SAT_MAX"
, "ccv_icf.c", 426, __extension__ __PRETTY_FUNCTION__); }))
;
427 int i;
428 feature->beta = 0;
429 for (i = 0; i < feature->count; i++)
430 {
431 int x0, y0, x1, y1;
432 do {
433 x0 = gsl_rng_uniform_int(rng, size.width);
434 x1 = gsl_rng_uniform_int(rng, size.width);
435 y0 = gsl_rng_uniform_int(rng, size.height);
436 y1 = gsl_rng_uniform_int(rng, size.height);
437 } while ((ccv_max(x0, x1)({ typeof (x0) _a = (x0); typeof (x1) _b = (x1); (_a > _b)
? _a : _b; })
- ccv_min(x0, x1)({ typeof (x0) _a = (x0); typeof (x1) _b = (x1); (_a < _b)
? _a : _b; })
+ 1) * (ccv_max(y0, y1)({ typeof (y0) _a = (y0); typeof (y1) _b = (y1); (_a > _b)
? _a : _b; })
- ccv_min(y0, y1)({ typeof (y0) _a = (y0); typeof (y1) _b = (y1); (_a < _b)
? _a : _b; })
+ 1) < (minimum + 1) * (minimum + 1) ||
438 (ccv_max(x0, x1)({ typeof (x0) _a = (x0); typeof (x1) _b = (x1); (_a > _b)
? _a : _b; })
- ccv_min(x0, x1)({ typeof (x0) _a = (x0); typeof (x1) _b = (x1); (_a < _b)
? _a : _b; })
+ 1) < minimum ||
439 (ccv_max(y0, y1)({ typeof (y0) _a = (y0); typeof (y1) _b = (y1); (_a > _b)
? _a : _b; })
- ccv_min(y0, y1)({ typeof (y0) _a = (y0); typeof (y1) _b = (y1); (_a < _b)
? _a : _b; })
+ 1) < minimum);
440 feature->sat[i * 2].x = ccv_min(x0, x1)({ typeof (x0) _a = (x0); typeof (x1) _b = (x1); (_a < _b)
? _a : _b; })
;
441 feature->sat[i * 2].y = ccv_min(y0, y1)({ typeof (y0) _a = (y0); typeof (y1) _b = (y1); (_a < _b)
? _a : _b; })
;
442 feature->sat[i * 2 + 1].x = ccv_max(x0, x1)({ typeof (x0) _a = (x0); typeof (x1) _b = (x1); (_a > _b)
? _a : _b; })
;
443 feature->sat[i * 2 + 1].y = ccv_max(y0, y1)({ typeof (y0) _a = (y0); typeof (y1) _b = (y1); (_a > _b)
? _a : _b; })
;
444 feature->channel[i] = gsl_rng_uniform_int(rng, grayscale ? 8 : 10); // 8-channels for grayscale, and 10-channels for rgb
445 assert(feature->channel[i] >= 0 && feature->channel[i] < (grayscale ? 8 : 10))((void) sizeof ((feature->channel[i] >= 0 && feature
->channel[i] < (grayscale ? 8 : 10)) ? 1 : 0), __extension__
({ if (feature->channel[i] >= 0 && feature->
channel[i] < (grayscale ? 8 : 10)) ; else __assert_fail ("feature->channel[i] >= 0 && feature->channel[i] < (grayscale ? 8 : 10)"
, "ccv_icf.c", 445, __extension__ __PRETTY_FUNCTION__); }))
;
446 feature->alpha[i] = gsl_rng_uniform(rng) / (float)((feature->sat[i * 2 + 1].x - feature->sat[i * 2].x + 1) * (feature->sat[i * 2 + 1].y - feature->sat[i * 2].y + 1));
447 }
448}
449
450static void _ccv_icf_check_params(ccv_icf_new_param_t params)
451{
452 assert(params.size.width > 0 && params.size.height > 0)((void) sizeof ((params.size.width > 0 && params.size
.height > 0) ? 1 : 0), __extension__ ({ if (params.size.width
> 0 && params.size.height > 0) ; else __assert_fail
("params.size.width > 0 && params.size.height > 0"
, "ccv_icf.c", 452, __extension__ __PRETTY_FUNCTION__); }))
;
453 assert(params.deform_shift >= 0)((void) sizeof ((params.deform_shift >= 0) ? 1 : 0), __extension__
({ if (params.deform_shift >= 0) ; else __assert_fail ("params.deform_shift >= 0"
, "ccv_icf.c", 453, __extension__ __PRETTY_FUNCTION__); }))
;
454 assert(params.deform_angle >= 0)((void) sizeof ((params.deform_angle >= 0) ? 1 : 0), __extension__
({ if (params.deform_angle >= 0) ; else __assert_fail ("params.deform_angle >= 0"
, "ccv_icf.c", 454, __extension__ __PRETTY_FUNCTION__); }))
;
455 assert(params.deform_scale >= 0 && params.deform_scale < 1)((void) sizeof ((params.deform_scale >= 0 && params
.deform_scale < 1) ? 1 : 0), __extension__ ({ if (params.deform_scale
>= 0 && params.deform_scale < 1) ; else __assert_fail
("params.deform_scale >= 0 && params.deform_scale < 1"
, "ccv_icf.c", 455, __extension__ __PRETTY_FUNCTION__); }))
;
456 assert(params.feature_size > 0)((void) sizeof ((params.feature_size > 0) ? 1 : 0), __extension__
({ if (params.feature_size > 0) ; else __assert_fail ("params.feature_size > 0"
, "ccv_icf.c", 456, __extension__ __PRETTY_FUNCTION__); }))
;
457 assert(params.acceptance > 0 && params.acceptance < 1.0)((void) sizeof ((params.acceptance > 0 && params.acceptance
< 1.0) ? 1 : 0), __extension__ ({ if (params.acceptance >
0 && params.acceptance < 1.0) ; else __assert_fail
("params.acceptance > 0 && params.acceptance < 1.0"
, "ccv_icf.c", 457, __extension__ __PRETTY_FUNCTION__); }))
;
458}
459
460static ccv_dense_matrix_t* _ccv_icf_capture_feature(gsl_rng* rng, ccv_dense_matrix_t* image, ccv_decimal_pose_t pose, ccv_size_t size, ccv_margin_t margin, float deform_angle, float deform_scale, float deform_shift)
461{
462 float rotate_x = (deform_angle * 2 * gsl_rng_uniform(rng) - deform_angle) * CCV_PI(3.141592653589793) / 180 + pose.pitch;
463 float rotate_y = (deform_angle * 2 * gsl_rng_uniform(rng) - deform_angle) * CCV_PI(3.141592653589793) / 180 + pose.yaw;
464 float rotate_z = (deform_angle * 2 * gsl_rng_uniform(rng) - deform_angle) * CCV_PI(3.141592653589793) / 180 + pose.roll;
465 float scale = gsl_rng_uniform(rng);
466 // to make the scale evenly distributed, for example, when deforming of 1/2 ~ 2, we want it to distribute around 1, rather than any average of 1/2 ~ 2
467 scale = (1 + deform_scale * scale) / (1 + deform_scale * (1 - scale));
468 float scale_ratio = sqrtf((float)(size.width * size.height) / (pose.a * pose.b * 4));
469 float m00 = cosf(rotate_z) * scale;
470 float m01 = cosf(rotate_y) * sinf(rotate_z) * scale;
471 float m02 = (deform_shift * 2 * gsl_rng_uniform(rng) - deform_shift) / scale_ratio + pose.x + (margin.right - margin.left) / scale_ratio - image->cols * 0.5;
472 float m10 = (sinf(rotate_y) * cosf(rotate_z) - cosf(rotate_x) * sinf(rotate_z)) * scale;
473 float m11 = (sinf(rotate_y) * sinf(rotate_z) + cosf(rotate_x) * cosf(rotate_z)) * scale;
474 float m12 = (deform_shift * 2 * gsl_rng_uniform(rng) - deform_shift) / scale_ratio + pose.y + (margin.bottom - margin.top) / scale_ratio - image->rows * 0.5;
475 float m20 = (sinf(rotate_y) * cosf(rotate_z) + sinf(rotate_x) * sinf(rotate_z)) * scale;
476 float m21 = (sinf(rotate_y) * sinf(rotate_z) - sinf(rotate_x) * cosf(rotate_z)) * scale;
477 float m22 = cosf(rotate_x) * cosf(rotate_y);
478 ccv_dense_matrix_t* b = 0;
479 ccv_perspective_transform(image, &b, 0, m00, m01, m02, m10, m11, m12, m20, m21, m22);
480 ccv_dense_matrix_t* resize = 0;
481 // have 1px border around the grayscale image because we need these to compute correct gradient feature
482 ccv_size_t scale_size = {
483 .width = (int)((size.width + margin.left + margin.right + 2) / scale_ratio + 0.5),
484 .height = (int)((size.height + margin.top + margin.bottom + 2) / scale_ratio + 0.5),
485 };
486 assert(scale_size.width > 0 && scale_size.height > 0)((void) sizeof ((scale_size.width > 0 && scale_size
.height > 0) ? 1 : 0), __extension__ ({ if (scale_size.width
> 0 && scale_size.height > 0) ; else __assert_fail
("scale_size.width > 0 && scale_size.height > 0"
, "ccv_icf.c", 486, __extension__ __PRETTY_FUNCTION__); }))
;
487 ccv_slice(b, (ccv_matrix_t**)&resize, 0, (int)(b->rows * 0.5 - (size.height + margin.top + margin.bottom + 2) / scale_ratio * 0.5 + 0.5), (int)(b->cols * 0.5 - (size.width + margin.left + margin.right + 2) / scale_ratio * 0.5 + 0.5), scale_size.height, scale_size.width);
488 ccv_matrix_free(b);
489 b = 0;
490 if (scale_ratio > 1)
491 ccv_resample(resize, &b, 0, size.height + margin.top + margin.bottom + 2, size.width + margin.left + margin.right + 2, CCV_INTER_CUBIC);
492 else
493 ccv_resample(resize, &b, 0, size.height + margin.top + margin.bottom + 2, size.width + margin.left + margin.right + 2, CCV_INTER_AREA);
494 ccv_matrix_free(resize);
495 return b;
496}
497
498typedef struct {
499 uint8_t correct:1;
500 double weight;
501 float rate;
502} ccv_icf_example_state_t;
503
504typedef struct {
505 uint8_t classifier:1;
506 uint8_t positives:1;
507 uint8_t negatives:1;
508 uint8_t features:1;
509 uint8_t example_state:1;
510 uint8_t precomputed:1;
511} ccv_icf_classifier_cascade_persistence_state_t;
512
513typedef struct {
514 uint32_t index;
515 float value;
516} ccv_icf_value_index_t;
517
518typedef struct {
519 ccv_function_state_reserve_fieldint line_no;;
520 int i;
521 int bootstrap;
522 ccv_icf_new_param_t params;
523 ccv_icf_classifier_cascade_t* classifier;
524 ccv_array_t* positives;
525 ccv_array_t* negatives;
526 ccv_icf_feature_t* features;
527 ccv_size_t size;
528 ccv_margin_t margin;
529 ccv_icf_example_state_t* example_state;
530 uint8_t* precomputed;
531 ccv_icf_classifier_cascade_persistence_state_t x;
532} ccv_icf_classifier_cascade_state_t;
533
534static void _ccv_icf_write_classifier_cascade_state(ccv_icf_classifier_cascade_state_t* state, const char* directory)
535{
536 char filename[1024];
537 snprintf(filename, 1024, "%s/state", directory);
538 FILE* w = fopen(filename, "w+");
539 fprintf(w, "%d %d %d\n", state->line_no, state->i, state->bootstrap);
540 fprintf(w, "%d %d %d\n", state->params.feature_size, state->size.width, state->size.height);
541 fprintf(w, "%d %d %d %d\n", state->margin.left, state->margin.top, state->margin.right, state->margin.bottom);
542 fclose(w);
543 int i, q;
544 if (!state->x.positives)
545 {
546 snprintf(filename, 1024, "%s/positives", directory);
547 w = fopen(filename, "wb+");
548 fwrite(&state->positives->rnum, sizeof(state->positives->rnum), 1, w);
549 fwrite(&state->positives->rsize, sizeof(state->positives->rsize), 1, w);
550 for (i = 0; i < state->positives->rnum; i++)
551 {
552 ccv_dense_matrix_t* a = (ccv_dense_matrix_t*)ccv_array_get(state->positives, i)((void*)(((char*)((state->positives)->data)) + (size_t)
(state->positives)->rsize * (size_t)(i)))
;
553 assert(a->rows == state->size.height + state->margin.top + state->margin.bottom + 2 && a->cols == state->size.width + state->margin.left + state->margin.right + 2)((void) sizeof ((a->rows == state->size.height + state->
margin.top + state->margin.bottom + 2 && a->cols
== state->size.width + state->margin.left + state->
margin.right + 2) ? 1 : 0), __extension__ ({ if (a->rows ==
state->size.height + state->margin.top + state->margin
.bottom + 2 && a->cols == state->size.width + state
->margin.left + state->margin.right + 2) ; else __assert_fail
("a->rows == state->size.height + state->margin.top + state->margin.bottom + 2 && a->cols == state->size.width + state->margin.left + state->margin.right + 2"
, "ccv_icf.c", 553, __extension__ __PRETTY_FUNCTION__); }))
;
554 fwrite(a, 1, state->positives->rsize, w);
555 }
556 fclose(w);
557 state->x.positives = 1;
558 }
559 if (!state->x.negatives)
560 {
561 assert(state->negatives->rsize == state->positives->rsize)((void) sizeof ((state->negatives->rsize == state->positives
->rsize) ? 1 : 0), __extension__ ({ if (state->negatives
->rsize == state->positives->rsize) ; else __assert_fail
("state->negatives->rsize == state->positives->rsize"
, "ccv_icf.c", 561, __extension__ __PRETTY_FUNCTION__); }))
;
562 snprintf(filename, 1024, "%s/negatives", directory);
563 w = fopen(filename, "wb+");
564 fwrite(&state->negatives->rnum, sizeof(state->negatives->rnum), 1, w);
565 fwrite(&state->negatives->rsize, sizeof(state->negatives->rsize), 1, w);
566 for (i = 0; i < state->negatives->rnum; i++)
567 {
568 ccv_dense_matrix_t* a = (ccv_dense_matrix_t*)ccv_array_get(state->negatives, i)((void*)(((char*)((state->negatives)->data)) + (size_t)
(state->negatives)->rsize * (size_t)(i)))
;
569 assert(a->rows == state->size.height + state->margin.top + state->margin.bottom + 2 && a->cols == state->size.width + state->margin.left + state->margin.right + 2)((void) sizeof ((a->rows == state->size.height + state->
margin.top + state->margin.bottom + 2 && a->cols
== state->size.width + state->margin.left + state->
margin.right + 2) ? 1 : 0), __extension__ ({ if (a->rows ==
state->size.height + state->margin.top + state->margin
.bottom + 2 && a->cols == state->size.width + state
->margin.left + state->margin.right + 2) ; else __assert_fail
("a->rows == state->size.height + state->margin.top + state->margin.bottom + 2 && a->cols == state->size.width + state->margin.left + state->margin.right + 2"
, "ccv_icf.c", 569, __extension__ __PRETTY_FUNCTION__); }))
;
570 fwrite(a, 1, state->negatives->rsize, w);
571 }
572 fclose(w);
573 state->x.negatives = 1;
574 }
575 if (!state->x.features)
576 {
577 snprintf(filename, 1024, "%s/features", directory);
578 w = fopen(filename, "w+");
579 for (i = 0; i < state->params.feature_size; i++)
580 {
581 ccv_icf_feature_t* feature = state->features + i;
582 fprintf(w, "%d %a\n", feature->count, feature->beta);
583 for (q = 0; q < feature->count; q++)
584 fprintf(w, "%d %a %d %d %d %d\n", feature->channel[q], feature->alpha[q], feature->sat[q * 2].x, feature->sat[q * 2].y, feature->sat[q * 2 + 1].x, feature->sat[q * 2 + 1].y);
585 }
586 fclose(w);
587 state->x.features = 1;
588 }
589 if (!state->x.example_state)
590 {
591 snprintf(filename, 1024, "%s/example_state", directory);
592 w = fopen(filename, "w+");
593 for (i = 0; i < state->positives->rnum + state->negatives->rnum; i++)
594 fprintf(w, "%u %la %a\n", (uint32_t)state->example_state[i].correct, state->example_state[i].weight, state->example_state[i].rate);
595 fclose(w);
596 state->x.example_state = 1;
597 }
598 if (!state->x.precomputed)
599 {
600 size_t step = (3 * (state->positives->rnum + state->negatives->rnum) + 3) & -4;
601 snprintf(filename, 1024, "%s/precomputed", directory);
602 w = fopen(filename, "wb+");
603 fwrite(state->precomputed, 1, step * state->params.feature_size, w);
604 fclose(w);
605 state->x.precomputed = 1;
606 }
607 if (!state->x.classifier)
608 {
609 snprintf(filename, 1024, "%s/cascade", directory);
610 ccv_icf_write_classifier_cascade(state->classifier, filename);
611 state->x.classifier = 1;
612 }
613}
614
615static void _ccv_icf_read_classifier_cascade_state(const char* directory, ccv_icf_classifier_cascade_state_t* state)
616{
617 char filename[1024];
618 state->line_no = state->i = 0;
619 state->bootstrap = 0;
620 snprintf(filename, 1024, "%s/state", directory);
621 FILE* r = fopen(filename, "r");
622 if (r)
623 {
624 int feature_size;
625 fscanf(r, "%d %d %d", &state->line_no, &state->i, &state->bootstrap);
626 fscanf(r, "%d %d %d", &feature_size, &state->size.width, &state->size.height);
627 fscanf(r, "%d %d %d %d", &state->margin.left, &state->margin.top, &state->margin.right, &state->margin.bottom);
628 assert(feature_size == state->params.feature_size)((void) sizeof ((feature_size == state->params.feature_size
) ? 1 : 0), __extension__ ({ if (feature_size == state->params
.feature_size) ; else __assert_fail ("feature_size == state->params.feature_size"
, "ccv_icf.c", 628, __extension__ __PRETTY_FUNCTION__); }))
;
629 fclose(r);
630 }
631 int i, q;
632 snprintf(filename, 1024, "%s/positives", directory);
633 r = fopen(filename, "rb");
634 state->x.precomputed = state->x.features = state->x.example_state = state->x.classifier = state->x.positives = state->x.negatives = 1;
635 if (r)
636 {
637 int rnum, rsize;
638 fread(&rnum, sizeof(rnum), 1, r);
639 fread(&rsize, sizeof(rsize), 1, r);
640 state->positives = ccv_array_new(rsize, rnum, 0);
641 ccv_dense_matrix_t* a = (ccv_dense_matrix_t*)alloca(rsize)__builtin_alloca (rsize);
642 for (i = 0; i < rnum; i++)
643 {
644 fread(a, 1, rsize, r);
645 assert(a->rows == state->size.height + state->margin.top + state->margin.bottom + 2 && a->cols == state->size.width + state->margin.left + state->margin.right + 2)((void) sizeof ((a->rows == state->size.height + state->
margin.top + state->margin.bottom + 2 && a->cols
== state->size.width + state->margin.left + state->
margin.right + 2) ? 1 : 0), __extension__ ({ if (a->rows ==
state->size.height + state->margin.top + state->margin
.bottom + 2 && a->cols == state->size.width + state
->margin.left + state->margin.right + 2) ; else __assert_fail
("a->rows == state->size.height + state->margin.top + state->margin.bottom + 2 && a->cols == state->size.width + state->margin.left + state->margin.right + 2"
, "ccv_icf.c", 645, __extension__ __PRETTY_FUNCTION__); }))
;
646 ccv_array_push(state->positives, a);
647 }
648 fclose(r);
649 }
650 snprintf(filename, 1024, "%s/negatives", directory);
651 r = fopen(filename, "rb");
652 if (r)
653 {
654 int rnum, rsize;
655 fread(&rnum, sizeof(rnum), 1, r);
656 fread(&rsize, sizeof(rsize), 1, r);
657 state->negatives = ccv_array_new(rsize, rnum, 0);
658 ccv_dense_matrix_t* a = (ccv_dense_matrix_t*)alloca(rsize)__builtin_alloca (rsize);
659 for (i = 0; i < rnum; i++)
660 {
661 fread(a, 1, rsize, r);
662 assert(a->rows == state->size.height + state->margin.top + state->margin.bottom + 2 && a->cols == state->size.width + state->margin.left + state->margin.right + 2)((void) sizeof ((a->rows == state->size.height + state->
margin.top + state->margin.bottom + 2 && a->cols
== state->size.width + state->margin.left + state->
margin.right + 2) ? 1 : 0), __extension__ ({ if (a->rows ==
state->size.height + state->margin.top + state->margin
.bottom + 2 && a->cols == state->size.width + state
->margin.left + state->margin.right + 2) ; else __assert_fail
("a->rows == state->size.height + state->margin.top + state->margin.bottom + 2 && a->cols == state->size.width + state->margin.left + state->margin.right + 2"
, "ccv_icf.c", 662, __extension__ __PRETTY_FUNCTION__); }))
;
663 ccv_array_push(state->negatives, a);
664 }
665 fclose(r);
666 }
667 snprintf(filename, 1024, "%s/features", directory);
668 r = fopen(filename, "r");
669 if (r)
670 {
671 state->features = (ccv_icf_feature_t*)ccmallocmalloc(state->params.feature_size * sizeof(ccv_icf_feature_t));
672 for (i = 0; i < state->params.feature_size; i++)
673 {
674 ccv_icf_feature_t* feature = state->features + i;
675 fscanf(r, "%d %a", &feature->count, &feature->beta);
676 for (q = 0; q < feature->count; q++)
677 fscanf(r, "%d %a %d %d %d %d", &feature->channel[q], &feature->alpha[q], &feature->sat[q * 2].x, &feature->sat[q * 2].y, &feature->sat[q * 2 + 1].x, &feature->sat[q * 2 + 1].y);
678 }
679 fclose(r);
680 }
681 snprintf(filename, 1024, "%s/example_state", directory);
682 r = fopen(filename, "r");
683 if (r)
684 {
685 state->example_state = (ccv_icf_example_state_t*)ccmallocmalloc((state->positives->rnum + state->negatives->rnum) * sizeof(ccv_icf_example_state_t));
686 for (i = 0; i < state->positives->rnum + state->negatives->rnum; i++)
687 {
688 uint32_t correct;
689 double weight;
690 float rate;
691 fscanf(r, "%u %la %a", &correct, &weight, &rate);
692 state->example_state[i].correct = correct;
693 state->example_state[i].weight = weight;
694 state->example_state[i].rate = rate;
695 }
696 fclose(r);
697 } else
698 state->example_state = 0;
699 snprintf(filename, 1024, "%s/precomputed", directory);
700 r = fopen(filename, "rb");
701 if (r)
702 {
703 size_t step = (3 * (state->positives->rnum + state->negatives->rnum) + 3) & -4;
704 state->precomputed = (uint8_t*)ccmallocmalloc(sizeof(uint8_t) * state->params.feature_size * step);
705 fread(state->precomputed, 1, step * state->params.feature_size, r);
706 fclose(r);
707 } else
708 state->precomputed = 0;
709 snprintf(filename, 1024, "%s/cascade", directory);
710 state->classifier = ccv_icf_read_classifier_cascade(filename);
711 if (!state->classifier)
712 {
713 state->classifier = (ccv_icf_classifier_cascade_t*)ccmallocmalloc(sizeof(ccv_icf_classifier_cascade_t));
714 state->classifier->count = 0;
715 state->classifier->grayscale = state->params.grayscale;
716 state->classifier->weak_classifiers = (ccv_icf_decision_tree_t*)ccmallocmalloc(sizeof(ccv_icf_decision_tree_t) * state->params.weak_classifier);
717 } else {
718 if (state->classifier->count < state->params.weak_classifier)
719 state->classifier->weak_classifiers = (ccv_icf_decision_tree_t*)ccreallocrealloc(state->classifier->weak_classifiers, sizeof(ccv_icf_decision_tree_t) * state->params.weak_classifier);
720 }
721}
722
723#define less_than(s1, s2, aux) ((s1).value < (s2).value)
724static CCV_IMPLEMENT_QSORT(_ccv_icf_precomputed_ordering, ccv_icf_value_index_t, less_than)void _ccv_icf_precomputed_ordering(ccv_icf_value_index_t *array
, size_t total, int aux) { int isort_thresh = 7; ccv_icf_value_index_t
t; int sp = 0; struct { ccv_icf_value_index_t *lb; ccv_icf_value_index_t
*ub; } stack[48]; if( total <= 1 ) return; stack[0].lb = array
; stack[0].ub = array + (total - 1); while( sp >= 0 ) { ccv_icf_value_index_t
* left = stack[sp].lb; ccv_icf_value_index_t* right = stack[sp
--].ub; for(;;) { int i, n = (int)(right - left) + 1, m; ccv_icf_value_index_t
* ptr; ccv_icf_value_index_t* ptr2; if( n <= isort_thresh )
{ insert_sort: for( ptr = left + 1; ptr <= right; ptr++ )
{ for( ptr2 = ptr; ptr2 > left && less_than(ptr2[
0],ptr2[-1], aux); ptr2--) (((t)) = ((ptr2[0])), ((ptr2[0])) =
((ptr2[-1])), ((ptr2[-1])) = ((t))); } break; } else { ccv_icf_value_index_t
* left0; ccv_icf_value_index_t* left1; ccv_icf_value_index_t*
right0; ccv_icf_value_index_t* right1; ccv_icf_value_index_t
* pivot; ccv_icf_value_index_t* a; ccv_icf_value_index_t* b; ccv_icf_value_index_t
* c; int swap_cnt = 0; left0 = left; right0 = right; pivot = left
+ (n/2); if( n > 40 ) { int d = n / 8; a = left, b = left
+ d, c = left + 2*d; left = less_than(*a, *b, aux) ? (less_than
(*b, *c, aux) ? b : (less_than(*a, *c, aux) ? c : a)) : (less_than
(*c, *b, aux) ? b : (less_than(*a, *c, aux) ? a : c)); a = pivot
- d, b = pivot, c = pivot + d; pivot = less_than(*a, *b, aux
) ? (less_than(*b, *c, aux) ? b : (less_than(*a, *c, aux) ? c
: a)) : (less_than(*c, *b, aux) ? b : (less_than(*a, *c, aux
) ? a : c)); a = right - 2*d, b = right - d, c = right; right
= less_than(*a, *b, aux) ? (less_than(*b, *c, aux) ? b : (less_than
(*a, *c, aux) ? c : a)) : (less_than(*c, *b, aux) ? b : (less_than
(*a, *c, aux) ? a : c)); } a = left, b = pivot, c = right; pivot
= less_than(*a, *b, aux) ? (less_than(*b, *c, aux) ? b : (less_than
(*a, *c, aux) ? c : a)) : (less_than(*c, *b, aux) ? b : (less_than
(*a, *c, aux) ? a : c)); if( pivot != left0 ) { (((t)) = ((*pivot
)), ((*pivot)) = ((*left0)), ((*left0)) = ((t))); pivot = left0
; } left = left1 = left0 + 1; right = right1 = right0; for(;;
) { while( left <= right && !less_than(*pivot, *left
, aux) ) { if( !less_than(*left, *pivot, aux) ) { if( left >
left1 ) (((t)) = ((*left1)), ((*left1)) = ((*left)), ((*left
)) = ((t))); swap_cnt = 1; left1++; } left++; } while( left <=
right && !less_than(*right, *pivot, aux) ) { if( !less_than
(*pivot, *right, aux) ) { if( right < right1 ) (((t)) = ((
*right1)), ((*right1)) = ((*right)), ((*right)) = ((t))); swap_cnt
= 1; right1--; } right--; } if( left > right ) break; (((
t)) = ((*left)), ((*left)) = ((*right)), ((*right)) = ((t)));
swap_cnt = 1; left++; right--; } if( swap_cnt == 0 ) { left =
left0, right = right0; goto insert_sort; } n = ({ typeof ((int
)(left1 - left0)) _a = ((int)(left1 - left0)); typeof ((int)(
left - left1)) _b = ((int)(left - left1)); (_a < _b) ? _a :
_b; }); for( i = 0; i < n; i++ ) (((t)) = ((left0[i])), (
(left0[i])) = ((left[i-n])), ((left[i-n])) = ((t))); n = ({ typeof
((int)(right0 - right1)) _a = ((int)(right0 - right1)); typeof
((int)(right1 - right)) _b = ((int)(right1 - right)); (_a <
_b) ? _a : _b; }); for( i = 0; i < n; i++ ) (((t)) = ((left
[i])), ((left[i])) = ((right0[i-n+1])), ((right0[i-n+1])) = (
(t))); n = (int)(left - left1); m = (int)(right1 - right); if
( n > 1 ) { if( m > 1 ) { if( n > m ) { stack[++sp].
lb = left0; stack[sp].ub = left0 + n - 1; left = right0 - m +
1, right = right0; } else { stack[++sp].lb = right0 - m + 1;
stack[sp].ub = right0; left = left0, right = left0 + n - 1; }
} else left = left0, right = left0 + n - 1; } else if( m >
1 ) left = right0 - m + 1, right = right0; else break; } } }
}
725#undef less_than
726
727static inline void _ccv_icf_3_uint8_to_1_uint1_1_uint23(uint8_t* u8, uint8_t* u1, uint32_t* uint23)
728{
729 *u1 = (u8[0] >> 7);
730 *uint23 = (((uint32_t)(u8[0] & 0x7f)) << 16) | ((uint32_t)(u8[1]) << 8) | u8[2];
731}
732
733static inline uint32_t _ccv_icf_3_uint8_to_1_uint23(uint8_t* u8)
734{
735 return (((uint32_t)(u8[0] & 0x7f)) << 16) | ((uint32_t)(u8[1]) << 8) | u8[2];
736}
737
738static inline void _ccv_icf_1_uint1_1_uint23_to_3_uint8(uint8_t u1, uint32_t u23, uint8_t* u8)
739{
740 u8[0] = ((u1 << 7) | (u23 >> 16)) & 0xff;
741 u8[1] = (u23 >> 8) & 0xff;
742 u8[2] = u23 & 0xff;
743}
744
745static float _ccv_icf_run_feature_on_example(ccv_icf_feature_t* feature, ccv_dense_matrix_t* a)
746{
747 ccv_dense_matrix_t* icf = 0;
748 // we have 1px padding around the image
749 ccv_icf(a, &icf, 0);
750 ccv_dense_matrix_t* sat = 0;
751 ccv_sat(icf, &sat, 0, CCV_PADDING_ZERO);
752 ccv_matrix_free(icf);
753 float* ptr = sat->data.f32;
754 int ch = CCV_GET_CHANNEL(sat->type)((sat->type) & 0xFFF);
755 float c = _ccv_icf_run_feature(feature, ptr, sat->cols, ch, 1, 1);
756 ccv_matrix_free(sat);
757 return c;
758}
759
760static uint8_t* _ccv_icf_precompute_features(ccv_icf_feature_t* features, int feature_size, ccv_array_t* positives, ccv_array_t* negatives)
761{
762 int i, j;
763 // we use 3 bytes to represent the sorted index, and compute feature result (float) on fly
764 size_t step = (3 * (positives->rnum + negatives->rnum) + 3) & -4;
765 uint8_t* precomputed = (uint8_t*)ccmallocmalloc(sizeof(uint8_t) * feature_size * step);
766 ccv_icf_value_index_t* sortkv = (ccv_icf_value_index_t*)ccmallocmalloc(sizeof(ccv_icf_value_index_t) * (positives->rnum + negatives->rnum));
767 PRINT(CCV_CLI_INFO, " - precompute features using %uM memory temporarily\n", (uint32_t)((sizeof(float) * (positives->rnum + negatives->rnum) * feature_size + sizeof(uint8_t) * feature_size * step) / (1024 * 1024)))do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - precompute features using %uM memory temporarily\n", (uint32_t
)((sizeof(float) * (positives->rnum + negatives->rnum) *
feature_size + sizeof(uint8_t) * feature_size * step) / (1024
* 1024))); fflush(stdout); } } while (0)
;
768 float* featval = (float*)ccmallocmalloc(sizeof(float) * feature_size * (positives->rnum + negatives->rnum));
769 ccv_disable_cache(); // clean up cache so we have enough space to run it
770#ifdef USE_DISPATCH1
771 dispatch_semaphore_t sema = dispatch_semaphore_create(1);
772 dispatch_apply(positives->rnum + negatives->rnum, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t i) {
773#else
774 for (i = 0; i < positives->rnum + negatives->rnum; i++)
775 {
776#endif
777#ifdef USE_DISPATCH1
778 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER(~0ull));
779#endif
780 if (i % 37 == 0 || i == positives->rnum + negatives->rnum - 1) // don't flush too fast
781 FLUSH(CCV_CLI_INFO, " - precompute %d features through %d%% (%d / %d) examples", feature_size, (int)(i + 1) * 100 / (positives->rnum + negatives->rnum), (int)i + 1, positives->rnum + negatives->rnum)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { for
(_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT;
_CCV_PRINT_LOOP++) printf("\b"); for (_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP
< _CCV_PRINT_COUNT; _CCV_PRINT_LOOP++) printf(" "); for (
_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT; _CCV_PRINT_LOOP
++) printf("\b"); _CCV_PRINT_COUNT = printf(" - precompute %d features through %d%% (%d / %d) examples"
, feature_size, (int)(i + 1) * 100 / (positives->rnum + negatives
->rnum), (int)i + 1, positives->rnum + negatives->rnum
); fflush(stdout); } } while (0)
;
782#ifdef USE_DISPATCH1
783 dispatch_semaphore_signal(sema);
784 int j;
785#endif
786 ccv_dense_matrix_t* a = (ccv_dense_matrix_t*)ccv_array_get(i < positives->rnum ? positives : negatives, i < positives->rnum ? i : i - positives->rnum)((void*)(((char*)((i < positives->rnum ? positives : negatives
)->data)) + (size_t)(i < positives->rnum ? positives
: negatives)->rsize * (size_t)(i < positives->rnum ?
i : i - positives->rnum)))
;
787 a->data.u8 = (unsigned char*)(a + 1); // re-host the pointer to the right place
788 ccv_dense_matrix_t* icf = 0;
789 // we have 1px padding around the image
790 ccv_icf(a, &icf, 0);
791 ccv_dense_matrix_t* sat = 0;
792 ccv_sat(icf, &sat, 0, CCV_PADDING_ZERO);
793 ccv_matrix_free(icf);
794 float* ptr = sat->data.f32;
795 int ch = CCV_GET_CHANNEL(sat->type)((sat->type) & 0xFFF);
796 for (j = 0; j < feature_size; j++)
797 {
798 ccv_icf_feature_t* feature = features + j;
799 float c = _ccv_icf_run_feature(feature, ptr, sat->cols, ch, 1, 1);
800 assert(isfinite(c))((void) sizeof (((sizeof ((c)) == sizeof (float) ? __finitef (
c) : sizeof ((c)) == sizeof (double) ? __finite (c) : __finitel
(c))) ? 1 : 0), __extension__ ({ if ((sizeof ((c)) == sizeof
(float) ? __finitef (c) : sizeof ((c)) == sizeof (double) ? __finite
(c) : __finitel (c))) ; else __assert_fail ("isfinite(c)", "ccv_icf.c"
, 800, __extension__ __PRETTY_FUNCTION__); }))
;
801 featval[(size_t)j * (positives->rnum + negatives->rnum) + i] = c;
802 }
803 ccv_matrix_free(sat);
804#ifdef USE_DISPATCH1
805 });
806 dispatch_release(sema);
807#else
808 }
809#endif
810 PRINT(CCV_CLI_INFO, "\n")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("\n"); fflush(stdout); } } while (0)
;
811 uint8_t* computed = precomputed;
812 float* pfeatval = featval;
813 for (i = 0; i < feature_size; i++)
814 {
815 if (i % 37 == 0 || i == feature_size - 1) // don't flush too fast
816 FLUSH(CCV_CLI_INFO, " - precompute %d examples through %d%% (%d / %d) features", positives->rnum + negatives->rnum, (i + 1) * 100 / feature_size, i + 1, feature_size)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { for
(_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT;
_CCV_PRINT_LOOP++) printf("\b"); for (_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP
< _CCV_PRINT_COUNT; _CCV_PRINT_LOOP++) printf(" "); for (
_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT; _CCV_PRINT_LOOP
++) printf("\b"); _CCV_PRINT_COUNT = printf(" - precompute %d examples through %d%% (%d / %d) features"
, positives->rnum + negatives->rnum, (i + 1) * 100 / feature_size
, i + 1, feature_size); fflush(stdout); } } while (0)
;
817 for (j = 0; j < positives->rnum + negatives->rnum; j++)
818 sortkv[j].value = pfeatval[j], sortkv[j].index = j;
819 _ccv_icf_precomputed_ordering(sortkv, positives->rnum + negatives->rnum, 0);
820 // the first flag denotes if the subsequent one are equal to the previous one (if so, we have to skip both of them)
821 for (j = 0; j < positives->rnum + negatives->rnum - 1; j++)
822 _ccv_icf_1_uint1_1_uint23_to_3_uint8(sortkv[j].value == sortkv[j + 1].value, sortkv[j].index, computed + j * 3);
823 j = positives->rnum + negatives->rnum - 1;
824 _ccv_icf_1_uint1_1_uint23_to_3_uint8(0, sortkv[j].index, computed + j * 3);
825 computed += step;
826 pfeatval += positives->rnum + negatives->rnum;
827 }
828 ccfreefree(featval);
829 ccfreefree(sortkv);
830 PRINT(CCV_CLI_INFO, "\n - features are precomputed on examples and will occupy %uM memory\n", (uint32_t)((feature_size * step) / (1024 * 1024)))do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("\n - features are precomputed on examples and will occupy %uM memory\n"
, (uint32_t)((feature_size * step) / (1024 * 1024))); fflush(
stdout); } } while (0)
;
831 return precomputed;
832}
833
834typedef struct {
835 uint32_t pass;
836 double weigh[4];
837 int first_feature;
838 uint8_t* lut;
839} ccv_icf_decision_tree_cache_t;
840
841static inline float _ccv_icf_compute_threshold_between(ccv_icf_feature_t* feature, uint8_t* computed, ccv_array_t* positives, ccv_array_t* negatives, int index0, int index1)
842{
843 float c[2];
844 uint32_t b[2] = {
845 _ccv_icf_3_uint8_to_1_uint23(computed + index0 * 3),
846 _ccv_icf_3_uint8_to_1_uint23(computed + index1 * 3),
847 };
848 ccv_dense_matrix_t* a = (ccv_dense_matrix_t*)ccv_array_get(b[0] < positives->rnum ? positives : negatives, b[0] < positives->rnum ? b[0] : b[0] - positives->rnum)((void*)(((char*)((b[0] < positives->rnum ? positives :
negatives)->data)) + (size_t)(b[0] < positives->rnum
? positives : negatives)->rsize * (size_t)(b[0] < positives
->rnum ? b[0] : b[0] - positives->rnum)))
;
849 a->data.u8 = (unsigned char*)(a + 1); // re-host the pointer to the right place
850 c[0] = _ccv_icf_run_feature_on_example(feature, a);
851 a = (ccv_dense_matrix_t*)ccv_array_get(b[1] < positives->rnum ? positives : negatives, b[1] < positives->rnum ? b[1] : b[1] - positives->rnum)((void*)(((char*)((b[1] < positives->rnum ? positives :
negatives)->data)) + (size_t)(b[1] < positives->rnum
? positives : negatives)->rsize * (size_t)(b[1] < positives
->rnum ? b[1] : b[1] - positives->rnum)))
;
852 a->data.u8 = (unsigned char*)(a + 1); // re-host the pointer to the right place
853 c[1] = _ccv_icf_run_feature_on_example(feature, a);
854 return (c[0] + c[1]) * 0.5;
855}
856
857static inline void _ccv_icf_example_correct(ccv_icf_example_state_t* example_state, uint8_t* computed, uint8_t* lut, int leaf, ccv_array_t* positives, ccv_array_t* negatives, int start, int end)
858{
859 int i;
860 for (i = start; i <= end; i++)
861 {
862 uint32_t index = _ccv_icf_3_uint8_to_1_uint23(computed + i * 3);
863 if (!lut || lut[index] == leaf)
864 example_state[index].correct = (index < positives->rnum);
865 }
866}
867
868typedef struct {
869 int error_index;
870 double error_rate;
871 double weigh[2];
872 int count[2];
873} ccv_icf_first_feature_find_t;
874
875static ccv_icf_decision_tree_cache_t _ccv_icf_find_first_feature(ccv_icf_feature_t* features, int feature_size, ccv_array_t* positives, ccv_array_t* negatives, uint8_t* precomputed, ccv_icf_example_state_t* example_state, ccv_icf_feature_t* feature)
876{
877 int i;
878 assert(feature != 0)((void) sizeof ((feature != 0) ? 1 : 0), __extension__ ({ if (
feature != 0) ; else __assert_fail ("feature != 0", "ccv_icf.c"
, 878, __extension__ __PRETTY_FUNCTION__); }))
;
879 ccv_icf_decision_tree_cache_t intermediate_cache;
880 double aweigh0 = 0, aweigh1 = 0;
881 for (i = 0; i < positives->rnum; i++)
882 aweigh1 += example_state[i].weight, example_state[i].correct = 0; // assuming positive examples we get wrong
883 for (i = positives->rnum; i < positives->rnum + negatives->rnum; i++)
884 aweigh0 += example_state[i].weight, example_state[i].correct = 1; // assuming negative examples we get right
885 size_t step = (3 * (positives->rnum + negatives->rnum) + 3) & -4;
886 ccv_icf_first_feature_find_t* feature_find = (ccv_icf_first_feature_find_t*)ccmallocmalloc(sizeof(ccv_icf_first_feature_find_t) * feature_size);
887 parallel_for(i, feature_size){ int i; for ((i) = 0; (i) < (feature_size); (i)++) { {
888 ccv_icf_first_feature_find_t min_find = {
889 .error_rate = 1.0,
890 .error_index = 0,
891 .weigh = {0, 0},
892 .count = {0, 0},
893 };
894 double weigh[2] = {0, 0};
895 int count[2] = {0, 0};
896 int j;
897 uint8_t* computed = precomputed + step * i;
898 for (j = 0; j < positives->rnum + negatives->rnum; j++)
899 {
900 uint8_t skip;
901 uint32_t index;
902 _ccv_icf_3_uint8_to_1_uint1_1_uint23(computed + j * 3, &skip, &index);
903 conditional_assert(j == positives->rnum + negatives->rnum - 1, !skip)if ((j == positives->rnum + negatives->rnum - 1)) { ((void
) sizeof ((!skip) ? 1 : 0), __extension__ ({ if (!skip) ; else
__assert_fail ("!skip", "ccv_icf.c", 903, __extension__ __PRETTY_FUNCTION__
); })); }
;
904 assert(index >= 0 && index < positives->rnum + negatives->rnum)((void) sizeof ((index >= 0 && index < positives
->rnum + negatives->rnum) ? 1 : 0), __extension__ ({ if
(index >= 0 && index < positives->rnum + negatives
->rnum) ; else __assert_fail ("index >= 0 && index < positives->rnum + negatives->rnum"
, "ccv_icf.c", 904, __extension__ __PRETTY_FUNCTION__); }))
;
905 weigh[index < positives->rnum] += example_state[index].weight;
906 assert(example_state[index].weight > 0)((void) sizeof ((example_state[index].weight > 0) ? 1 : 0)
, __extension__ ({ if (example_state[index].weight > 0) ; else
__assert_fail ("example_state[index].weight > 0", "ccv_icf.c"
, 906, __extension__ __PRETTY_FUNCTION__); }))
;
907 assert(weigh[0] <= aweigh0 + 1e-10 && weigh[1] <= aweigh1 + 1e-10)((void) sizeof ((weigh[0] <= aweigh0 + 1e-10 && weigh
[1] <= aweigh1 + 1e-10) ? 1 : 0), __extension__ ({ if (weigh
[0] <= aweigh0 + 1e-10 && weigh[1] <= aweigh1 +
1e-10) ; else __assert_fail ("weigh[0] <= aweigh0 + 1e-10 && weigh[1] <= aweigh1 + 1e-10"
, "ccv_icf.c", 907, __extension__ __PRETTY_FUNCTION__); }))
;
908 ++count[index < positives->rnum];
909 if (skip) // the current index is equal to the next one, we cannot differentiate, therefore, skip
910 continue;
911 double error_rate = ccv_min(weigh[0] + aweigh1 - weigh[1], weigh[1] + aweigh0 - weigh[0])({ typeof (weigh[0] + aweigh1 - weigh[1]) _a = (weigh[0] + aweigh1
- weigh[1]); typeof (weigh[1] + aweigh0 - weigh[0]) _b = (weigh
[1] + aweigh0 - weigh[0]); (_a < _b) ? _a : _b; })
;
912 assert(error_rate > 0)((void) sizeof ((error_rate > 0) ? 1 : 0), __extension__ (
{ if (error_rate > 0) ; else __assert_fail ("error_rate > 0"
, "ccv_icf.c", 912, __extension__ __PRETTY_FUNCTION__); }))
;
913 if (error_rate < min_find.error_rate)
914 {
915 min_find.error_index = j;
916 min_find.error_rate = error_rate;
917 min_find.weigh[0] = weigh[0];
918 min_find.weigh[1] = weigh[1];
919 min_find.count[0] = count[0];
920 min_find.count[1] = count[1];
921 }
922 }
923 feature_find[i] = min_find;
924 } parallel_endfor} }
925 ccv_icf_first_feature_find_t best = {
926 .error_rate = 1.0,
927 .error_index = -1,
928 .weigh = {0, 0},
929 .count = {0, 0},
930 };
931 int feature_index = 0;
932 for (i = 0; i < feature_size; i++)
933 if (feature_find[i].error_rate < best.error_rate)
934 {
935 best = feature_find[i];
936 feature_index = i;
937 }
938 ccfreefree(feature_find);
939 *feature = features[feature_index];
940 uint8_t* computed = precomputed + step * feature_index;
941 intermediate_cache.lut = (uint8_t*)ccmallocmalloc(positives->rnum + negatives->rnum);
942 assert(best.error_index < positives->rnum + negatives->rnum - 1 && best.error_index >= 0)((void) sizeof ((best.error_index < positives->rnum + negatives
->rnum - 1 && best.error_index >= 0) ? 1 : 0), __extension__
({ if (best.error_index < positives->rnum + negatives->
rnum - 1 && best.error_index >= 0) ; else __assert_fail
("best.error_index < positives->rnum + negatives->rnum - 1 && best.error_index >= 0"
, "ccv_icf.c", 942, __extension__ __PRETTY_FUNCTION__); }))
;
943 if (best.weigh[0] + aweigh1 - best.weigh[1] < best.weigh[1] + aweigh0 - best.weigh[0])
944 {
945 for (i = 0; i < positives->rnum + negatives->rnum; i++)
946 intermediate_cache.lut[_ccv_icf_3_uint8_to_1_uint23(computed + i * 3)] = (i <= best.error_index);
947 feature->beta = _ccv_icf_compute_threshold_between(feature, computed, positives, negatives, best.error_index, best.error_index + 1);
948 // revert the sign of alpha, after threshold is computed
949 for (i = 0; i < feature->count; i++)
950 feature->alpha[i] = -feature->alpha[i];
951 intermediate_cache.weigh[0] = aweigh0 - best.weigh[0];
952 intermediate_cache.weigh[1] = aweigh1 - best.weigh[1];
953 intermediate_cache.weigh[2] = best.weigh[0];
954 intermediate_cache.weigh[3] = best.weigh[1];
955 intermediate_cache.pass = 3;
956 if (best.count[0] == 0)
957 intermediate_cache.pass &= 2; // only positive examples in the right, no need to build right leaf
958 if (best.count[1] == positives->rnum)
959 intermediate_cache.pass &= 1; // no positive examples in the left, no need to build left leaf
960 if (!(intermediate_cache.pass & 1)) // mark positives in the right as correct, if we don't have right leaf
961 _ccv_icf_example_correct(example_state, computed, 0, 0, positives, negatives, 0, best.error_index);
962 } else {
963 for (i = 0; i < positives->rnum + negatives->rnum; i++)
964 intermediate_cache.lut[_ccv_icf_3_uint8_to_1_uint23(computed + i * 3)] = (i > best.error_index);
965 feature->beta = -_ccv_icf_compute_threshold_between(feature, computed, positives, negatives, best.error_index, best.error_index + 1);
966 intermediate_cache.weigh[0] = best.weigh[0];
967 intermediate_cache.weigh[1] = best.weigh[1];
968 intermediate_cache.weigh[2] = aweigh0 - best.weigh[0];
969 intermediate_cache.weigh[3] = aweigh1 - best.weigh[1];
970 intermediate_cache.pass = 3;
971 if (best.count[0] == negatives->rnum)
972 intermediate_cache.pass &= 2; // only positive examples in the right, no need to build right leaf
973 if (best.count[1] == 0)
974 intermediate_cache.pass &= 1; // no positive examples in the left, no need to build left leaf
975 if (!(intermediate_cache.pass & 1)) // mark positives in the right as correct if we don't have right leaf
976 _ccv_icf_example_correct(example_state, computed, 0, 0, positives, negatives, best.error_index + 1, positives->rnum + negatives->rnum - 1);
977 }
978 intermediate_cache.first_feature = feature_index;
979 return intermediate_cache;
980}
981
982typedef struct {
983 int error_index;
984 double error_rate;
985 double weigh[2];
986} ccv_icf_second_feature_find_t;
987
988static double _ccv_icf_find_second_feature(ccv_icf_decision_tree_cache_t intermediate_cache, int leaf, ccv_icf_feature_t* features, int feature_size, ccv_array_t* positives, ccv_array_t* negatives, uint8_t* precomputed, ccv_icf_example_state_t* example_state, ccv_icf_feature_t* feature)
989{
990 size_t step = (3 * (positives->rnum + negatives->rnum) + 3) & -4;
991 uint8_t* lut = intermediate_cache.lut;
992 double* aweigh = intermediate_cache.weigh + leaf * 2;
993 ccv_icf_second_feature_find_t* feature_find = (ccv_icf_second_feature_find_t*)ccmallocmalloc(sizeof(ccv_icf_second_feature_find_t) * feature_size);
994 parallel_for(i, feature_size){ int i; for ((i) = 0; (i) < (feature_size); (i)++) { {
995 ccv_icf_second_feature_find_t min_find = {
996 .error_rate = 1.0,
997 .error_index = 0,
998 .weigh = {0, 0},
999 };
1000 double weigh[2] = {0, 0};
1001 uint8_t* computed = precomputed + step * i;
1002 int j, k;
1003 for (j = 0; j < positives->rnum + negatives->rnum; j++)
1004 {
1005 uint8_t skip;
1006 uint32_t index;
1007 _ccv_icf_3_uint8_to_1_uint1_1_uint23(computed + j * 3, &skip, &index);
1008 conditional_assert(j == positives->rnum + negatives->rnum - 1, !skip)if ((j == positives->rnum + negatives->rnum - 1)) { ((void
) sizeof ((!skip) ? 1 : 0), __extension__ ({ if (!skip) ; else
__assert_fail ("!skip", "ccv_icf.c", 1008, __extension__ __PRETTY_FUNCTION__
); })); }
;
1009 assert(index >= 0 && index < positives->rnum + negatives->rnum)((void) sizeof ((index >= 0 && index < positives
->rnum + negatives->rnum) ? 1 : 0), __extension__ ({ if
(index >= 0 && index < positives->rnum + negatives
->rnum) ; else __assert_fail ("index >= 0 && index < positives->rnum + negatives->rnum"
, "ccv_icf.c", 1009, __extension__ __PRETTY_FUNCTION__); }))
;
1010 // only care about part of the data
1011 if (lut[index] == leaf)
1012 {
1013 uint8_t leaf_skip = 0;
1014 for (k = j + 1; skip; k++)
1015 {
1016 uint32_t new_index;
1017 _ccv_icf_3_uint8_to_1_uint1_1_uint23(computed + j * 3, &skip, &new_index);
1018 // if the next equal one is the same leaf, we cannot distinguish them, skip
1019 if ((leaf_skip = (lut[new_index] == leaf)))
1020 break;
1021 conditional_assert(k == positives->rnum + negatives->rnum - 1, !skip)if ((k == positives->rnum + negatives->rnum - 1)) { ((void
) sizeof ((!skip) ? 1 : 0), __extension__ ({ if (!skip) ; else
__assert_fail ("!skip", "ccv_icf.c", 1021, __extension__ __PRETTY_FUNCTION__
); })); }
;
1022 }
1023 weigh[index < positives->rnum] += example_state[index].weight;
1024 if (leaf_skip)
1025 continue;
1026 assert(example_state[index].weight > 0)((void) sizeof ((example_state[index].weight > 0) ? 1 : 0)
, __extension__ ({ if (example_state[index].weight > 0) ; else
__assert_fail ("example_state[index].weight > 0", "ccv_icf.c"
, 1026, __extension__ __PRETTY_FUNCTION__); }))
;
1027 assert(weigh[0] <= aweigh[0] + 1e-10 && weigh[1] <= aweigh[1] + 1e-10)((void) sizeof ((weigh[0] <= aweigh[0] + 1e-10 && weigh
[1] <= aweigh[1] + 1e-10) ? 1 : 0), __extension__ ({ if (weigh
[0] <= aweigh[0] + 1e-10 && weigh[1] <= aweigh[
1] + 1e-10) ; else __assert_fail ("weigh[0] <= aweigh[0] + 1e-10 && weigh[1] <= aweigh[1] + 1e-10"
, "ccv_icf.c", 1027, __extension__ __PRETTY_FUNCTION__); }))
;
1028 double error_rate = ccv_min(weigh[0] + aweigh[1] - weigh[1], weigh[1] + aweigh[0] - weigh[0])({ typeof (weigh[0] + aweigh[1] - weigh[1]) _a = (weigh[0] + aweigh
[1] - weigh[1]); typeof (weigh[1] + aweigh[0] - weigh[0]) _b =
(weigh[1] + aweigh[0] - weigh[0]); (_a < _b) ? _a : _b; }
)
;
1029 if (error_rate < min_find.error_rate)
1030 {
1031 min_find.error_index = j;
1032 min_find.error_rate = error_rate;
1033 min_find.weigh[0] = weigh[0];
1034 min_find.weigh[1] = weigh[1];
1035 }
1036 }
1037 }
1038 feature_find[i] = min_find;
1039 } parallel_endfor} }
1040 ccv_icf_second_feature_find_t best = {
1041 .error_rate = 1.0,
1042 .error_index = -1,
1043 .weigh = {0, 0},
1044 };
1045 int i;
1046 int feature_index = 0;
1047 for (i = 0; i < feature_size; i++)
1048 if (feature_find[i].error_rate < best.error_rate)
1049 {
1050 best = feature_find[i];
1051 feature_index = i;
1052 }
1053 ccfreefree(feature_find);
1054 *feature = features[feature_index];
1055 uint8_t* computed = precomputed + step * feature_index;
1056 assert(best.error_index < positives->rnum + negatives->rnum - 1 && best.error_index >= 0)((void) sizeof ((best.error_index < positives->rnum + negatives
->rnum - 1 && best.error_index >= 0) ? 1 : 0), __extension__
({ if (best.error_index < positives->rnum + negatives->
rnum - 1 && best.error_index >= 0) ; else __assert_fail
("best.error_index < positives->rnum + negatives->rnum - 1 && best.error_index >= 0"
, "ccv_icf.c", 1056, __extension__ __PRETTY_FUNCTION__); }))
;
1057 if (best.weigh[0] + aweigh[1] - best.weigh[1] < best.weigh[1] + aweigh[0] - best.weigh[0])
1058 {
1059 feature->beta = _ccv_icf_compute_threshold_between(feature, computed, positives, negatives, best.error_index, best.error_index + 1);
1060 // revert the sign of alpha, after threshold is computed
1061 for (i = 0; i < feature->count; i++)
1062 feature->alpha[i] = -feature->alpha[i];
1063 // mark everything on the right properly
1064 _ccv_icf_example_correct(example_state, computed, lut, leaf, positives, negatives, 0, best.error_index);
1065 return best.weigh[1] + aweigh[0] - best.weigh[0];
1066 } else {
1067 feature->beta = -_ccv_icf_compute_threshold_between(feature, computed, positives, negatives, best.error_index, best.error_index + 1);
1068 // mark everything on the right properly
1069 _ccv_icf_example_correct(example_state, computed, lut, leaf, positives, negatives, best.error_index + 1, positives->rnum + negatives->rnum - 1);
1070 return best.weigh[0] + aweigh[1] - best.weigh[1];
1071 }
1072}
1073
1074static double _ccv_icf_find_best_weak_classifier(ccv_icf_feature_t* features, int feature_size, ccv_array_t* positives, ccv_array_t* negatives, uint8_t* precomputed, ccv_icf_example_state_t* example_state, ccv_icf_decision_tree_t* weak_classifier)
1075{
1076 // we are building the specific depth-2 decision tree
1077 ccv_icf_decision_tree_cache_t intermediate_cache = _ccv_icf_find_first_feature(features, feature_size, positives, negatives, precomputed, example_state, weak_classifier->features);
1078 // find the left feature
1079 // for the pass, 10 is the left branch, 01 is the right branch
1080 weak_classifier->pass = intermediate_cache.pass;
1081 double rate = 0;
1082 if (weak_classifier->pass & 0x2)
1083 rate += _ccv_icf_find_second_feature(intermediate_cache, 0, features, feature_size, positives, negatives, precomputed, example_state, weak_classifier->features + 1);
1084 else
1085 rate += intermediate_cache.weigh[0]; // the negative weights covered by first feature
1086 // find the right feature
1087 if (weak_classifier->pass & 0x1)
1088 rate += _ccv_icf_find_second_feature(intermediate_cache, 1, features, feature_size, positives, negatives, precomputed, example_state, weak_classifier->features + 2);
1089 else
1090 rate += intermediate_cache.weigh[3]; // the positive weights covered by first feature
1091 ccfreefree(intermediate_cache.lut);
1092 return rate;
1093}
1094
1095static ccv_array_t* _ccv_icf_collect_validates(gsl_rng* rng, ccv_size_t size, ccv_margin_t margin, ccv_array_t* validatefiles, int grayscale)
1096{
1097 ccv_array_t* validates = ccv_array_new(ccv_compute_dense_matrix_size(size.height + margin.top + margin.bottom + 2, size.width + margin.left + margin.right + 2, CCV_8U | (grayscale ? CCV_C1 : CCV_C3))(((sizeof(ccv_dense_matrix_t) + 15) & -16) + (((size.width
+ margin.left + margin.right + 2) * _ccv_get_data_type_size[
((CCV_8U | (grayscale ? CCV_C1 : CCV_C3)) & 0xFF000) >>
12] * ((CCV_8U | (grayscale ? CCV_C1 : CCV_C3)) & 0xFFF)
+ 3) & -4) * (size.height + margin.top + margin.bottom +
2))
, validatefiles->rnum, 0);
1098 int i;
1099 // collect tests
1100 for (i = 0; i < validatefiles->rnum; i++)
1101 {
1102 ccv_file_info_t* file_info = (ccv_file_info_t*)ccv_array_get(validatefiles, i)((void*)(((char*)((validatefiles)->data)) + (size_t)(validatefiles
)->rsize * (size_t)(i)))
;
1103 ccv_dense_matrix_t* image = 0;
1104 ccv_read(file_info->filename, &image, CCV_IO_ANY_FILE | (grayscale ? CCV_IO_GRAY : CCV_IO_RGB_COLOR))ccv_read_impl(file_info->filename, &image, CCV_IO_ANY_FILE
| (grayscale ? CCV_IO_GRAY : CCV_IO_RGB_COLOR), 0, 0, 0)
;
1105 if (image == 0)
1106 {
1107 PRINT(CCV_CLI_ERROR, "\n - %s: cannot be open, possibly corrupted\n", file_info->filename)do { if ((CCV_CLI_ERROR & ccv_cli_get_output_levels())) {
printf("\n - %s: cannot be open, possibly corrupted\n", file_info
->filename); fflush(stdout); } } while (0)
;
1108 continue;
1109 }
1110 ccv_dense_matrix_t* feature = _ccv_icf_capture_feature(rng, image, file_info->pose, size, margin, 0, 0, 0);
1111 feature->sig = 0;
1112 ccv_array_push(validates, feature);
1113 ccv_matrix_free(feature);
1114 ccv_matrix_free(image);
1115 }
1116 return validates;
1117}
1118
1119static ccv_array_t* _ccv_icf_collect_positives(gsl_rng* rng, ccv_size_t size, ccv_margin_t margin, ccv_array_t* posfiles, int posnum, float deform_angle, float deform_scale, float deform_shift, int grayscale)
1120{
1121 ccv_array_t* positives = ccv_array_new(ccv_compute_dense_matrix_size(size.height + margin.top + margin.bottom + 2, size.width + margin.left + margin.right + 2, CCV_8U | (grayscale ? CCV_C1 : CCV_C3))(((sizeof(ccv_dense_matrix_t) + 15) & -16) + (((size.width
+ margin.left + margin.right + 2) * _ccv_get_data_type_size[
((CCV_8U | (grayscale ? CCV_C1 : CCV_C3)) & 0xFF000) >>
12] * ((CCV_8U | (grayscale ? CCV_C1 : CCV_C3)) & 0xFFF)
+ 3) & -4) * (size.height + margin.top + margin.bottom +
2))
, posnum, 0);
1122 int i, j, q;
1123 // collect positives (with random deformation)
1124 for (i = 0; i < posnum;)
1125 {
1126 FLUSH(CCV_CLI_INFO, " - collect positives %d%% (%d / %d)", (i + 1) * 100 / posnum, i + 1, posnum)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { for
(_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT;
_CCV_PRINT_LOOP++) printf("\b"); for (_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP
< _CCV_PRINT_COUNT; _CCV_PRINT_LOOP++) printf(" "); for (
_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT; _CCV_PRINT_LOOP
++) printf("\b"); _CCV_PRINT_COUNT = printf(" - collect positives %d%% (%d / %d)"
, (i + 1) * 100 / posnum, i + 1, posnum); fflush(stdout); } }
while (0)
;
1127 double ratio = (double)(posnum - i) / posfiles->rnum;
1128 for (j = 0; j < posfiles->rnum && i < posnum; j++)
1129 {
1130 ccv_file_info_t* file_info = (ccv_file_info_t*)ccv_array_get(posfiles, j)((void*)(((char*)((posfiles)->data)) + (size_t)(posfiles)->
rsize * (size_t)(j)))
;
1131 ccv_dense_matrix_t* image = 0;
1132 ccv_read(file_info->filename, &image, CCV_IO_ANY_FILE | (grayscale ? CCV_IO_GRAY : CCV_IO_RGB_COLOR))ccv_read_impl(file_info->filename, &image, CCV_IO_ANY_FILE
| (grayscale ? CCV_IO_GRAY : CCV_IO_RGB_COLOR), 0, 0, 0)
;
1133 if (image == 0)
1134 {
1135 PRINT(CCV_CLI_ERROR, "\n - %s: cannot be open, possibly corrupted\n", file_info->filename)do { if ((CCV_CLI_ERROR & ccv_cli_get_output_levels())) {
printf("\n - %s: cannot be open, possibly corrupted\n", file_info
->filename); fflush(stdout); } } while (0)
;
1136 continue;
1137 }
1138 for (q = 0; q < ratio; q++)
1139 if (q < (int)ratio || gsl_rng_uniform(rng) <= ratio - (int)ratio)
1140 {
1141 FLUSH(CCV_CLI_INFO, " - collect positives %d%% (%d / %d)", (i + 1) * 100 / posnum, i + 1, posnum)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { for
(_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT;
_CCV_PRINT_LOOP++) printf("\b"); for (_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP
< _CCV_PRINT_COUNT; _CCV_PRINT_LOOP++) printf(" "); for (
_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT; _CCV_PRINT_LOOP
++) printf("\b"); _CCV_PRINT_COUNT = printf(" - collect positives %d%% (%d / %d)"
, (i + 1) * 100 / posnum, i + 1, posnum); fflush(stdout); } }
while (0)
;
1142 ccv_dense_matrix_t* feature = _ccv_icf_capture_feature(rng, image, file_info->pose, size, margin, deform_angle, deform_scale, deform_shift);
1143 feature->sig = 0;
1144 ccv_array_push(positives, feature);
1145 ccv_matrix_free(feature);
1146 ++i;
1147 if (i >= posnum)
1148 break;
1149 }
1150 ccv_matrix_free(image);
1151 }
1152 }
1153 PRINT(CCV_CLI_INFO, "\n")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("\n"); fflush(stdout); } } while (0)
;
1154 return positives;
1155}
1156
1157static uint64_t* _ccv_icf_precompute_classifier_cascade(ccv_icf_classifier_cascade_t* cascade, ccv_array_t* positives)
1158{
1159 int step = ((cascade->count - 1) >> 6) + 1;
1160 uint64_t* precomputed = (uint64_t*)ccmallocmalloc(sizeof(uint64_t) * positives->rnum * step);
18
Storing uninitialized value
1161 uint64_t* result = precomputed;
1162 int i, j;
1163 for (i = 0; i < positives->rnum; i++)
19
Assuming the condition is true
20
Loop condition is true. Entering loop body
1164 {
1165 ccv_dense_matrix_t* a = (ccv_dense_matrix_t*)(ccv_array_get(positives, i)((void*)(((char*)((positives)->data)) + (size_t)(positives
)->rsize * (size_t)(i)))
);
1166 a->data.u8 = (uint8_t*)(a + 1);
1167 ccv_dense_matrix_t* icf = 0;
1168 ccv_icf(a, &icf, 0);
1169 ccv_dense_matrix_t* sat = 0;
1170 ccv_sat(icf, &sat, 0, CCV_PADDING_ZERO);
1171 ccv_matrix_free(icf);
1172 float* ptr = sat->data.f32;
1173 int ch = CCV_GET_CHANNEL(sat->type)((sat->type) & 0xFFF);
1174 for (j = 0; j < cascade->count; j++)
21
Loop condition is true. Entering loop body
1175 if (_ccv_icf_run_weak_classifier(cascade->weak_classifiers + j, ptr, sat->cols, ch, 1, 1))
22
Taking false branch
1176 precomputed[j >> 6] |= (1UL << (j & 63));
1177 else
1178 precomputed[j >> 6] &= ~(1UL << (j & 63));
23
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage
1179 ccv_matrix_free(sat);
1180 precomputed += step;
1181 }
1182 return result;
1183}
1184
1185#define less_than(s1, s2, aux) ((s1) > (s2))
1186static CCV_IMPLEMENT_QSORT(_ccv_icf_threshold_rating, float, less_than)void _ccv_icf_threshold_rating(float *array, size_t total, int
aux) { int isort_thresh = 7; float t; int sp = 0; struct { float
*lb; float *ub; } stack[48]; if( total <= 1 ) return; stack
[0].lb = array; stack[0].ub = array + (total - 1); while( sp >=
0 ) { float* left = stack[sp].lb; float* right = stack[sp--]
.ub; for(;;) { int i, n = (int)(right - left) + 1, m; float* ptr
; float* ptr2; if( n <= isort_thresh ) { insert_sort: for(
ptr = left + 1; ptr <= right; ptr++ ) { for( ptr2 = ptr; ptr2
> left && less_than(ptr2[0],ptr2[-1], aux); ptr2--
) (((t)) = ((ptr2[0])), ((ptr2[0])) = ((ptr2[-1])), ((ptr2[-1
])) = ((t))); } break; } else { float* left0; float* left1; float
* right0; float* right1; float* pivot; float* a; float* b; float
* c; int swap_cnt = 0; left0 = left; right0 = right; pivot = left
+ (n/2); if( n > 40 ) { int d = n / 8; a = left, b = left
+ d, c = left + 2*d; left = less_than(*a, *b, aux) ? (less_than
(*b, *c, aux) ? b : (less_than(*a, *c, aux) ? c : a)) : (less_than
(*c, *b, aux) ? b : (less_than(*a, *c, aux) ? a : c)); a = pivot
- d, b = pivot, c = pivot + d; pivot = less_than(*a, *b, aux
) ? (less_than(*b, *c, aux) ? b : (less_than(*a, *c, aux) ? c
: a)) : (less_than(*c, *b, aux) ? b : (less_than(*a, *c, aux
) ? a : c)); a = right - 2*d, b = right - d, c = right; right
= less_than(*a, *b, aux) ? (less_than(*b, *c, aux) ? b : (less_than
(*a, *c, aux) ? c : a)) : (less_than(*c, *b, aux) ? b : (less_than
(*a, *c, aux) ? a : c)); } a = left, b = pivot, c = right; pivot
= less_than(*a, *b, aux) ? (less_than(*b, *c, aux) ? b : (less_than
(*a, *c, aux) ? c : a)) : (less_than(*c, *b, aux) ? b : (less_than
(*a, *c, aux) ? a : c)); if( pivot != left0 ) { (((t)) = ((*pivot
)), ((*pivot)) = ((*left0)), ((*left0)) = ((t))); pivot = left0
; } left = left1 = left0 + 1; right = right1 = right0; for(;;
) { while( left <= right && !less_than(*pivot, *left
, aux) ) { if( !less_than(*left, *pivot, aux) ) { if( left >
left1 ) (((t)) = ((*left1)), ((*left1)) = ((*left)), ((*left
)) = ((t))); swap_cnt = 1; left1++; } left++; } while( left <=
right && !less_than(*right, *pivot, aux) ) { if( !less_than
(*pivot, *right, aux) ) { if( right < right1 ) (((t)) = ((
*right1)), ((*right1)) = ((*right)), ((*right)) = ((t))); swap_cnt
= 1; right1--; } right--; } if( left > right ) break; (((
t)) = ((*left)), ((*left)) = ((*right)), ((*right)) = ((t)));
swap_cnt = 1; left++; right--; } if( swap_cnt == 0 ) { left =
left0, right = right0; goto insert_sort; } n = ({ typeof ((int
)(left1 - left0)) _a = ((int)(left1 - left0)); typeof ((int)(
left - left1)) _b = ((int)(left - left1)); (_a < _b) ? _a :
_b; }); for( i = 0; i < n; i++ ) (((t)) = ((left0[i])), (
(left0[i])) = ((left[i-n])), ((left[i-n])) = ((t))); n = ({ typeof
((int)(right0 - right1)) _a = ((int)(right0 - right1)); typeof
((int)(right1 - right)) _b = ((int)(right1 - right)); (_a <
_b) ? _a : _b; }); for( i = 0; i < n; i++ ) (((t)) = ((left
[i])), ((left[i])) = ((right0[i-n+1])), ((right0[i-n+1])) = (
(t))); n = (int)(left - left1); m = (int)(right1 - right); if
( n > 1 ) { if( m > 1 ) { if( n > m ) { stack[++sp].
lb = left0; stack[sp].ub = left0 + n - 1; left = right0 - m +
1, right = right0; } else { stack[++sp].lb = right0 - m + 1;
stack[sp].ub = right0; left = left0, right = left0 + n - 1; }
} else left = left0, right = left0 + n - 1; } else if( m >
1 ) left = right0 - m + 1, right = right0; else break; } } }
}
1187#undef less_than
1188
1189static void _ccv_icf_classifier_cascade_soft_with_validates(ccv_array_t* validates, ccv_icf_classifier_cascade_t* cascade, double min_accept)
1190{
1191 int i, j;
1192 int step = ((cascade->count - 1) >> 6) + 1;
1193 uint64_t* precomputed = _ccv_icf_precompute_classifier_cascade(cascade, validates);
17
Calling '_ccv_icf_precompute_classifier_cascade'
1194 float* positive_rate = (float*)ccmallocmalloc(sizeof(float) * validates->rnum);
1195 uint64_t* computed = precomputed;
1196 for (i = 0; i < validates->rnum; i++)
1197 {
1198 positive_rate[i] = 0;
1199 for (j = 0; j < cascade->count; j++)
1200 {
1201 uint64_t accept = computed[j >> 6] & (1UL << (j & 63));
1202 positive_rate[i] += cascade->weak_classifiers[j].weigh[!!accept];
1203 }
1204 computed += step;
1205 }
1206 _ccv_icf_threshold_rating(positive_rate, validates->rnum, 0);
1207 float threshold = positive_rate[ccv_min((int)(min_accept * (validates->rnum + 0.5) - 0.5), validates->rnum - 1)({ typeof ((int)(min_accept * (validates->rnum + 0.5) - 0.5
)) _a = ((int)(min_accept * (validates->rnum + 0.5) - 0.5)
); typeof (validates->rnum - 1) _b = (validates->rnum -
1); (_a < _b) ? _a : _b; })
];
1208 ccfreefree(positive_rate);
1209 computed = precomputed;
1210 // compute the final acceptance per validates / negatives with final threshold
1211 uint64_t* acceptance = (uint64_t*)cccalloccalloc(((validates->rnum - 1) >> 6) + 1, sizeof(uint64_t));
1212 int true_positives = 0;
1213 for (i = 0; i < validates->rnum; i++)
1214 {
1215 float rate = 0;
1216 for (j = 0; j < cascade->count; j++)
1217 {
1218 uint64_t accept = computed[j >> 6] & (1UL << (j & 63));
1219 rate += cascade->weak_classifiers[j].weigh[!!accept];
1220 }
1221 if (rate >= threshold)
1222 {
1223 acceptance[i >> 6] |= (1UL << (i & 63));
1224 ++true_positives;
1225 } else
1226 acceptance[i >> 6] &= ~(1UL << (i & 63));
1227 computed += step;
1228 }
1229 PRINT(CCV_CLI_INFO, " - at threshold %f, true positive rate: %f%%\n", threshold, (float)true_positives * 100 / validates->rnum)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - at threshold %f, true positive rate: %f%%\n", threshold,
(float)true_positives * 100 / validates->rnum); fflush(stdout
); } } while (0)
;
1230 float* rate = (float*)cccalloccalloc(validates->rnum, sizeof(float));
1231 for (j = 0; j < cascade->count; j++)
1232 {
1233 computed = precomputed;
1234 for (i = 0; i < validates->rnum; i++)
1235 {
1236 uint64_t correct = computed[j >> 6] & (1UL << (j & 63));
1237 rate[i] += cascade->weak_classifiers[j].weigh[!!correct];
1238 computed += step;
1239 }
1240 float threshold = FLT_MAX3.40282347e+38F;
1241 // find a threshold that keeps all accepted validates still acceptable
1242 for (i = 0; i < validates->rnum; i++)
1243 {
1244 uint64_t correct = acceptance[i >> 6] & (1UL << (i & 63));
1245 if (correct && rate[i] < threshold)
1246 threshold = rate[i];
1247 }
1248 cascade->weak_classifiers[j].threshold = threshold - 1e-10;
1249 }
1250 ccfreefree(rate);
1251 ccfreefree(acceptance);
1252 ccfreefree(precomputed);
1253}
1254
1255typedef struct {
1256 ccv_point_t point;
1257 float sum;
1258} ccv_point_with_sum_t;
1259
1260static void _ccv_icf_bootstrap_negatives(ccv_icf_classifier_cascade_t* cascade, ccv_array_t* negatives, gsl_rng* rng, ccv_array_t* bgfiles, int negnum, int grayscale, int spread, ccv_icf_param_t params)
1261{
1262#ifdef USE_DISPATCH1
1263 __block__attribute__((__blocks__(byref))) int i;
1264#else
1265 int i;
1266#endif
1267#ifdef USE_DISPATCH1
1268 __block__attribute__((__blocks__(byref))) int fppi = 0, is = 0;
1269#else
1270 int fppi = 0, is = 0;
1271#endif
1272 int t = 0;
1273 for (i = 0; i < negnum;)
1274 {
1275 double ratio = (double)(negnum - i) / bgfiles->rnum;
1276#ifdef USE_DISPATCH1
1277 dispatch_semaphore_t sem = dispatch_semaphore_create(1);
1278 dispatch_apply(bgfiles->rnum, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t j) {
1279#else
1280 size_t j;
1281 for (j = 0; j < bgfiles->rnum; j++)
1282 {
1283#endif
1284 int k, x, y, q, p;
1285 ccv_dense_matrix_t* a = (ccv_dense_matrix_t*)ccmallocmalloc(ccv_compute_dense_matrix_size(cascade->size.height + 2, cascade->size.width + 2, (grayscale ? CCV_C1 : CCV_C3) | CCV_8U)(((sizeof(ccv_dense_matrix_t) + 15) & -16) + (((cascade->
size.width + 2) * _ccv_get_data_type_size[(((grayscale ? CCV_C1
: CCV_C3) | CCV_8U) & 0xFF000) >> 12] * (((grayscale
? CCV_C1 : CCV_C3) | CCV_8U) & 0xFFF) + 3) & -4) * (
cascade->size.height + 2))
);
1286#ifdef USE_DISPATCH1
1287 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER(~0ull));
1288#endif
1289 if (i >= negnum || (spread && ratio < 1 && gsl_rng_uniform(rng) > ratio))
1290 {
1291 ccfreefree(a);
1292#ifdef USE_DISPATCH1
1293 dispatch_semaphore_signal(sem);
1294 return;
1295#else
1296 continue;
1297#endif
1298 }
1299 FLUSH(CCV_CLI_INFO, " - bootstrap negatives %d%% (%d / %d) [%u / %d] %s", (i + 1) * 100 / negnum, i + 1, negnum, (uint32_t)(j + 1), bgfiles->rnum, spread ? "" : "without statistic balancing")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { for
(_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT;
_CCV_PRINT_LOOP++) printf("\b"); for (_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP
< _CCV_PRINT_COUNT; _CCV_PRINT_LOOP++) printf(" "); for (
_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT; _CCV_PRINT_LOOP
++) printf("\b"); _CCV_PRINT_COUNT = printf(" - bootstrap negatives %d%% (%d / %d) [%u / %d] %s"
, (i + 1) * 100 / negnum, i + 1, negnum, (uint32_t)(j + 1), bgfiles
->rnum, spread ? "" : "without statistic balancing"); fflush
(stdout); } } while (0)
;
1300#ifdef USE_DISPATCH1
1301 gsl_rng* crng = gsl_rng_alloc(gsl_rng_default);
1302 gsl_rng_set(crng, gsl_rng_get(rng));
1303 dispatch_semaphore_signal(sem);
1304#else
1305 gsl_rng* crng = rng;
1306#endif
1307 ccv_file_info_t* file_info = (ccv_file_info_t*)ccv_array_get(bgfiles, j)((void*)(((char*)((bgfiles)->data)) + (size_t)(bgfiles)->
rsize * (size_t)(j)))
;
1308 ccv_dense_matrix_t* image = 0;
1309 ccv_read(file_info->filename, &image, CCV_IO_ANY_FILE | (grayscale ? CCV_IO_GRAY : CCV_IO_RGB_COLOR))ccv_read_impl(file_info->filename, &image, CCV_IO_ANY_FILE
| (grayscale ? CCV_IO_GRAY : CCV_IO_RGB_COLOR), 0, 0, 0)
;
1310 if (image == 0)
1311 {
1312 PRINT(CCV_CLI_ERROR, "\n - %s: cannot be open, possibly corrupted\n", file_info->filename)do { if ((CCV_CLI_ERROR & ccv_cli_get_output_levels())) {
printf("\n - %s: cannot be open, possibly corrupted\n", file_info
->filename); fflush(stdout); } } while (0)
;
1313 ccfreefree(a);
1314#ifdef USE_DISPATCH1
1315 gsl_rng_free(crng);
1316 return;
1317#else
1318 continue;
1319#endif
1320 }
1321 if (ccv_max(image->rows, image->cols)({ typeof (image->rows) _a = (image->rows); typeof (image
->cols) _b = (image->cols); (_a > _b) ? _a : _b; })
< 800 ||
1322 image->rows <= (cascade->size.height - cascade->margin.top - cascade->margin.bottom) ||
1323 image->cols <= (cascade->size.width - cascade->margin.left - cascade->margin.right)) // background is too small, blow it up to next scale
1324 {
1325 ccv_dense_matrix_t* blowup = 0;
1326 ccv_sample_up(image, &blowup, 0, 0, 0);
1327 ccv_matrix_free(image);
1328 image = blowup;
1329 }
1330 if (image->rows <= (cascade->size.height - cascade->margin.top - cascade->margin.bottom) ||
1331 image->cols <= (cascade->size.width - cascade->margin.left - cascade->margin.right)) // background is still too small, abort
1332 {
1333 ccv_matrix_free(image);
1334 ccfreefree(a);
1335#ifdef USE_DISPATCH1
1336 gsl_rng_free(crng);
1337 return;
1338#else
1339 continue;
1340#endif
1341 }
1342 double scale = pow(2., 1. / (params.interval + 1.));
1343 int next = params.interval + 1;
1344 int scale_upto = (int)(log(ccv_min((double)image->rows / (cascade->size.height - cascade->margin.top - cascade->margin.bottom), (double)image->cols / (cascade->size.width - cascade->margin.left - cascade->margin.right))({ typeof ((double)image->rows / (cascade->size.height -
cascade->margin.top - cascade->margin.bottom)) _a = ((
double)image->rows / (cascade->size.height - cascade->
margin.top - cascade->margin.bottom)); typeof ((double)image
->cols / (cascade->size.width - cascade->margin.left
- cascade->margin.right)) _b = ((double)image->cols / (
cascade->size.width - cascade->margin.left - cascade->
margin.right)); (_a < _b) ? _a : _b; })
) / log(scale) - DBL_MIN2.2250738585072014e-308) + 1;
1345 ccv_dense_matrix_t** pyr = (ccv_dense_matrix_t**)ccmallocmalloc(scale_upto * sizeof(ccv_dense_matrix_t*));
1346 memset(pyr, 0, scale_upto * sizeof(ccv_dense_matrix_t*));
1347#ifdef USE_DISPATCH1
1348 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER(~0ull));
1349#endif
1350 ++is; // how many images are scanned
1351#ifdef USE_DISPATCH1
1352 dispatch_semaphore_signal(sem);
1353#endif
1354 if (t % 2 != 0)
1355 ccv_flip(image, 0, 0, CCV_FLIP_X);
1356 if (t % 4 >= 2)
1357 ccv_flip(image, 0, 0, CCV_FLIP_Y);
1358 pyr[0] = image;
1359 for (q = 1; q < ccv_min(params.interval + 1, scale_upto)({ typeof (params.interval + 1) _a = (params.interval + 1); typeof
(scale_upto) _b = (scale_upto); (_a < _b) ? _a : _b; })
; q++)
1360 ccv_resample(pyr[0], &pyr[q], 0, (int)(pyr[0]->rows / pow(scale, q)), (int)(pyr[0]->cols / pow(scale, q)), CCV_INTER_AREA);
1361 for (q = next; q < scale_upto; q++)
1362 ccv_sample_down(pyr[q - next], &pyr[q], 0, 0, 0);
1363 for (q = 0; q < scale_upto; q++)
1364 {
1365#ifdef USE_DISPATCH1
1366 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER(~0ull));
1367#endif
1368 if (i >= negnum)
1369 {
1370#ifdef USE_DISPATCH1
1371 dispatch_semaphore_signal(sem);
1372#endif
1373 ccv_matrix_free(pyr[q]);
1374 continue;
1375 }
1376#ifdef USE_DISPATCH1
1377 dispatch_semaphore_signal(sem);
1378#endif
1379 ccv_dense_matrix_t* bordered = 0;
1380 ccv_border(pyr[q], (ccv_matrix_t**)&bordered, 0, cascade->margin);
1381 ccv_matrix_free(pyr[q]);
1382 ccv_dense_matrix_t* icf = 0;
1383 ccv_icf(bordered, &icf, 0);
1384 ccv_dense_matrix_t* sat = 0;
1385 ccv_sat(icf, &sat, 0, CCV_PADDING_ZERO);
1386 ccv_matrix_free(icf);
1387 assert(sat->rows == bordered->rows + 1 && sat->cols == bordered->cols + 1)((void) sizeof ((sat->rows == bordered->rows + 1 &&
sat->cols == bordered->cols + 1) ? 1 : 0), __extension__
({ if (sat->rows == bordered->rows + 1 && sat->
cols == bordered->cols + 1) ; else __assert_fail ("sat->rows == bordered->rows + 1 && sat->cols == bordered->cols + 1"
, "ccv_icf.c", 1387, __extension__ __PRETTY_FUNCTION__); }))
;
1388 int ch = CCV_GET_CHANNEL(sat->type)((sat->type) & 0xFFF);
1389 float* ptr = sat->data.f32 + sat->cols * ch;
1390 ccv_array_t* seq = ccv_array_new(sizeof(ccv_point_with_sum_t), 64, 0);
1391 for (y = 1; y < sat->rows - cascade->size.height - 2; y += params.step_through)
1392 {
1393 for (x = 1; x < sat->cols - cascade->size.width - 2; x += params.step_through)
1394 {
1395 int pass = 1;
1396 float sum = 0;
1397 for (p = 0; p < cascade->count; p++)
1398 {
1399 ccv_icf_decision_tree_t* weak_classifier = cascade->weak_classifiers + p;
1400 int c = _ccv_icf_run_weak_classifier(weak_classifier, ptr, sat->cols, ch, x, 0);
1401 sum += weak_classifier->weigh[c];
1402 if (sum < weak_classifier->threshold)
1403 {
1404 pass = 0;
1405 break;
1406 }
1407 }
1408 if (pass)
1409 {
1410 ccv_point_with_sum_t point;
1411 point.point = ccv_point(x - 1, y - 1);
1412 point.sum = sum;
1413 ccv_array_push(seq, &point);
1414 }
1415 }
1416 ptr += sat->cols * ch * params.step_through;
1417 }
1418 ccv_matrix_free(sat);
1419 // shuffle negatives so that we don't have too biased negatives
1420#ifdef USE_DISPATCH1
1421 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER(~0ull));
1422#endif
1423 fppi += seq->rnum; // how many detections we have in total
1424#ifdef USE_DISPATCH1
1425 dispatch_semaphore_signal(sem);
1426#endif
1427 if (seq->rnum > 0)
1428 {
1429 gsl_ran_shuffle(crng, ccv_array_get(seq, 0)((void*)(((char*)((seq)->data)) + (size_t)(seq)->rsize *
(size_t)(0)))
, seq->rnum, seq->rsize);
1430 /* so that we at least collect 10 from each scale */
1431 for (p = 0; p < (spread ? ccv_min(10, seq->rnum)({ typeof (10) _a = (10); typeof (seq->rnum) _b = (seq->
rnum); (_a < _b) ? _a : _b; })
: seq->rnum); p++) // collect enough negatives from this scale
1432 {
1433 a = ccv_dense_matrix_new(cascade->size.height + 2, cascade->size.width + 2, (grayscale ? CCV_C1 : CCV_C3) | CCV_8U, a, 0);
1434 ccv_point_with_sum_t* point = (ccv_point_with_sum_t*)ccv_array_get(seq, p)((void*)(((char*)((seq)->data)) + (size_t)(seq)->rsize *
(size_t)(p)))
;
1435 ccv_slice(bordered, (ccv_matrix_t**)&a, 0, point->point.y, point->point.x, a->rows, a->cols);
1436 assert(bordered->rows >= point->point.y + a->rows && bordered->cols >= point->point.x + a->cols)((void) sizeof ((bordered->rows >= point->point.y + a
->rows && bordered->cols >= point->point.
x + a->cols) ? 1 : 0), __extension__ ({ if (bordered->rows
>= point->point.y + a->rows && bordered->
cols >= point->point.x + a->cols) ; else __assert_fail
("bordered->rows >= point->point.y + a->rows && bordered->cols >= point->point.x + a->cols"
, "ccv_icf.c", 1436, __extension__ __PRETTY_FUNCTION__); }))
;
1437 a->sig = 0;
1438 // verify the data we sliced is worthy negative
1439 ccv_dense_matrix_t* icf = 0;
1440 ccv_icf(a, &icf, 0);
1441 ccv_dense_matrix_t* sat = 0;
1442 ccv_sat(icf, &sat, 0, CCV_PADDING_ZERO);
1443 ccv_matrix_free(icf);
1444 float* ptr = sat->data.f32;
1445 int ch = CCV_GET_CHANNEL(sat->type)((sat->type) & 0xFFF);
1446 int pass = 1;
1447 float sum = 0;
1448 for (k = 0; k < cascade->count; k++)
1449 {
1450 ccv_icf_decision_tree_t* weak_classifier = cascade->weak_classifiers + k;
1451 int c = _ccv_icf_run_weak_classifier(weak_classifier, ptr, sat->cols, ch, 1, 1);
1452 sum += weak_classifier->weigh[c];
1453 if (sum < weak_classifier->threshold)
1454 {
1455 pass = 0;
1456 break;
1457 }
1458 }
1459 ccv_matrix_free(sat);
1460 if (pass)
1461 {
1462#ifdef USE_DISPATCH1
1463 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER(~0ull));
1464#endif
1465 if (i < negnum)
1466 ccv_array_push(negatives, a);
1467 ++i;
1468 if (i >= negnum)
1469 {
1470#ifdef USE_DISPATCH1
1471 dispatch_semaphore_signal(sem);
1472#endif
1473 break;
1474 }
1475#ifdef USE_DISPATCH1
1476 dispatch_semaphore_signal(sem);
1477#endif
1478 }
1479 }
1480 }
1481 ccv_array_free(seq);
1482 ccv_matrix_free(bordered);
1483 }
1484 ccfreefree(pyr);
1485 ccfreefree(a);
1486#ifdef USE_DISPATCH1
1487 gsl_rng_free(crng);
1488 });
1489 dispatch_release(sem);
1490#else
1491 }
1492#endif
1493 if ((double)fppi / is <= (double)negnum / bgfiles->rnum) // if the targeted negative per image is bigger than our fppi, we don't prob anymore
1494 spread = 0;
1495 ++t;
1496 if (t > (spread ? 4 : 3) && !spread) // we've go over 4 or 3 transformations (original, flip x, flip y, flip x & y, [and original again]), and nothing we can do now
1497 break;
1498 }
1499 PRINT(CCV_CLI_INFO, "\n")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("\n"); fflush(stdout); } } while (0)
;
1500}
1501
1502static ccv_array_t* _ccv_icf_collect_negatives(gsl_rng* rng, ccv_size_t size, ccv_margin_t margin, ccv_array_t* bgfiles, int negnum, float deform_angle, float deform_scale, float deform_shift, int grayscale)
1503{
1504 ccv_array_t* negatives = ccv_array_new(ccv_compute_dense_matrix_size(size.height + margin.top + margin.bottom + 2, size.width + margin.left + margin.right + 2, CCV_8U | (grayscale ? CCV_C1 : CCV_C3))(((sizeof(ccv_dense_matrix_t) + 15) & -16) + (((size.width
+ margin.left + margin.right + 2) * _ccv_get_data_type_size[
((CCV_8U | (grayscale ? CCV_C1 : CCV_C3)) & 0xFF000) >>
12] * ((CCV_8U | (grayscale ? CCV_C1 : CCV_C3)) & 0xFFF)
+ 3) & -4) * (size.height + margin.top + margin.bottom +
2))
, negnum, 0);
1505 int i, j, q;
1506 // randomly collect negatives (with random deformation)
1507 for (i = 0; i < negnum;)
1508 {
1509 FLUSH(CCV_CLI_INFO, " - collect negatives %d%% (%d / %d)", (i + 1) * 100 / negnum, i + 1, negnum)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { for
(_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT;
_CCV_PRINT_LOOP++) printf("\b"); for (_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP
< _CCV_PRINT_COUNT; _CCV_PRINT_LOOP++) printf(" "); for (
_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT; _CCV_PRINT_LOOP
++) printf("\b"); _CCV_PRINT_COUNT = printf(" - collect negatives %d%% (%d / %d)"
, (i + 1) * 100 / negnum, i + 1, negnum); fflush(stdout); } }
while (0)
;
1510 double ratio = (double)(negnum - i) / bgfiles->rnum;
1511 for (j = 0; j < bgfiles->rnum && i < negnum; j++)
1512 {
1513 ccv_file_info_t* file_info = (ccv_file_info_t*)ccv_array_get(bgfiles, j)((void*)(((char*)((bgfiles)->data)) + (size_t)(bgfiles)->
rsize * (size_t)(j)))
;
1514 ccv_dense_matrix_t* image = 0;
1515 ccv_read(file_info->filename, &image, CCV_IO_ANY_FILE | (grayscale ? CCV_IO_GRAY : CCV_IO_RGB_COLOR))ccv_read_impl(file_info->filename, &image, CCV_IO_ANY_FILE
| (grayscale ? CCV_IO_GRAY : CCV_IO_RGB_COLOR), 0, 0, 0)
;
1516 if (image == 0)
1517 {
1518 PRINT(CCV_CLI_ERROR, "\n - %s: cannot be open, possibly corrupted\n", file_info->filename)do { if ((CCV_CLI_ERROR & ccv_cli_get_output_levels())) {
printf("\n - %s: cannot be open, possibly corrupted\n", file_info
->filename); fflush(stdout); } } while (0)
;
1519 continue;
1520 }
1521 double max_scale_ratio = ccv_min((double)image->rows / size.height, (double)image->cols / size.width)({ typeof ((double)image->rows / size.height) _a = ((double
)image->rows / size.height); typeof ((double)image->cols
/ size.width) _b = ((double)image->cols / size.width); (_a
< _b) ? _a : _b; })
;
1522 if (max_scale_ratio <= 0.5) // too small to be interesting
1523 continue;
1524 for (q = 0; q < ratio; q++)
1525 if (q < (int)ratio || gsl_rng_uniform(rng) <= ratio - (int)ratio)
1526 {
1527 FLUSH(CCV_CLI_INFO, " - collect negatives %d%% (%d / %d)", (i + 1) * 100 / negnum, i + 1, negnum)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { for
(_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT;
_CCV_PRINT_LOOP++) printf("\b"); for (_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP
< _CCV_PRINT_COUNT; _CCV_PRINT_LOOP++) printf(" "); for (
_CCV_PRINT_LOOP = 0; _CCV_PRINT_LOOP < _CCV_PRINT_COUNT; _CCV_PRINT_LOOP
++) printf("\b"); _CCV_PRINT_COUNT = printf(" - collect negatives %d%% (%d / %d)"
, (i + 1) * 100 / negnum, i + 1, negnum); fflush(stdout); } }
while (0)
;
1528 ccv_decimal_pose_t pose;
1529 double scale_ratio = gsl_rng_uniform(rng) * (max_scale_ratio - 0.5) + 0.5;
1530 pose.a = size.width * 0.5 * scale_ratio;
1531 pose.b = size.height * 0.5 * scale_ratio;
1532 pose.x = gsl_rng_uniform_int(rng, ccv_max((int)(image->cols - pose.a * 2 + 1.5), 1)({ typeof ((int)(image->cols - pose.a * 2 + 1.5)) _a = ((int
)(image->cols - pose.a * 2 + 1.5)); typeof (1) _b = (1); (
_a > _b) ? _a : _b; })
) + pose.a;
1533 pose.y = gsl_rng_uniform_int(rng, ccv_max((int)(image->rows - pose.b * 2 + 1.5), 1)({ typeof ((int)(image->rows - pose.b * 2 + 1.5)) _a = ((int
)(image->rows - pose.b * 2 + 1.5)); typeof (1) _b = (1); (
_a > _b) ? _a : _b; })
) + pose.b;
1534 pose.roll = pose.pitch = pose.yaw = 0;
1535 ccv_dense_matrix_t* feature = _ccv_icf_capture_feature(rng, image, pose, size, margin, deform_angle, deform_scale, deform_shift);
1536 feature->sig = 0;
1537 ccv_array_push(negatives, feature);
1538 ccv_matrix_free(feature);
1539 ++i;
1540 if (i >= negnum)
1541 break;
1542 }
1543 ccv_matrix_free(image);
1544 }
1545 }
1546 PRINT(CCV_CLI_INFO, "\n")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("\n"); fflush(stdout); } } while (0)
;
1547 return negatives;
1548}
1549
1550#ifdef USE_SANITY_ASSERTION
1551static double _ccv_icf_rate_weak_classifier(ccv_icf_decision_tree_t* weak_classifier, ccv_array_t* positives, ccv_array_t* negatives, ccv_icf_example_state_t* example_state)
1552{
1553 int i;
1554 double rate = 0;
1555 for (i = 0; i < positives->rnum + negatives->rnum; i++)
1556 {
1557 ccv_dense_matrix_t* a = (ccv_dense_matrix_t*)ccv_array_get(i < positives->rnum ? positives : negatives, i < positives->rnum ? i : i - positives->rnum)((void*)(((char*)((i < positives->rnum ? positives : negatives
)->data)) + (size_t)(i < positives->rnum ? positives
: negatives)->rsize * (size_t)(i < positives->rnum ?
i : i - positives->rnum)))
;
1558 a->data.u8 = (uint8_t*)(a + 1); // re-host the pointer to the right place
1559 ccv_dense_matrix_t* icf = 0;
1560 // we have 1px padding around the image
1561 ccv_icf(a, &icf, 0);
1562 ccv_dense_matrix_t* sat = 0;
1563 ccv_sat(icf, &sat, 0, CCV_PADDING_ZERO);
1564 ccv_matrix_free(icf);
1565 float* ptr = sat->data.f32;
1566 int ch = CCV_GET_CHANNEL(sat->type)((sat->type) & 0xFFF);
1567 if (i < positives->rnum)
1568 {
1569 if (_ccv_icf_run_weak_classifier(weak_classifier, ptr, sat->cols, ch, 1, 1))
1570 {
1571 assert(example_state[i].correct)((void) sizeof ((example_state[i].correct) ? 1 : 0), __extension__
({ if (example_state[i].correct) ; else __assert_fail ("example_state[i].correct"
, "ccv_icf.c", 1571, __extension__ __PRETTY_FUNCTION__); }))
;
1572 rate += example_state[i].weight;
1573 } else {
1574 assert(!example_state[i].correct)((void) sizeof ((!example_state[i].correct) ? 1 : 0), __extension__
({ if (!example_state[i].correct) ; else __assert_fail ("!example_state[i].correct"
, "ccv_icf.c", 1574, __extension__ __PRETTY_FUNCTION__); }))
;
1575 }
1576 } else {
1577 if (!_ccv_icf_run_weak_classifier(weak_classifier, ptr, sat->cols, ch, 1, 1))
1578 {
1579 assert(example_state[i].correct)((void) sizeof ((example_state[i].correct) ? 1 : 0), __extension__
({ if (example_state[i].correct) ; else __assert_fail ("example_state[i].correct"
, "ccv_icf.c", 1579, __extension__ __PRETTY_FUNCTION__); }))
;
1580 rate += example_state[i].weight;
1581 } else {
1582 assert(!example_state[i].correct)((void) sizeof ((!example_state[i].correct) ? 1 : 0), __extension__
({ if (!example_state[i].correct) ; else __assert_fail ("!example_state[i].correct"
, "ccv_icf.c", 1582, __extension__ __PRETTY_FUNCTION__); }))
;
1583 }
1584 }
1585 ccv_matrix_free(sat);
1586 }
1587 return rate;
1588}
1589#endif
1590#endif
1591
1592ccv_icf_classifier_cascade_t* ccv_icf_classifier_cascade_new(ccv_array_t* posfiles, int posnum, ccv_array_t* bgfiles, int negnum, ccv_array_t* validatefiles, const char* dir, ccv_icf_new_param_t params)
1593{
1594#ifdef HAVE_GSL1
1595 _ccv_icf_check_params(params);
1596 assert(posfiles->rnum > 0)((void) sizeof ((posfiles->rnum > 0) ? 1 : 0), __extension__
({ if (posfiles->rnum > 0) ; else __assert_fail ("posfiles->rnum > 0"
, "ccv_icf.c", 1596, __extension__ __PRETTY_FUNCTION__); }))
;
1597 assert(bgfiles->rnum > 0)((void) sizeof ((bgfiles->rnum > 0) ? 1 : 0), __extension__
({ if (bgfiles->rnum > 0) ; else __assert_fail ("bgfiles->rnum > 0"
, "ccv_icf.c", 1597, __extension__ __PRETTY_FUNCTION__); }))
;
1598 assert(posnum > 0 && negnum > 0)((void) sizeof ((posnum > 0 && negnum > 0) ? 1 :
0), __extension__ ({ if (posnum > 0 && negnum >
0) ; else __assert_fail ("posnum > 0 && negnum > 0"
, "ccv_icf.c", 1598, __extension__ __PRETTY_FUNCTION__); }))
;
1599 PRINT(CCV_CLI_INFO, "with %d positive examples and %d negative examples\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("with %d positive examples and %d negative examples\n" "positive examples are going to be collected from %d positive images\n"
"negative examples are are going to be collected from %d background images\n"
, posnum, negnum, posfiles->rnum, bgfiles->rnum); fflush
(stdout); } } while (0)
1600 "positive examples are going to be collected from %d positive images\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("with %d positive examples and %d negative examples\n" "positive examples are going to be collected from %d positive images\n"
"negative examples are are going to be collected from %d background images\n"
, posnum, negnum, posfiles->rnum, bgfiles->rnum); fflush
(stdout); } } while (0)
1601 "negative examples are are going to be collected from %d background images\n",do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("with %d positive examples and %d negative examples\n" "positive examples are going to be collected from %d positive images\n"
"negative examples are are going to be collected from %d background images\n"
, posnum, negnum, posfiles->rnum, bgfiles->rnum); fflush
(stdout); } } while (0)
1602 posnum, negnum, posfiles->rnum, bgfiles->rnum)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("with %d positive examples and %d negative examples\n" "positive examples are going to be collected from %d positive images\n"
"negative examples are are going to be collected from %d background images\n"
, posnum, negnum, posfiles->rnum, bgfiles->rnum); fflush
(stdout); } } while (0)
;
1603 PRINT(CCV_CLI_INFO, "use color? %s\n", params.grayscale ? "no" : "yes")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("use color? %s\n", params.grayscale ? "no" : "yes"); fflush(
stdout); } } while (0)
;
1604 PRINT(CCV_CLI_INFO, "feature pool size : %d\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1605 "weak classifier count : %d\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1606 "soft cascade acceptance : %lf\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1607 "minimum dimension of ICF feature : %d\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1608 "number of bootstrap : %d\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1609 "distortion on translation : %f\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1610 "distortion on rotation : %f\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1611 "distortion on scale : %f\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1612 "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1613 "------------------------\n",do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
1614 params.feature_size, params.weak_classifier, params.acceptance, params.min_dimension, params.bootstrap, params.deform_shift, params.deform_angle, params.deform_scale, params.size.width, params.size.height, params.margin.left, params.margin.top, params.margin.right, params.margin.bottom)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("feature pool size : %d\n" "weak classifier count : %d\n" "soft cascade acceptance : %lf\n"
"minimum dimension of ICF feature : %d\n" "number of bootstrap : %d\n"
"distortion on translation : %f\n" "distortion on rotation : %f\n"
"distortion on scale : %f\n" "learn ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", params.feature_size, params.weak_classifier
, params.acceptance, params.min_dimension, params.bootstrap, params
.deform_shift, params.deform_angle, params.deform_scale, params
.size.width, params.size.height, params.margin.left, params.margin
.top, params.margin.right, params.margin.bottom); fflush(stdout
); } } while (0)
;
1615 gsl_rng_env_setup();
1616 gsl_rng* rng = gsl_rng_alloc(gsl_rng_default);
1617 // we will keep all states inside this structure for easier save / resume across process
1618 // this should work better than ad-hoc one we used in DPM / BBF implementation
1619 ccv_icf_classifier_cascade_state_t z;
1620 z.params = params;
1621 ccv_function_state_begin(_ccv_icf_read_classifier_cascade_state, z, dir)(_ccv_icf_read_classifier_cascade_state)((dir), &(z)); switch
((z).line_no) { case 0:;
;
1622 z.classifier->grayscale = params.grayscale;
1623 z.size = params.size;
1624 z.margin = params.margin;
1625 z.classifier->size = ccv_size(z.size.width + z.margin.left + z.margin.right, z.size.height + z.margin.top + z.margin.bottom);
1626 z.features = (ccv_icf_feature_t*)ccmallocmalloc(sizeof(ccv_icf_feature_t) * params.feature_size);
1627 // generate random features
1628 for (z.i = 0; z.i < params.feature_size; z.i++)
1629 _ccv_icf_randomize_feature(rng, z.classifier->size, params.min_dimension, z.features + z.i, params.grayscale);
1630 z.x.features = 0;
1631 ccv_function_state_resume(_ccv_icf_write_classifier_cascade_state, z, dir)do { (z).line_no = 1631; (_ccv_icf_write_classifier_cascade_state
)(&(z), (dir)); case 1631:; } while (0)
;
1632 z.positives = _ccv_icf_collect_positives(rng, z.size, z.margin, posfiles, posnum, params.deform_angle, params.deform_scale, params.deform_shift, params.grayscale);
1633 z.x.positives = 0;
1634 ccv_function_state_resume(_ccv_icf_write_classifier_cascade_state, z, dir)do { (z).line_no = 1634; (_ccv_icf_write_classifier_cascade_state
)(&(z), (dir)); case 1634:; } while (0)
;
1635 z.negatives = _ccv_icf_collect_negatives(rng, z.size, z.margin, bgfiles, negnum, params.deform_angle, params.deform_scale, params.deform_shift, params.grayscale);
1636 z.x.negatives = 0;
1637 ccv_function_state_resume(_ccv_icf_write_classifier_cascade_state, z, dir)do { (z).line_no = 1637; (_ccv_icf_write_classifier_cascade_state
)(&(z), (dir)); case 1637:; } while (0)
;
1638 for (z.bootstrap = 0; z.bootstrap <= params.bootstrap; z.bootstrap++)
1639 {
1640 z.example_state = (ccv_icf_example_state_t*)ccmallocmalloc(sizeof(ccv_icf_example_state_t) * (z.negatives->rnum + z.positives->rnum));
1641 memset(z.example_state, 0, sizeof(ccv_icf_example_state_t) * (z.negatives->rnum + z.positives->rnum));
1642 for (z.i = 0; z.i < z.positives->rnum + z.negatives->rnum; z.i++)
1643 z.example_state[z.i].weight = (z.i < z.positives->rnum) ? 0.5 / z.positives->rnum : 0.5 / z.negatives->rnum;
1644 z.x.example_state = 0;
1645 ccv_function_state_resume(_ccv_icf_write_classifier_cascade_state, z, dir)do { (z).line_no = 1645; (_ccv_icf_write_classifier_cascade_state
)(&(z), (dir)); case 1645:; } while (0)
;
1646 z.precomputed = _ccv_icf_precompute_features(z.features, params.feature_size, z.positives, z.negatives);
1647 z.x.precomputed = 0;
1648 ccv_function_state_resume(_ccv_icf_write_classifier_cascade_state, z, dir)do { (z).line_no = 1648; (_ccv_icf_write_classifier_cascade_state
)(&(z), (dir)); case 1648:; } while (0)
;
1649 for (z.i = 0; z.i < params.weak_classifier; z.i++)
1650 {
1651 z.classifier->count = z.i + 1;
1652 PRINT(CCV_CLI_INFO, " - boost weak classifier %d of %d\n", z.i + 1, params.weak_classifier)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - boost weak classifier %d of %d\n", z.i + 1, params.weak_classifier
); fflush(stdout); } } while (0)
;
1653 int j;
1654 ccv_icf_decision_tree_t weak_classifier;
1655 double rate = _ccv_icf_find_best_weak_classifier(z.features, params.feature_size, z.positives, z.negatives, z.precomputed, z.example_state, &weak_classifier);
1656 assert(rate > 0.5)((void) sizeof ((rate > 0.5) ? 1 : 0), __extension__ ({ if
(rate > 0.5) ; else __assert_fail ("rate > 0.5", "ccv_icf.c"
, 1656, __extension__ __PRETTY_FUNCTION__); }))
; // it has to be better than random chance
1657#ifdef USE_SANITY_ASSERTION
1658 double confirm_rate = _ccv_icf_rate_weak_classifier(&weak_classifier, z.positives, z.negatives, z.example_state);
1659#endif
1660 double alpha = sqrt((1 - rate) / rate);
1661 double beta = 1.0 / alpha;
1662 double c = log(rate / (1 - rate));
1663 weak_classifier.weigh[0] = -c;
1664 weak_classifier.weigh[1] = c;
1665 weak_classifier.threshold = 0;
1666 double reweigh = 0;
1667 for (j = 0; j < z.positives->rnum + z.negatives->rnum; j++)
1668 {
1669 z.example_state[j].weight *= (z.example_state[j].correct) ? alpha : beta;
1670 z.example_state[j].rate += weak_classifier.weigh[!((j < z.positives->rnum) ^ z.example_state[j].correct)];
1671 reweigh += z.example_state[j].weight;
1672 }
1673 reweigh = 1.0 / reweigh;
1674#ifdef USE_SANITY_ASSERTION
1675 PRINT(CCV_CLI_INFO, " - on all examples, best feature at rate %lf, confirm rate %lf\n", rate, confirm_rate)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - on all examples, best feature at rate %lf, confirm rate %lf\n"
, rate, confirm_rate); fflush(stdout); } } while (0)
;
1676#else
1677 PRINT(CCV_CLI_INFO, " - on all examples, best feature at rate %lf\n", rate)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - on all examples, best feature at rate %lf\n", rate); fflush
(stdout); } } while (0)
;
1678#endif
1679 // balancing the weight to sum 1.0
1680 for (j = 0; j < z.positives->rnum + z.negatives->rnum; j++)
1681 z.example_state[j].weight *= reweigh;
1682 z.classifier->weak_classifiers[z.i] = weak_classifier;
1683 // compute the threshold at given acceptance
1684 float threshold = z.example_state[0].rate;
1685 for (j = 1; j < z.positives->rnum; j++)
1686 if (z.example_state[j].rate < threshold)
1687 threshold = z.example_state[j].rate;
1688 int true_positives = 0, false_positives = 0;
1689 for (j = 0; j < z.positives->rnum; j++)
1690 if (z.example_state[j].rate >= threshold)
1691 ++true_positives;
1692 for (j = z.positives->rnum; j < z.positives->rnum + z.negatives->rnum; j++)
1693 if (z.example_state[j].rate >= threshold)
1694 ++false_positives;
1695 PRINT(CCV_CLI_INFO, " - at threshold %f, true positive rate: %f%%, false positive rate: %f%% (%d)\n", threshold, (float)true_positives * 100 / z.positives->rnum, (float)false_positives * 100 / z.negatives->rnum, false_positives)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - at threshold %f, true positive rate: %f%%, false positive rate: %f%% (%d)\n"
, threshold, (float)true_positives * 100 / z.positives->rnum
, (float)false_positives * 100 / z.negatives->rnum, false_positives
); fflush(stdout); } } while (0)
;
1696 PRINT(CCV_CLI_INFO, " - first feature :\n")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - first feature :\n"); fflush(stdout); } } while (0)
;
1697 for (j = 0; j < weak_classifier.features[0].count; j++)
1698 PRINT(CCV_CLI_INFO, " - %d - (%d, %d) - (%d, %d)\n", weak_classifier.features[0].channel[j], weak_classifier.features[0].sat[j * 2].x, weak_classifier.features[0].sat[j * 2].y, weak_classifier.features[0].sat[j * 2 + 1].x, weak_classifier.features[0].sat[j * 2 + 1].y)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - %d - (%d, %d) - (%d, %d)\n", weak_classifier.features[0]
.channel[j], weak_classifier.features[0].sat[j * 2].x, weak_classifier
.features[0].sat[j * 2].y, weak_classifier.features[0].sat[j *
2 + 1].x, weak_classifier.features[0].sat[j * 2 + 1].y); fflush
(stdout); } } while (0)
;
1699 if (weak_classifier.pass & 0x2)
1700 {
1701 PRINT(CCV_CLI_INFO, " - second feature, on left :\n")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - second feature, on left :\n"); fflush(stdout); } } while
(0)
;
1702 for (j = 0; j < weak_classifier.features[1].count; j++)
1703 PRINT(CCV_CLI_INFO, " - | - %d - (%d, %d) - (%d, %d)\n", weak_classifier.features[1].channel[j], weak_classifier.features[1].sat[j * 2].x, weak_classifier.features[1].sat[j * 2].y, weak_classifier.features[1].sat[j * 2 + 1].x, weak_classifier.features[1].sat[j * 2 + 1].y)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - | - %d - (%d, %d) - (%d, %d)\n", weak_classifier.features
[1].channel[j], weak_classifier.features[1].sat[j * 2].x, weak_classifier
.features[1].sat[j * 2].y, weak_classifier.features[1].sat[j *
2 + 1].x, weak_classifier.features[1].sat[j * 2 + 1].y); fflush
(stdout); } } while (0)
;
1704 }
1705 if (weak_classifier.pass & 0x1)
1706 {
1707 PRINT(CCV_CLI_INFO, " - second feature, on right :\n")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - second feature, on right :\n"); fflush(stdout); } } while
(0)
;
1708 for (j = 0; j < weak_classifier.features[2].count; j++)
1709 PRINT(CCV_CLI_INFO, " - | - %d - (%d, %d) - (%d, %d)\n", weak_classifier.features[2].channel[j], weak_classifier.features[2].sat[j * 2].x, weak_classifier.features[2].sat[j * 2].y, weak_classifier.features[2].sat[j * 2 + 1].x, weak_classifier.features[2].sat[j * 2 + 1].y)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - | - %d - (%d, %d) - (%d, %d)\n", weak_classifier.features
[2].channel[j], weak_classifier.features[2].sat[j * 2].x, weak_classifier
.features[2].sat[j * 2].y, weak_classifier.features[2].sat[j *
2 + 1].x, weak_classifier.features[2].sat[j * 2 + 1].y); fflush
(stdout); } } while (0)
;
1710 }
1711 z.classifier->count = z.i + 1; // update count
1712 z.classifier->size = ccv_size(z.size.width + z.margin.left + z.margin.right, z.size.height + z.margin.top + z.margin.bottom);
1713 z.classifier->margin = z.margin;
1714 if (z.i + 1 < params.weak_classifier)
1715 {
1716 z.x.example_state = 0;
1717 z.x.classifier = 0;
1718 ccv_function_state_resume(_ccv_icf_write_classifier_cascade_state, z, dir)do { (z).line_no = 1718; (_ccv_icf_write_classifier_cascade_state
)(&(z), (dir)); case 1718:; } while (0)
;
1719 }
1720 }
1721 if (z.bootstrap < params.bootstrap) // collecting negatives, again
1722 {
1723 // free expensive memory
1724 ccfreefree(z.example_state);
1725 z.example_state = 0;
1726 ccfreefree(z.precomputed);
1727 z.precomputed = 0;
1728 _ccv_icf_classifier_cascade_soft_with_validates(z.positives, z.classifier, 1); // assuming perfect score, what's the soft cascading will be
1729 int exists = z.negatives->rnum;
1730 int spread_policy = z.bootstrap < 2; // we don't spread bootstrapping anymore after the first two bootstrappings
1731 // try to boostrap half negatives from perfect scoring
1732 _ccv_icf_bootstrap_negatives(z.classifier, z.negatives, rng, bgfiles, (negnum + 1) / 2, params.grayscale, spread_policy, params.detector);
1733 int leftover = negnum - (z.negatives->rnum - exists);
1734 if (leftover > 0)
1735 {
1736 // if we cannot get enough negative examples, now will use the validates data set to extract more
1737 ccv_array_t* validates = _ccv_icf_collect_validates(rng, z.size, z.margin, validatefiles, params.grayscale);
1738 _ccv_icf_classifier_cascade_soft_with_validates(validates, z.classifier, params.acceptance);
1739 ccv_array_free(validates);
1740 _ccv_icf_bootstrap_negatives(z.classifier, z.negatives, rng, bgfiles, leftover, params.grayscale, spread_policy, params.detector);
1741 }
1742 PRINT(CCV_CLI_INFO, " - after %d bootstrapping, learn with %d positives and %d negatives\n", z.bootstrap + 1, z.positives->rnum, z.negatives->rnum)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
(" - after %d bootstrapping, learn with %d positives and %d negatives\n"
, z.bootstrap + 1, z.positives->rnum, z.negatives->rnum
); fflush(stdout); } } while (0)
;
1743 z.classifier->count = 0; // reset everything
1744 z.x.negatives = 0;
1745 } else {
1746 z.x.example_state = 0;
1747 z.x.classifier = 0;
1748 ccv_function_state_resume(_ccv_icf_write_classifier_cascade_state, z, dir)do { (z).line_no = 1748; (_ccv_icf_write_classifier_cascade_state
)(&(z), (dir)); case 1748:; } while (0)
;
1749 }
1750 }
1751 if (z.precomputed)
1752 ccfreefree(z.precomputed);
1753 if (z.example_state)
1754 ccfreefree(z.example_state);
1755 ccfreefree(z.features);
1756 ccv_array_free(z.positives);
1757 ccv_array_free(z.negatives);
1758 gsl_rng_free(rng);
1759 ccv_function_state_finish()};
1760 return z.classifier;
1761#else
1762 assert(0 && "ccv_icf_classifier_cascade_new requires GSL library support")((void) sizeof ((0 && "ccv_icf_classifier_cascade_new requires GSL library support"
) ? 1 : 0), __extension__ ({ if (0 && "ccv_icf_classifier_cascade_new requires GSL library support"
) ; else __assert_fail ("0 && \"ccv_icf_classifier_cascade_new requires GSL library support\""
, "ccv_icf.c", 1762, __extension__ __PRETTY_FUNCTION__); }))
;
1763 return 0;
1764#endif
1765}
1766
1767void ccv_icf_classifier_cascade_soft(ccv_icf_classifier_cascade_t* cascade, ccv_array_t* posfiles, double acceptance)
1768{
1769#ifdef HAVE_GSL1
1770 PRINT(CCV_CLI_INFO, "with %d positive examples\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("with %d positive examples\n" "going to accept %.2lf%% positive examples\n"
, posfiles->rnum, acceptance * 100); fflush(stdout); } } while
(0)
1
Assuming the condition is false
2
Taking false branch
3
Loop condition is false. Exiting loop
1771 "going to accept %.2lf%% positive examples\n",do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("with %d positive examples\n" "going to accept %.2lf%% positive examples\n"
, posfiles->rnum, acceptance * 100); fflush(stdout); } } while
(0)
1772 posfiles->rnum, acceptance * 100)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("with %d positive examples\n" "going to accept %.2lf%% positive examples\n"
, posfiles->rnum, acceptance * 100); fflush(stdout); } } while
(0)
;
1773 ccv_size_t size = ccv_size(cascade->size.width - cascade->margin.left - cascade->margin.right, cascade->size.height - cascade->margin.top - cascade->margin.bottom);
1774 PRINT(CCV_CLI_INFO, "use color? %s\n", cascade->grayscale ? "no" : "yes")do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("use color? %s\n", cascade->grayscale ? "no" : "yes"); fflush
(stdout); } } while (0)
;
4
Assuming the condition is false
5
Taking false branch
6
Loop condition is false. Exiting loop
1775 PRINT(CCV_CLI_INFO, "compute soft cascading thresholds for ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("compute soft cascading thresholds for ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", size.width, size.height, cascade
->margin.left, cascade->margin.top, cascade->margin.
right, cascade->margin.bottom); fflush(stdout); } } while (
0)
7
Assuming the condition is false
8
Taking false branch
9
Loop condition is false. Exiting loop
1776 "------------------------\n",do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("compute soft cascading thresholds for ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", size.width, size.height, cascade
->margin.left, cascade->margin.top, cascade->margin.
right, cascade->margin.bottom); fflush(stdout); } } while (
0)
1777 size.width, size.height, cascade->margin.left, cascade->margin.top, cascade->margin.right, cascade->margin.bottom)do { if ((CCV_CLI_INFO & ccv_cli_get_output_levels())) { printf
("compute soft cascading thresholds for ICF classifier cascade at size %dx%d with margin (%d,%d,%d,%d)\n"
"------------------------\n", size.width, size.height, cascade
->margin.left, cascade->margin.top, cascade->margin.
right, cascade->margin.bottom); fflush(stdout); } } while (
0)
;
1778 gsl_rng_env_setup();
1779 gsl_rng* rng = gsl_rng_alloc(gsl_rng_default);
1780 /* collect positives */
1781 double weigh[2] = {
1782 0, 0
1783 };
1784 int i;
1785 for (i = 0; i < cascade->count; i++)
10
Assuming the condition is true
11
Loop condition is true. Entering loop body
12
Assuming the condition is false
13
Loop condition is false. Execution continues on line 1791
1786 {
1787 ccv_icf_decision_tree_t* weak_classifier = cascade->weak_classifiers + i;
1788 weigh[0] += weak_classifier->weigh[0];
1789 weigh[1] += weak_classifier->weigh[1];
1790 }
1791 weigh[0] = 1 / fabs(weigh[0]), weigh[1] = 1 / fabs(weigh[1]);
1792 for (i = 0; i < cascade->count; i++)
14
Loop condition is true. Entering loop body
15
Loop condition is false. Execution continues on line 1798
1793 {
1794 ccv_icf_decision_tree_t* weak_classifier = cascade->weak_classifiers + i;
1795 weak_classifier->weigh[0] = weak_classifier->weigh[0] * weigh[0];
1796 weak_classifier->weigh[1] = weak_classifier->weigh[1] * weigh[1];
1797 }
1798 ccv_array_t* validates = _ccv_icf_collect_validates(rng, size, cascade->margin, posfiles, cascade->grayscale);
1799 /* compute soft cascading thresholds */
1800 _ccv_icf_classifier_cascade_soft_with_validates(validates, cascade, acceptance);
16
Calling '_ccv_icf_classifier_cascade_soft_with_validates'
1801 ccv_array_free(validates);
1802 gsl_rng_free(rng);
1803#else
1804 assert(0 && "ccv_icf_classifier_cascade_soft requires GSL library support")((void) sizeof ((0 && "ccv_icf_classifier_cascade_soft requires GSL library support"
) ? 1 : 0), __extension__ ({ if (0 && "ccv_icf_classifier_cascade_soft requires GSL library support"
) ; else __assert_fail ("0 && \"ccv_icf_classifier_cascade_soft requires GSL library support\""
, "ccv_icf.c", 1804, __extension__ __PRETTY_FUNCTION__); }))
;
1805#endif
1806}
1807
1808static void _ccv_icf_read_classifier_cascade_with_fd(FILE* r, ccv_icf_classifier_cascade_t* cascade)
1809{
1810 cascade->type = CCV_ICF_CLASSIFIER_TYPE_A;
1811 fscanf(r, "%d %d %d %d", &cascade->count, &cascade->size.width, &cascade->size.height, &cascade->grayscale);
1812 fscanf(r, "%d %d %d %d", &cascade->margin.left, &cascade->margin.top, &cascade->margin.right, &cascade->margin.bottom);
1813 cascade->weak_classifiers = (ccv_icf_decision_tree_t*)ccmallocmalloc(sizeof(ccv_icf_decision_tree_t) * cascade->count);
1814 int i, q;
1815 for (i = 0; i < cascade->count; i++)
1816 {
1817 ccv_icf_decision_tree_t* weak_classifier = cascade->weak_classifiers + i;
1818 fscanf(r, "%u %a %a %a", &weak_classifier->pass, &weak_classifier->weigh[0], &weak_classifier->weigh[1], &weak_classifier->threshold);
1819 fscanf(r, "%d %a", &weak_classifier->features[0].count, &weak_classifier->features[0].beta);
1820 for (q = 0; q < weak_classifier->features[0].count; q++)
1821 fscanf(r, "%d %a %d %d %d %d", &weak_classifier->features[0].channel[q], &weak_classifier->features[0].alpha[q], &weak_classifier->features[0].sat[q * 2].x, &weak_classifier->features[0].sat[q * 2].y, &weak_classifier->features[0].sat[q * 2 + 1].x, &weak_classifier->features[0].sat[q * 2 + 1].y);
1822 if (weak_classifier->pass & 0x2)
1823 {
1824 fscanf(r, "%d %a", &weak_classifier->features[1].count, &weak_classifier->features[1].beta);
1825 for (q = 0; q < weak_classifier->features[1].count; q++)
1826 fscanf(r, "%d %a %d %d %d %d", &weak_classifier->features[1].channel[q], &weak_classifier->features[1].alpha[q], &weak_classifier->features[1].sat[q * 2].x, &weak_classifier->features[1].sat[q * 2].y, &weak_classifier->features[1].sat[q * 2 + 1].x, &weak_classifier->features[1].sat[q * 2 + 1].y);
1827 }
1828 if (weak_classifier->pass & 0x1)
1829 {
1830 fscanf(r, "%d %a", &weak_classifier->features[2].count, &weak_classifier->features[2].beta);
1831 for (q = 0; q < weak_classifier->features[2].count; q++)
1832 fscanf(r, "%d %a %d %d %d %d", &weak_classifier->features[2].channel[q], &weak_classifier->features[2].alpha[q], &weak_classifier->features[2].sat[q * 2].x, &weak_classifier->features[2].sat[q * 2].y, &weak_classifier->features[2].sat[q * 2 + 1].x, &weak_classifier->features[2].sat[q * 2 + 1].y);
1833 }
1834 }
1835}
1836
1837static void _ccv_icf_write_classifier_cascade_with_fd(ccv_icf_classifier_cascade_t* cascade, FILE* w)
1838{
1839 int i, q;
1840 fprintf(w, "%d %d %d %d\n", cascade->count, cascade->size.width, cascade->size.height, cascade->grayscale);
1841 fprintf(w, "%d %d %d %d\n", cascade->margin.left, cascade->margin.top, cascade->margin.right, cascade->margin.bottom);
1842 for (i = 0; i < cascade->count; i++)
1843 {
1844 ccv_icf_decision_tree_t* weak_classifier = cascade->weak_classifiers + i;
1845 fprintf(w, "%u %a %a %a\n", weak_classifier->pass, weak_classifier->weigh[0], weak_classifier->weigh[1], weak_classifier->threshold);
1846 fprintf(w, "%d %a\n", weak_classifier->features[0].count, weak_classifier->features[0].beta);
1847 for (q = 0; q < weak_classifier->features[0].count; q++)
1848 fprintf(w, "%d %a\n%d %d %d %d\n", weak_classifier->features[0].channel[q], weak_classifier->features[0].alpha[q], weak_classifier->features[0].sat[q * 2].x, weak_classifier->features[0].sat[q * 2].y, weak_classifier->features[0].sat[q * 2 + 1].x, weak_classifier->features[0].sat[q * 2 + 1].y);
1849 if (weak_classifier->pass & 0x2)
1850 {
1851 fprintf(w, "%d %a\n", weak_classifier->features[1].count, weak_classifier->features[1].beta);
1852 for (q = 0; q < weak_classifier->features[1].count; q++)
1853 fprintf(w, "%d %a\n%d %d %d %d\n", weak_classifier->features[1].channel[q], weak_classifier->features[1].alpha[q], weak_classifier->features[1].sat[q * 2].x, weak_classifier->features[1].sat[q * 2].y, weak_classifier->features[1].sat[q * 2 + 1].x, weak_classifier->features[1].sat[q * 2 + 1].y);
1854 }
1855 if (weak_classifier->pass & 0x1)
1856 {
1857 fprintf(w, "%d %a\n", weak_classifier->features[2].count, weak_classifier->features[2].beta);
1858 for (q = 0; q < weak_classifier->features[2].count; q++)
1859 fprintf(w, "%d %a\n%d %d %d %d\n", weak_classifier->features[2].channel[q], weak_classifier->features[2].alpha[q], weak_classifier->features[2].sat[q * 2].x, weak_classifier->features[2].sat[q * 2].y, weak_classifier->features[2].sat[q * 2 + 1].x, weak_classifier->features[2].sat[q * 2 + 1].y);
1860 }
1861 }
1862}
1863
1864ccv_icf_classifier_cascade_t* ccv_icf_read_classifier_cascade(const char* filename)
1865{
1866 FILE* r = fopen(filename, "r");
1867 ccv_icf_classifier_cascade_t* cascade = 0;
1868 if (r)
1869 {
1870 cascade = (ccv_icf_classifier_cascade_t*)ccmallocmalloc(sizeof(ccv_icf_classifier_cascade_t));
1871 _ccv_icf_read_classifier_cascade_with_fd(r, cascade);
1872 fclose(r);
1873 }
1874 return cascade;
1875}
1876
1877void ccv_icf_write_classifier_cascade(ccv_icf_classifier_cascade_t* cascade, const char* filename)
1878{
1879 FILE* w = fopen(filename, "w+");
1880 if (w)
1881 {
1882 _ccv_icf_write_classifier_cascade_with_fd(cascade, w);
1883 fclose(w);
1884 }
1885}
1886
1887void ccv_icf_classifier_cascade_free(ccv_icf_classifier_cascade_t* classifier)
1888{
1889 ccfreefree(classifier->weak_classifiers);
1890 ccfreefree(classifier);
1891}
1892
1893ccv_icf_multiscale_classifier_cascade_t* ccv_icf_read_multiscale_classifier_cascade(const char* directory)
1894{
1895 char filename[1024];
1896 snprintf(filename, 1024, "%s/multiscale", directory);
1897 FILE* r = fopen(filename, "r");
1898 if (r)
1899 {
1900 int octave = 0, count = 0, grayscale = 0;
1901 fscanf(r, "%d %d %d", &octave, &count, &grayscale);
1902 fclose(r);
1903 ccv_icf_multiscale_classifier_cascade_t* classifier = (ccv_icf_multiscale_classifier_cascade_t*)ccmallocmalloc(sizeof(ccv_icf_multiscale_classifier_cascade_t) + sizeof(ccv_icf_classifier_cascade_t) * count);
1904 classifier->type = CCV_ICF_CLASSIFIER_TYPE_B;
1905 classifier->octave = octave;
1906 classifier->count = count;
1907 classifier->grayscale = grayscale;
1908 classifier->cascade = (ccv_icf_classifier_cascade_t*)(classifier + 1);
1909 int i;
1910 for (i = 0; i < count; i++)
1911 {
1912 snprintf(filename, 1024, "%s/cascade-%d", directory, i + 1);
1913 r = fopen(filename, "r");
1914 if (r)
1915 {
1916 ccv_icf_classifier_cascade_t* cascade = classifier->cascade + i;
1917 _ccv_icf_read_classifier_cascade_with_fd(r, cascade);
1918 fclose(r);
1919 }
1920 }
1921 return classifier;
1922 }
1923 return 0;
1924}
1925
1926void ccv_icf_write_multiscale_classifier_cascade(ccv_icf_multiscale_classifier_cascade_t* classifier, const char* directory)
1927{
1928 char filename[1024];
1929 snprintf(filename, 1024, "%s/multiscale", directory);
1930 FILE* w = fopen(filename, "w+");
1931 fprintf(w, "%d %d %d\n", classifier->octave, classifier->count, classifier->grayscale);
1932 fclose(w);
1933 int i;
1934 for (i = 0; i < classifier->count; i++)
1935 {
1936 snprintf(filename, 1024, "%s/cascade-%d", directory, i + 1);
1937 w = fopen(filename, "w+");
1938 _ccv_icf_write_classifier_cascade_with_fd(classifier->cascade + i, w);
1939 fclose(w);
1940 }
1941}
1942
1943void ccv_icf_multiscale_classifier_cascade_free(ccv_icf_multiscale_classifier_cascade_t* classifier)
1944{
1945 int i;
1946 for (i = 0; i < classifier->count; i++)
1947 ccfreefree(classifier->cascade[i].weak_classifiers);
1948 ccfreefree(classifier);
1949}
1950
1951static int _ccv_is_equal_same_class(const void* _r1, const void* _r2, void* data)
1952{
1953 const ccv_comp_t* r1 = (const ccv_comp_t*)_r1;
1954 const ccv_comp_t* r2 = (const ccv_comp_t*)_r2;
1955 int distance = (int)(ccv_min(r1->rect.width, r1->rect.height)({ typeof (r1->rect.width) _a = (r1->rect.width); typeof
(r1->rect.height) _b = (r1->rect.height); (_a < _b)
? _a : _b; })
* 0.25 + 0.5);
1956
1957 return r2->classification.id == r1->classification.id &&
1958 r2->rect.x <= r1->rect.x + distance &&
1959 r2->rect.x >= r1->rect.x - distance &&
1960 r2->rect.y <= r1->rect.y + distance &&
1961 r2->rect.y >= r1->rect.y - distance &&
1962 r2->rect.width <= (int)(r1->rect.width * 1.5 + 0.5) &&
1963 (int)(r2->rect.width * 1.5 + 0.5) >= r1->rect.width &&
1964 r2->rect.height <= (int)(r1->rect.height * 1.5 + 0.5) &&
1965 (int)(r2->rect.height * 1.5 + 0.5) >= r1->rect.height;
1966}
1967
1968static void _ccv_icf_detect_objects_with_classifier_cascade(ccv_dense_matrix_t* a, ccv_icf_classifier_cascade_t** cascades, int count, ccv_icf_param_t params, ccv_array_t* seq[])
1969{
1970 int i, j, k, q, x, y;
1971 int scale_upto = 1;
1972 for (i = 0; i < count; i++)
1973 scale_upto = ccv_max(scale_upto, (int)(log(ccv_min((double)a->rows / (cascades[i]->size.height - cascades[i]->margin.top - cascades[i]->margin.bottom), (double)a->cols / (cascades[i]->size.width - cascades[i]->margin.left - cascades[i]->margin.right))) / log(2.) - DBL_MIN) + 1)({ typeof (scale_upto) _a = (scale_upto); typeof ((int)(log((
{ typeof ((double)a->rows / (cascades[i]->size.height -
cascades[i]->margin.top - cascades[i]->margin.bottom))
_a = ((double)a->rows / (cascades[i]->size.height - cascades
[i]->margin.top - cascades[i]->margin.bottom)); typeof (
(double)a->cols / (cascades[i]->size.width - cascades[i
]->margin.left - cascades[i]->margin.right)) _b = ((double
)a->cols / (cascades[i]->size.width - cascades[i]->margin
.left - cascades[i]->margin.right)); (_a < _b) ? _a : _b
; })) / log(2.) - 2.2250738585072014e-308) + 1) _b = ((int)(log
(({ typeof ((double)a->rows / (cascades[i]->size.height
- cascades[i]->margin.top - cascades[i]->margin.bottom
)) _a = ((double)a->rows / (cascades[i]->size.height - cascades
[i]->margin.top - cascades[i]->margin.bottom)); typeof (
(double)a->cols / (cascades[i]->size.width - cascades[i
]->margin.left - cascades[i]->margin.right)) _b = ((double
)a->cols / (cascades[i]->size.width - cascades[i]->margin
.left - cascades[i]->margin.right)); (_a < _b) ? _a : _b
; })) / log(2.) - 2.2250738585072014e-308) + 1); (_a > _b)
? _a : _b; })
;
1974 ccv_dense_matrix_t** pyr = (ccv_dense_matrix_t**)alloca(sizeof(ccv_dense_matrix_t*) * scale_upto)__builtin_alloca (sizeof(ccv_dense_matrix_t*) * scale_upto);
1975 pyr[0] = a;
1976 for (i = 1; i < scale_upto; i++)
1977 {
1978 pyr[i] = 0;
1979 ccv_sample_down(pyr[i - 1], &pyr[i], 0, 0, 0);
1980 }
1981 for (i = 0; i < scale_upto; i++)
1982 {
1983 // run it
1984 for (j = 0; j < count; j++)
1985 {
1986 double scale_ratio = pow(2., 1. / (params.interval + 1));
1987 double scale = 1;
1988 ccv_icf_classifier_cascade_t* cascade = cascades[j];
1989 for (k = 0; k <= params.interval; k++)
1990 {
1991 int rows = (int)(pyr[i]->rows / scale + 0.5);
1992 int cols = (int)(pyr[i]->cols / scale + 0.5);
1993 if (rows < cascade->size.height || cols < cascade->size.width)
1994 break;
1995 ccv_dense_matrix_t* image = k == 0 ? pyr[i] : 0;
1996 if (k > 0)
1997 ccv_resample(pyr[i], &image, 0, rows, cols, CCV_INTER_AREA);
1998 ccv_dense_matrix_t* bordered = 0;
1999 ccv_border(image, (ccv_matrix_t**)&bordered, 0, cascade->margin);
2000 if (k > 0)
2001 ccv_matrix_free(image);
2002 rows = bordered->rows;
2003 cols = bordered->cols;
2004 ccv_dense_matrix_t* icf = 0;
2005 ccv_icf(bordered, &icf, 0);
2006 ccv_matrix_free(bordered);
2007 ccv_dense_matrix_t* sat = 0;
2008 ccv_sat(icf, &sat, 0, CCV_PADDING_ZERO);
2009 ccv_matrix_free(icf);
2010 int ch = CCV_GET_CHANNEL(sat->type)((sat->type) & 0xFFF);
2011 float* ptr = sat->data.f32;
2012 for (y = 0; y < rows; y += params.step_through)
2013 {
2014 if (y >= sat->rows - cascade->size.height - 1)
2015 break;
2016 for (x = 0; x < cols; x += params.step_through)
2017 {
2018 if (x >= sat->cols - cascade->size.width - 1)
2019 break;
2020 int pass = 1;
2021 float sum = 0;
2022 for (q = 0; q < cascade->count; q++)
2023 {
2024 ccv_icf_decision_tree_t* weak_classifier = cascade->weak_classifiers + q;
2025 int c = _ccv_icf_run_weak_classifier(weak_classifier, ptr, sat->cols, ch, x, 0);
2026 sum += weak_classifier->weigh[c];
2027 if (sum < weak_classifier->threshold)
2028 {
2029 pass = 0;
2030 break;
2031 }
2032 }
2033 if (pass)
2034 {
2035 ccv_comp_t comp;
2036 comp.rect = ccv_rect((int)((x + 0.5) * scale * (1 << i) - 0.5), (int)((y + 0.5) * scale * (1 << i) - 0.5), (cascade->size.width - cascade->margin.left - cascade->margin.right) * scale * (1 << i), (cascade->size.height - cascade->margin.top - cascade->margin.bottom) * scale * (1 << i));
2037 comp.neighbors = 1;
2038 comp.classification.id = j + 1;
2039 comp.classification.confidence = sum;
2040 ccv_array_push(seq[j], &comp);
2041 }
2042 }
2043 ptr += sat->cols * ch * params.step_through;
2044 }
2045 ccv_matrix_free(sat);
2046 scale *= scale_ratio;
2047 }
2048 }
2049 }
2050
2051 for (i = 1; i < scale_upto; i++)
2052 ccv_matrix_free(pyr[i]);
2053}
2054
2055static void _ccv_icf_detect_objects_with_multiscale_classifier_cascade(ccv_dense_matrix_t* a, ccv_icf_multiscale_classifier_cascade_t** multiscale_cascade, int count, ccv_icf_param_t params, ccv_array_t* seq[])
2056{
2057 int i, j, k, q, x, y, ix, iy, py;
2058 assert(multiscale_cascade[0]->count % multiscale_cascade[0]->octave == 0)((void) sizeof ((multiscale_cascade[0]->count % multiscale_cascade
[0]->octave == 0) ? 1 : 0), __extension__ ({ if (multiscale_cascade
[0]->count % multiscale_cascade[0]->octave == 0) ; else
__assert_fail ("multiscale_cascade[0]->count % multiscale_cascade[0]->octave == 0"
, "ccv_icf.c", 2058, __extension__ __PRETTY_FUNCTION__); }))
;
2059 ccv_margin_t margin = multiscale_cascade[0]->cascade[multiscale_cascade[0]->count - 1].margin;
2060 for (i = 1; i < count; i++)
2061 {
2062 assert(multiscale_cascade[i]->count % multiscale_cascade[i]->octave == 0)((void) sizeof ((multiscale_cascade[i]->count % multiscale_cascade
[i]->octave == 0) ? 1 : 0), __extension__ ({ if (multiscale_cascade
[i]->count % multiscale_cascade[i]->octave == 0) ; else
__assert_fail ("multiscale_cascade[i]->count % multiscale_cascade[i]->octave == 0"
, "ccv_icf.c", 2062, __extension__ __PRETTY_FUNCTION__); }))
;
2063 assert(multiscale_cascade[i - 1]->grayscale == multiscale_cascade[i]->grayscale)((void) sizeof ((multiscale_cascade[i - 1]->grayscale == multiscale_cascade
[i]->grayscale) ? 1 : 0), __extension__ ({ if (multiscale_cascade
[i - 1]->grayscale == multiscale_cascade[i]->grayscale)
; else __assert_fail ("multiscale_cascade[i - 1]->grayscale == multiscale_cascade[i]->grayscale"
, "ccv_icf.c", 2063, __extension__ __PRETTY_FUNCTION__); }))
;
2064 assert(multiscale_cascade[i - 1]->count == multiscale_cascade[i]->count)((void) sizeof ((multiscale_cascade[i - 1]->count == multiscale_cascade
[i]->count) ? 1 : 0), __extension__ ({ if (multiscale_cascade
[i - 1]->count == multiscale_cascade[i]->count) ; else __assert_fail
("multiscale_cascade[i - 1]->count == multiscale_cascade[i]->count"
, "ccv_icf.c", 2064, __extension__ __PRETTY_FUNCTION__); }))
;
2065 assert(multiscale_cascade[i - 1]->octave == multiscale_cascade[i]->octave)((void) sizeof ((multiscale_cascade[i - 1]->octave == multiscale_cascade
[i]->octave) ? 1 : 0), __extension__ ({ if (multiscale_cascade
[i - 1]->octave == multiscale_cascade[i]->octave) ; else
__assert_fail ("multiscale_cascade[i - 1]->octave == multiscale_cascade[i]->octave"
, "ccv_icf.c", 2065, __extension__ __PRETTY_FUNCTION__); }))
;
2066 ccv_icf_classifier_cascade_t* cascade = multiscale_cascade[i]->cascade + multiscale_cascade[i]->count - 1;
2067 margin.top = ccv_max(margin.top, cascade->margin.top)({ typeof (margin.top) _a = (margin.top); typeof (cascade->
margin.top) _b = (cascade->margin.top); (_a > _b) ? _a :
_b; })
;
2068 margin.right = ccv_max(margin.right, cascade->margin.right)({ typeof (margin.right) _a = (margin.right); typeof (cascade
->margin.right) _b = (cascade->margin.right); (_a > _b
) ? _a : _b; })
;
2069 margin.bottom = ccv_max(margin.bottom, cascade->margin.bottom)({ typeof (margin.bottom) _a = (margin.bottom); typeof (cascade
->margin.bottom) _b = (cascade->margin.bottom); (_a >
_b) ? _a : _b; })
;
2070 margin.left = ccv_max(margin.left, cascade->margin.left)({ typeof (margin.left) _a = (margin.left); typeof (cascade->
margin.left) _b = (cascade->margin.left); (_a > _b) ? _a
: _b; })
;
2071 }
2072 int scale_upto = 1;
2073 for (i = 0; i < count; i++)
2074 scale_upto = ccv_max(scale_upto, (int)(log(ccv_min((double)a->rows / (multiscale_cascade[i]->cascade[0].size.height - multiscale_cascade[i]->cascade[0].margin.top - multiscale_cascade[i]->cascade[0].margin.bottom), (double)a->cols / (multiscale_cascade[i]->cascade[0].size.width - multiscale_cascade[i]->cascade[0].margin.left - multiscale_cascade[i]->cascade[0].margin.right))) / log(2.) - DBL_MIN) + 2 - multiscale_cascade[i]->octave)({ typeof (scale_upto) _a = (scale_upto); typeof ((int)(log((
{ typeof ((double)a->rows / (multiscale_cascade[i]->cascade
[0].size.height - multiscale_cascade[i]->cascade[0].margin
.top - multiscale_cascade[i]->cascade[0].margin.bottom)) _a
= ((double)a->rows / (multiscale_cascade[i]->cascade[0
].size.height - multiscale_cascade[i]->cascade[0].margin.top
- multiscale_cascade[i]->cascade[0].margin.bottom)); typeof
((double)a->cols / (multiscale_cascade[i]->cascade[0].
size.width - multiscale_cascade[i]->cascade[0].margin.left
- multiscale_cascade[i]->cascade[0].margin.right)) _b = (
(double)a->cols / (multiscale_cascade[i]->cascade[0].size
.width - multiscale_cascade[i]->cascade[0].margin.left - multiscale_cascade
[i]->cascade[0].margin.right)); (_a < _b) ? _a : _b; })
) / log(2.) - 2.2250738585072014e-308) + 2 - multiscale_cascade
[i]->octave) _b = ((int)(log(({ typeof ((double)a->rows
/ (multiscale_cascade[i]->cascade[0].size.height - multiscale_cascade
[i]->cascade[0].margin.top - multiscale_cascade[i]->cascade
[0].margin.bottom)) _a = ((double)a->rows / (multiscale_cascade
[i]->cascade[0].size.height - multiscale_cascade[i]->cascade
[0].margin.top - multiscale_cascade[i]->cascade[0].margin.
bottom)); typeof ((double)a->cols / (multiscale_cascade[i]
->cascade[0].size.width - multiscale_cascade[i]->cascade
[0].margin.left - multiscale_cascade[i]->cascade[0].margin
.right)) _b = ((double)a->cols / (multiscale_cascade[i]->
cascade[0].size.width - multiscale_cascade[i]->cascade[0].
margin.left - multiscale_cascade[i]->cascade[0].margin.right
)); (_a < _b) ? _a : _b; })) / log(2.) - 2.2250738585072014e-308
) + 2 - multiscale_cascade[i]->octave); (_a > _b) ? _a :
_b; })
;
2075 ccv_dense_matrix_t** pyr = (ccv_dense_matrix_t**)alloca(sizeof(ccv_dense_matrix_t*) * scale_upto)__builtin_alloca (sizeof(ccv_dense_matrix_t*) * scale_upto);
2076 pyr[0] = a;
2077 for (i = 1; i < scale_upto; i++)
2078 {
2079 pyr[i] = 0;
2080 ccv_sample_down(pyr[i - 1], &pyr[i], 0, 0, 0);
2081 }
2082 for (i = 0; i < scale_upto; i++)
2083 {
2084 ccv_dense_matrix_t* bordered = 0;
2085 ccv_border(pyr[i], (ccv_matrix_t**)&bordered, 0, margin);
2086 ccv_dense_matrix_t* icf = 0;
2087 ccv_icf(bordered, &icf, 0);
2088 ccv_matrix_free(bordered);
2089 ccv_dense_matrix_t* sat = 0;
2090 ccv_sat(icf, &sat, 0, CCV_PADDING_ZERO);
2091 ccv_matrix_free(icf);
2092 int ch = CCV_GET_CHANNEL(sat->type)((sat->type) & 0xFFF);
2093 assert(CCV_GET_DATA_TYPE(sat->type) == CCV_32F)((void) sizeof ((((sat->type) & 0xFF000) == CCV_32F) ?
1 : 0), __extension__ ({ if (((sat->type) & 0xFF000) ==
CCV_32F) ; else __assert_fail ("CCV_GET_DATA_TYPE(sat->type) == CCV_32F"
, "ccv_icf.c", 2093, __extension__ __PRETTY_FUNCTION__); }))
;
2094 // run it
2095 for (j = 0; j < count; j++)
2096 {
2097 double scale_ratio = pow(2., (double)multiscale_cascade[j]->octave / multiscale_cascade[j]->count);
2098 int starter = i > 0 ? multiscale_cascade[j]->count - (multiscale_cascade[j]->count / multiscale_cascade[j]->octave) : 0;
2099 double scale = pow(scale_ratio, starter);
2100 for (k = starter; k < multiscale_cascade[j]->count; k++)
2101 {
2102 ccv_icf_classifier_cascade_t* cascade = multiscale_cascade[j]->cascade + k;
2103 int rows = (int)(pyr[i]->rows / scale + cascade->margin.top + 0.5);
2104 int cols = (int)(pyr[i]->cols / scale + cascade->margin.left + 0.5);
2105 int top = margin.top - cascade->margin.top;
2106 int right = margin.right - cascade->margin.right;
2107 int bottom = margin.bottom - cascade->margin.bottom;
2108 int left = margin.left - cascade->margin.left;
2109 if (sat->rows - top - bottom <= cascade->size.height || sat->cols - left - right <= cascade->size.width)
2110 break;
2111 float* ptr = sat->data.f32 + top * sat->cols * ch;
2112 for (y = 0, iy = py = top; y < rows; y += params.step_through)
2113 {
2114 iy = (int)((y + 0.5) * scale + top);
2115 if (iy >= sat->rows - cascade->size.height - 1)
2116 break;
2117 if (iy > py)
2118 {
2119 ptr += sat->cols * ch * (iy - py);
2120 py = iy;
2121 }
2122 for (x = 0; x < cols; x += params.step_through)
2123 {
2124 ix = (int)((x + 0.5) * scale + left);
2125 if (ix >= sat->cols - cascade->size.width - 1)
2126 break;
2127 int pass = 1;
2128 float sum = 0;
2129 for (q = 0; q < cascade->count; q++)
2130 {
2131 ccv_icf_decision_tree_t* weak_classifier = cascade->weak_classifiers + q;
2132 int c = _ccv_icf_run_weak_classifier(weak_classifier, ptr, sat->cols, ch, ix, 0);
2133 sum += weak_classifier->weigh[c];
2134 if (sum < weak_classifier->threshold)
2135 {
2136 pass = 0;
2137 break;
2138 }
2139 }
2140 if (pass)
2141 {
2142 ccv_comp_t comp;
2143 comp.rect = ccv_rect((int)((x + 0.5) * scale * (1 << i)), (int)((y + 0.5) * scale * (1 << i)), (cascade->size.width - cascade->margin.left - cascade->margin.right) << i, (cascade->size.height - cascade->margin.top - cascade->margin.bottom) << i);
2144 comp.neighbors = 1;
2145 comp.classification.id = j + 1;
2146 comp.classification.confidence = sum;
2147 ccv_array_push(seq[j], &comp);
2148 }
2149 }
2150 }
2151 scale *= scale_ratio;
2152 }
2153 }
2154 ccv_matrix_free(sat);
2155 }
2156
2157 for (i = 1; i < scale_upto; i++)
2158 ccv_matrix_free(pyr[i]);
2159}
2160
2161ccv_array_t* ccv_icf_detect_objects(ccv_dense_matrix_t* a, void* cascade, int count, ccv_icf_param_t params)
2162{
2163 assert(count > 0)((void) sizeof ((count > 0) ? 1 : 0), __extension__ ({ if (
count > 0) ; else __assert_fail ("count > 0", "ccv_icf.c"
, 2163, __extension__ __PRETTY_FUNCTION__); }))
;
2164 int i, j, k;
2165 int type = *(((int**)cascade)[0]);
2166 for (i = 1; i < count; i++)
2167 {
2168 // check all types to be the same
2169 assert(*(((int**)cascade)[i]) == type)((void) sizeof ((*(((int**)cascade)[i]) == type) ? 1 : 0), __extension__
({ if (*(((int**)cascade)[i]) == type) ; else __assert_fail (
"*(((int**)cascade)[i]) == type", "ccv_icf.c", 2169, __extension__
__PRETTY_FUNCTION__); }))
;
2170 }
2171 ccv_array_t** seq = (ccv_array_t**)alloca(sizeof(ccv_array_t*) * count)__builtin_alloca (sizeof(ccv_array_t*) * count);
2172 for (i = 0; i < count; i++)
2173 seq[i] = ccv_array_new(sizeof(ccv_comp_t), 64, 0);
2174 switch (type)
2175 {
2176 case CCV_ICF_CLASSIFIER_TYPE_A:
2177 _ccv_icf_detect_objects_with_classifier_cascade(a, (ccv_icf_classifier_cascade_t**)cascade, count, params, seq);
2178 break;
2179 case CCV_ICF_CLASSIFIER_TYPE_B:
2180 _ccv_icf_detect_objects_with_multiscale_classifier_cascade(a, (ccv_icf_multiscale_classifier_cascade_t**)cascade, count, params, seq);
2181 break;
2182 }
2183 ccv_array_t* result_seq = ccv_array_new(sizeof(ccv_comp_t), 64, 0);
2184 ccv_array_t* seq2 = ccv_array_new(sizeof(ccv_comp_t), 64, 0);
2185 for (k = 0; k < count; k++)
2186 {
2187 /* the following code from OpenCV's haar feature implementation */
2188 if(params.min_neighbors == 0)
2189 {
2190 for (i = 0; i < seq[k]->rnum; i++)
2191 {
2192 ccv_comp_t* comp = (ccv_comp_t*)ccv_array_get(seq[k], i)((void*)(((char*)((seq[k])->data)) + (size_t)(seq[k])->
rsize * (size_t)(i)))
;
2193 ccv_array_push(result_seq, comp);
2194 }
2195 } else {
2196 ccv_array_t* idx_seq = 0;
2197 ccv_array_clear(seq2);
2198 // group retrieved rectangles in order to filter out noise
2199 int ncomp = ccv_array_group(seq[k], &idx_seq, _ccv_is_equal_same_class, 0);
2200 ccv_comp_t* comps = (ccv_comp_t*)cccalloccalloc(ncomp + 1, sizeof(ccv_comp_t));
2201
2202 // count number of neighbors
2203 for (i = 0; i < seq[k]->rnum; i++)
2204 {
2205 ccv_comp_t r1 = *(ccv_comp_t*)ccv_array_get(seq[k], i)((void*)(((char*)((seq[k])->data)) + (size_t)(seq[k])->
rsize * (size_t)(i)))
;
2206 int idx = *(int*)ccv_array_get(idx_seq, i)((void*)(((char*)((idx_seq)->data)) + (size_t)(idx_seq)->
rsize * (size_t)(i)))
;
2207
2208 comps[idx].classification.id = r1.classification.id;
2209 if (r1.classification.confidence > comps[idx].classification.confidence || comps[idx].neighbors == 0)
2210 {
2211 comps[idx].rect = r1.rect;
2212 comps[idx].classification.confidence = r1.classification.confidence;
2213 }
2214
2215 ++comps[idx].neighbors;
2216 }
2217
2218 // calculate average bounding box
2219 for (i = 0; i < ncomp; i++)
2220 {
2221 int n = comps[i].neighbors;
2222 if (n >= params.min_neighbors)
2223 ccv_array_push(seq2, comps + i);
2224 }
2225
2226 // filter out large object rectangles contains small object rectangles
2227 for (i = 0; i < seq2->rnum; i++)
2228 {
2229 ccv_comp_t* r2 = (ccv_comp_t*)ccv_array_get(seq2, i)((void*)(((char*)((seq2)->data)) + (size_t)(seq2)->rsize
* (size_t)(i)))
;
2230 int distance = (int)(ccv_min(r2->rect.width, r2->rect.height)({ typeof (r2->rect.width) _a = (r2->rect.width); typeof
(r2->rect.height) _b = (r2->rect.height); (_a < _b)
? _a : _b; })
* 0.25 + 0.5);
2231 for (j = 0; j < seq2->rnum; j++)
2232 {
2233 ccv_comp_t r1 = *(ccv_comp_t*)ccv_array_get(seq2, j)((void*)(((char*)((seq2)->data)) + (size_t)(seq2)->rsize
* (size_t)(j)))
;
2234 if (i != j &&
2235 abs(r1.classification.id) == r2->classification.id &&
2236 r1.rect.x >= r2->rect.x - distance &&
2237 r1.rect.y >= r2->rect.y - distance &&
2238 r1.rect.x + r1.rect.width <= r2->rect.x + r2->rect.width + distance &&
2239 r1.rect.y + r1.rect.height <= r2->rect.y + r2->rect.height + distance &&
2240 // if r1 (the smaller one) is better, mute r2
2241 (r2->classification.confidence <= r1.classification.confidence && r2->neighbors < r1.neighbors))
2242 {
2243 r2->classification.id = -r2->classification.id;
2244 break;
2245 }
2246 }
2247 }
2248
2249 // filter out small object rectangles inside large object rectangles
2250 for (i = 0; i < seq2->rnum; i++)
2251 {
2252 ccv_comp_t r1 = *(ccv_comp_t*)ccv_array_get(seq2, i)((void*)(((char*)((seq2)->data)) + (size_t)(seq2)->rsize
* (size_t)(i)))
;
2253 if (r1.classification.id > 0)
2254 {
2255 int flag = 1;
2256
2257 for (j = 0; j < seq2->rnum; j++)
2258 {
2259 ccv_comp_t r2 = *(ccv_comp_t*)ccv_array_get(seq2, j)((void*)(((char*)((seq2)->data)) + (size_t)(seq2)->rsize
* (size_t)(j)))
;
2260 int distance = (int)(ccv_min(r2.rect.width, r2.rect.height)({ typeof (r2.rect.width) _a = (r2.rect.width); typeof (r2.rect
.height) _b = (r2.rect.height); (_a < _b) ? _a : _b; })
* 0.25 + 0.5);
2261
2262 if (i != j &&
2263 abs(r1.classification.id) == abs(r2.classification.id) &&
2264 r1.rect.x >= r2.rect.x - distance &&
2265 r1.rect.y >= r2.rect.y - distance &&
2266 r1.rect.x + r1.rect.width <= r2.rect.x + r2.rect.width + distance &&
2267 r1.rect.y + r1.rect.height <= r2.rect.y + r2.rect.height + distance &&
2268 // if r2 is better, we mute r1
2269 (r2.classification.confidence > r1.classification.confidence || r2.neighbors >= r1.neighbors))
2270 {
2271 flag = 0;
2272 break;
2273 }
2274 }
2275
2276 if (flag)
2277 ccv_array_push(result_seq, &r1);
2278 }
2279 }
2280 ccv_array_free(idx_seq);
2281 ccfreefree(comps);
2282 }
2283 ccv_array_free(seq[k]);
2284 }
2285 ccv_array_free(seq2);
2286
2287 return result_seq;
2288}