Spaces:
Runtime error
Runtime error
| import numpy as np | |
| import cv2 as cv | |
| from PIL import Image | |
| def norm_mat(mat): | |
| return cv.normalize(mat, None, 0, 255, cv.NORM_MINMAX).astype(np.uint8) | |
| def minmax_dev(patch, mask): | |
| c = patch[1, 1] | |
| minimum, maximum, _, _ = cv.minMaxLoc(patch, mask) | |
| if c < minimum: | |
| return -1 | |
| if c > maximum: | |
| return +1 | |
| return 0 | |
| def blk_filter(img, radius): | |
| result = np.zeros_like(img, np.float32) | |
| rows, cols = result.shape | |
| block = 2 * radius + 1 | |
| for i in range(radius, rows, block): | |
| for j in range(radius, cols, block): | |
| result[ | |
| i - radius : i + radius + 1, j - radius : j + radius + 1 | |
| ] = np.std( | |
| img[i - radius : i + radius + 1, j - radius : j + radius + 1] | |
| ) | |
| return cv.normalize(result, None, 0, 127, cv.NORM_MINMAX, cv.CV_8UC1) | |
| def preprocess(image, channel=4, radius=2): | |
| if not isinstance(image, np.ndarray): | |
| image = np.array(image) # Ensure image is a NumPy array | |
| if channel == 0: | |
| img = cv.cvtColor(image, cv.COLOR_BGR2GRAY) | |
| elif channel == 4: | |
| b, g, r = cv.split(image.astype(np.float64)) | |
| img = cv.sqrt(cv.pow(b, 2) + cv.pow(g, 2) + cv.pow(r, 2)) | |
| else: | |
| img = image[:, :, 3 - channel] | |
| kernel = 3 | |
| border = kernel // 2 | |
| shape = (img.shape[0] - kernel + 1, img.shape[1] - kernel + 1, kernel, kernel) | |
| strides = 2 * img.strides | |
| patches = np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides) | |
| patches = patches.reshape((-1, kernel, kernel)) | |
| mask = np.full((kernel, kernel), 255, dtype=np.uint8) | |
| mask[border, border] = 0 | |
| blocks = [0] * shape[0] * shape[1] | |
| for i, patch in enumerate(patches): | |
| blocks[i] = minmax_dev(patch, mask) | |
| output = np.array(blocks).reshape(shape[:-2]) | |
| output = cv.copyMakeBorder( | |
| output, border, border, border, border, cv.BORDER_CONSTANT | |
| ) | |
| low = output == -1 | |
| high = output == +1 | |
| minmax = np.zeros_like(image) | |
| if radius > 0: | |
| radius += 3 | |
| low = blk_filter(low, radius) | |
| high = blk_filter(high, radius) | |
| if channel <= 2: | |
| minmax[:, :, 2 - channel] = low | |
| minmax[:, :, 2 - channel] += high | |
| else: | |
| minmax = np.repeat(low[:, :, np.newaxis], 3, axis=2) | |
| minmax += np.repeat(high[:, :, np.newaxis], 3, axis=2) | |
| minmax = norm_mat(minmax) | |
| else: | |
| if channel == 0: | |
| minmax[low] = [0, 0, 255] | |
| minmax[high] = [0, 0, 255] | |
| elif channel == 1: | |
| minmax[low] = [0, 255, 0] | |
| minmax[high] = [0, 255, 0] | |
| elif channel == 2: | |
| minmax[low] = [255, 0, 0] | |
| minmax[high] = [255, 0, 0] | |
| elif channel == 3: | |
| minmax[low] = [255, 255, 255] | |
| minmax[high] = [255, 255, 255] | |
| return Image.fromarray(minmax) |