1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
| from PIL import Image from tqdm import tqdm import numpy as np import os
class PreDigest(): def __init__(self, source, dirpath, K, block, number): ''' 预处理初始化类 :param source: 图片原路径 :param dirpath: 保存目录路径 :param K: 保留的特征值数量 :param block: 二值化操作梯度的大小 :param number: 进行二值化操作的次数 ''' self.source = source self.dirpath = dirpath self.K = K self.block = block self.number = number
def _get_bin_table(self, threshold=200): ''' 获取灰度转二值的映射table 0表示黑色,1表示白色 :param threshold: 二值化的边界阈值 :return: ''' table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(1) return table
def _sum_9_region_new(self, img, x, y): ''' 确认噪声点 :param img:图片 :param x: :param y: :return: ''' cur_pixel = img.getpixel((x, y)) width = img.width height = img.height
if cur_pixel == 1: return 0
if y < 3: return 1 elif y > height - 3: return 1 else: if x < 3: return 1 elif x == width - 1: return 1 else: sum = img.getpixel((x - 1, y - 1)) \ + img.getpixel((x - 1, y)) \ + img.getpixel((x - 1, y + 1)) \ + img.getpixel((x, y - 1)) \ + cur_pixel \ + img.getpixel((x, y + 1)) \ + img.getpixel((x + 1, y - 1)) \ + img.getpixel((x + 1, y)) \ + img.getpixel((x + 1, y + 1)) return 9 - sum
def _collect_noise_point(self, img): ''' 搜索到所有的噪声点 :param img: 图片数组 :return: ''' noise_point_list = [] for x in range(img.width): for y in range(img.height): res_9 = self._sum_9_region_new(img, x, y) if (0 < res_9 < 3) and img.getpixel((x, y)) == 0: pos = (x, y) noise_point_list.append(pos) return noise_point_list
def _remove_noise_pixel(self, img, noise_point_list): ''' 根据噪点的位置信息,消除二值图片的黑点噪声 :param img: 图片数组 :param noise_point_list: 统计到的噪声点的情况 :return: ''' for item in noise_point_list: img.putpixel((item[0], item[1]), 1)
def _restore(self, u, sigma, v, k): ''' 转换成图片数组 :param u: :param sigma: :param v: :param k: :return: ''' a = np.dot(u[:, :k], np.diag(sigma[:k])).dot(v[:k, :]) a[a < 0] = 0 a[a > 255] = 255 return np.rint(a).astype('uint8')
def _SVD(self, frame, K = 10): ''' 进行SVD操作 :param frame: 图片数组 :param K: 保留特征值数量 :return: ''' a = np.array(frame) u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0]) u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1]) u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])
R = self._restore(u_r, sigma_r, v_r, K) G = self._restore(u_g, sigma_g, v_g, K) B = self._restore(u_b, sigma_b, v_b, K) I = np.stack((R, G, B), axis=2) return I
def _pre_digest(self, gray, threshold): table = self._get_bin_table(threshold) binary = gray.point(table, '1') noise_point_list = self._collect_noise_point(binary) self._remove_noise_pixel(binary, noise_point_list) binary.save(os.path.join(self.dirpath, "T matrix_" + str(threshold) + ".png"))
def _svd_img(self, filepath): ''' 开始执行svd操作 :param filepath: :return: ''' img = Image.open(filepath) svd_array = self._SVD(img, self.K) svd_img = Image.fromarray(svd_array) new_path = os.path.join(self.dirpath, "T matrix_svd.png") svd_img.save(new_path) return new_path
def run(self): print("开始SVD处理!") new_path = self._svd_img(self.source) print("结束SVD处理!") img = Image.open(new_path) gray = img.convert('L') gray.save(os.path.join(self.dirpath, "T matrix_grey.png")) for i in tqdm(range(1, self.number)): self._pre_digest(gray, self.block * i)
if __name__ == '__main__': K = 400 block = 25 number = int(256 / block) dir_path = "./after_img_" + str(K) + "_" + str(block) if(not os.path.exists(dir_path)): os.mkdir(dir_path) tmp = PreDigest("./img/T matrix.png", dir_path, K, block, number) tmp.run()
|