(ch)
| 18 | n_bins = 256 |
| 19 | |
| 20 | def tune_channel(ch): |
| 21 | n = ch.size |
| 22 | cut = cutoff * n // 100 |
| 23 | if cut == 0: |
| 24 | high, low = ch.max(), ch.min() |
| 25 | else: |
| 26 | hist = cv2.calcHist([ch], [0], None, [n_bins], [0, n_bins]) |
| 27 | low = np.argwhere(np.cumsum(hist) > cut) |
| 28 | low = 0 if low.shape[0] == 0 else low[0] |
| 29 | high = np.argwhere(np.cumsum(hist[::-1]) > cut) |
| 30 | high = n_bins - 1 if high.shape[0] == 0 else n_bins - 1 - high[0] |
| 31 | if high <= low: |
| 32 | table = np.arange(n_bins) |
| 33 | else: |
| 34 | scale = (n_bins - 1) / (high - low) |
| 35 | offset = -low * scale |
| 36 | table = np.arange(n_bins) * scale + offset |
| 37 | table[table < 0] = 0 |
| 38 | table[table > n_bins - 1] = n_bins - 1 |
| 39 | table = table.clip(0, 255).astype(np.uint8) |
| 40 | return table[ch] |
| 41 | |
| 42 | channels = [tune_channel(ch) for ch in cv2.split(img)] |
| 43 | out = cv2.merge(channels) |
no test coverage detected
searching dependent graphs…