001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit http://imagingbook.com for additional details. 008 *******************************************************************************/ 009 010package imagingbook.pub.histogram; 011 012public class PiecewiseLinearCdf { 013 private int K; 014 private int[] iArr; 015 private double[] pArr; 016 017 public PiecewiseLinearCdf(int K, int[] ik, double[] Pk) { 018 this.K = K; // number of intensity values (typ. 256) 019 int N = ik.length; 020 iArr = new int[N + 2]; // array of intensity values 021 pArr = new double[N + 2]; // array of cum. distribution values 022 iArr[0] = -1; 023 pArr[0] = 0; 024 for (int i = 0; i < N; i++) { 025 iArr[i + 1] = ik[i]; 026 pArr[i + 1] = Pk[i]; 027 } 028 iArr[N + 1] = K - 1; 029 pArr[N + 1] = 1; 030 } 031 032 double getCdf(int i) { 033 if (i < 0) 034 return 0; 035 else if (i >= K - 1) 036 return 1; 037 else { 038 int s = 0, N = iArr.length - 1; 039 for (int j = 0; j <= N; j++) { // find s (segment index) 040 if (iArr[j] <= i) 041 s = j; 042 else 043 break; 044 } 045 return pArr[s] + (i - iArr[s]) 046 * ((pArr[s + 1] - pArr[s]) / (iArr[s + 1] - iArr[s])); 047 } 048 } 049 050 int getInverseCdf(double z) { 051 if (z < getCdf(0)) 052 return 0; 053 else if (z >= 1) 054 return K - 1; 055 else { 056 int r = 0, N = iArr.length - 1; 057 for (int j = 0; j <= N; j++) { // find r (segment index) 058 if (pArr[j] <= z) 059 r = j; 060 else 061 break; 062 } 063 return (int) Math.round(iArr[r] + (z - pArr[r]) 064 * ((iArr[r + 1] - iArr[r]) / (pArr[r + 1] - pArr[r]))); 065 } 066 } 067 068 // for testing only: 069 public double[] getPdf() { 070 double[] prob = new double[K]; 071 prob[0] = getCdf(0); 072 for (int i = 1; i < K; i++) { 073 prob[i] = getCdf(i) - getCdf(i-1); 074 } 075 return prob; 076 } 077 078}