| 80 | } |
| 81 | |
| 82 | Array<float> otsuThreshold(const Array<float>& in, const unsigned NUM_BINS, |
| 83 | const float maxVal) { |
| 84 | Array<uint> hist = histogram<float>(in, NUM_BINS, 0, maxVal, false); |
| 85 | |
| 86 | const dim4& inDims = in.dims(); |
| 87 | const dim4& hDims = hist.dims(); |
| 88 | |
| 89 | const dim4 oDims(1, hDims[1], hDims[2], hDims[3]); |
| 90 | vector<af_seq> seqBegin(4, af_span); |
| 91 | vector<af_seq> seqRest(4, af_span); |
| 92 | vector<af_seq> sliceIndex(4, af_span); |
| 93 | |
| 94 | seqBegin[0] = af_make_seq(0, static_cast<double>(hDims[0] - 1), 1); |
| 95 | seqRest[0] = af_make_seq(0, static_cast<double>(hDims[0] - 1), 1); |
| 96 | |
| 97 | Array<float> UnitP = createValueArray<float>(oDims, 1.0f); |
| 98 | Array<float> histf = cast<float, uint>(hist); |
| 99 | Array<float> totals = createValueArray<float>(hDims, inDims[0] * inDims[1]); |
| 100 | Array<float> weights = |
| 101 | iota<float>(dim4(NUM_BINS), oDims); // a.k.a histogram shape |
| 102 | |
| 103 | // pixel frequency probabilities |
| 104 | auto freqs = arithOp<float, af_div_t>(histf, totals, hDims); |
| 105 | auto cumFreqs = scan<af_add_t, float, float>(freqs, 0); |
| 106 | auto oneMCumFreqs = arithOp<float, af_sub_t>(UnitP, cumFreqs, hDims); |
| 107 | auto qLqH = arithOp<float, af_mul_t>(cumFreqs, oneMCumFreqs, hDims); |
| 108 | auto product = arithOp<float, af_mul_t>(weights, freqs, hDims); |
| 109 | auto cumProduct = scan<af_add_t, float, float>(product, 0); |
| 110 | auto weightedSum = reduce<af_add_t, float, float>(product, 0); |
| 111 | |
| 112 | dim4 sigmaDims(NUM_BINS - 1, hDims[1], hDims[2], hDims[3]); |
| 113 | Array<float> sigmas = createEmptyArray<float>(sigmaDims); |
| 114 | for (unsigned b = 0; b < (NUM_BINS - 1); ++b) { |
| 115 | const dim4 fDims(b + 1, hDims[1], hDims[2], hDims[3]); |
| 116 | const dim4 eDims(NUM_BINS - 1 - b, hDims[1], hDims[2], hDims[3]); |
| 117 | |
| 118 | sliceIndex[0] = {double(b), double(b), 1}; |
| 119 | seqBegin[0].end = static_cast<double>(b); |
| 120 | seqRest[0].begin = static_cast<double>(b + 1); |
| 121 | |
| 122 | auto qL = createSubArray(cumFreqs, sliceIndex, false); |
| 123 | auto qH = arithOp<float, af_sub_t>(UnitP, qL, oDims); |
| 124 | auto _muL = createSubArray(cumProduct, sliceIndex, false); |
| 125 | auto _muH = arithOp<float, af_sub_t>(weightedSum, _muL, oDims); |
| 126 | auto muL = arithOp<float, af_div_t>(_muL, qL, oDims); |
| 127 | auto muH = arithOp<float, af_div_t>(_muH, qH, oDims); |
| 128 | auto diff = arithOp<float, af_sub_t>(muL, muH, oDims); |
| 129 | auto sqrd = arithOp<float, af_mul_t>(diff, diff, oDims); |
| 130 | auto op2 = createSubArray(qLqH, sliceIndex, false); |
| 131 | auto sigma = arithOp<float, af_mul_t>(sqrd, op2, oDims); |
| 132 | |
| 133 | auto binRes = createSubArray<float>(sigmas, sliceIndex, false); |
| 134 | copyArray(binRes, sigma); |
| 135 | } |
| 136 | |
| 137 | Array<float> thresh = createEmptyArray<float>(oDims); |
| 138 | Array<uint> locs = createEmptyArray<uint>(oDims); |
| 139 |
no test coverage detected