float imProcessMinMaxThreshold(const imImage* src_image, imImage* dst_image) { imStats stats; imCalcImageStatistics(src_image, &stats); float level = (stats.max - stats.min)/2.0f; imProcessThreshold(src_image, dst_image, level, 1); return level; }
int imProcessOtsuThreshold(const imImage* src_image, imImage* dst_image) { int hcount; unsigned long* histo = imHistogramNew(src_image->data_type, &hcount); imCalcHistogram(src_image, histo, 0, 0); double totalPixels = src_image->count; double* p = new double [hcount]; for (int i=0; i<hcount; i++) p[i] = (double)histo[i]/totalPixels; int level = MaximizeDiscriminantFunction(p, hcount); level += imHistogramShift(src_image->data_type); imProcessThreshold(src_image, dst_image, (float)level, 1); imHistogramRelease(histo); delete [] p; return level; }
int imProcessPercentThreshold(const imImage* src_image, imImage* dst_image, float percent) { int hcount; unsigned long* histo = imHistogramNew(src_image->data_type, &hcount); unsigned long cut = (unsigned long)((src_image->count * percent)/100.); imCalcHistogram(src_image, histo, 0, 1); // cumulative int i; for (i = 0; i < hcount; i++) { if (histo[i] > cut) break; } int level = (i==0? 0: i==hcount? hcount-1: i-1); level += imHistogramShift(src_image->data_type); imProcessThreshold(src_image, dst_image, (float)level, 1); imHistogramRelease(histo); return level; }
int imProcessUniformErrThreshold(const imImage* src_image, imImage* dst_image) { int level = thresUniErr((imbyte*)src_image->data[0], src_image->width, src_image->height); imProcessThreshold(src_image, dst_image, (float)level, 1); return level; }
int imProcessBrinkThreshold(const imImage* image, imImage* dest, bool white_is_255 ) { imImage *src = imImageDuplicate( image ); if ( !white_is_255 ) imProcessNegative( src, src ); int i, j; int Topt = 0; double p[MAX_GRAY]; // pmf (i.e. normalized histogram) unsigned long histo[MAX_GRAY]; // from imlib: "Histogram is always 256 positions long" double m_f[MAX_GRAY]; // first foreground moment double m_b[MAX_GRAY]; // first background moment double tmp0[MAX_GRAY][MAX_GRAY]; double tmp1[MAX_GRAY][MAX_GRAY]; double tmp3[MAX_GRAY][MAX_GRAY]; double tmp4[MAX_GRAY][MAX_GRAY]; double tmpVec1[MAX_GRAY]; double tmpVec2[MAX_GRAY]; imCalcGrayHistogram(src, histo, NON_CUMULATIVE); // gray histogram computed double invHistSum = 1.0 / vecSum(histo, MAX_GRAY); // inverse of the sum for (i = 0; i < MAX_GRAY; ++i) p[i] = histo[i] * invHistSum; // equivalent to dividing by the sum, but faster! m_f[0] = 0.0; for (i = 1; i < MAX_GRAY; ++i) // m_f = cumsum(g .* p).'; m_f[i] = i * p[i] + m_f[i - 1]; memcpy(m_b, m_f, VEC_DBL_SZ); // m_b = m_f(end) - m_f; for (i = 0; i < MAX_GRAY; ++i) m_b[i] = m_f[MAX_GRAY - 1] - m_b[i]; /****************** END OF BINAR_ASHLEY PORTION, START OF ENTROPY_BRINK********************************/ for (i = 0; i < MAX_GRAY; ++i) // tmp0 = m_f_rep ./ g_rep; { for (j = 0; j < MAX_GRAY; ++j) { tmp0[i][j] = m_f[j] / i; if ((m_f[j] == 0) || (i == 0)) { tmp1[i][j] = 0.0; // replace inf or NaN values with 0 tmp3[i][j] = 0.0; } else { tmp1[i][j] = log(tmp0[i][j]); tmp3[i][j] = log(1.0 / tmp0[i][j]);; } tmp4[i][j] = p[i] * (m_f[j] * tmp1[i][j] + i * tmp3[i][j]); } } diagCumSum(tmpVec1, tmp4); // tmpVec is now the diagonal of the cumulative sum of tmp4 // same operation but for background moment, NOTE: tmp1 through tmp4 get overwritten for (i = 0; i < MAX_GRAY; ++i) { for (j = 0; j < MAX_GRAY; ++j) { tmp0[i][j] = m_b[j] / i; // tmpb0 = m_b_rep ./ g_rep; if ((m_b[j] == 0) || (i == 0)) { tmp1[i][j] = 0.0; // replace inf or NaN values with 0 tmp3[i][j] = 0.0; } else { tmp1[i][j] = log(tmp0[i][j]); tmp3[i][j] = log(1.0 / tmp0[i][j]);; } tmp4[i][j] = p[i] * (m_b[j] * tmp1[i][j] + i * tmp3[i][j]); } } sumMinusDiagCumSum(tmpVec2, tmp4); // sum columns, subtract diagonal of cumsum of tmp4 for (i = 0; i < MAX_GRAY; ++i) tmpVec1[i] += tmpVec2[i]; Topt = calcTopt(m_f, m_b, tmpVec1); // DO I NEED TO ADD ONE? imProcessThreshold(src, dest, Topt, true); imProcessBitwiseNot(dest, dest); // HACK ALERT: HAVE TO FLIP BITS return Topt; }