使用Python PIL库实现简单验证码的去噪处理(3)

通过binary mode的值我们可以知道二值化后得到的图片的像素值由0或1表示,而且当前(0, 0)代表的像素值的为0,它代表黑色,通过上面的图片我们也可以知道,左上角顶点确实是黑色的。

上面的代码中我们还使用了getcolors方法,它用来返回像素信息,是一个含有元素的列表:[(该种像素的数量,(该种像素)),(...),...],当该列表特别大的时候,它会返回None,这也是为什么上面彩色图片调用getcolors的时候会返回None。而[(503, 0), (1993, 1)]就表示我们得到的二值化黑白图片,由503个黑色像素点和1993个白色像素点组成。

通过binary.size我们可以得到二值化后的黑白图片的width和height值:(78, 32),它就表示该图片由78X32个像素点组成,正好等于503+1993的和。(78, 32)也说明该图片横向上共有32行,每行有78个像素点。将由0和1表示的图片打印出来看一下:

# encoding=utf8 from PIL import Image def get_bin_table(threshold=115): ''' 获取灰度转二值的映射table 0表示黑色,1表示白色 ''' table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(1) return table def main(): image = Image.open('RandomPicture.png') imgry = image.convert('L') table = get_bin_table() binary = imgry.point(table, '1') width, height = binary.size lis = binary.getdata() # 返回图片所有的像素值,要使用list()才能显示出具体数值 lis = list(lis) start = 0 step = width for i in range(height): for p in lis[start: start+step]: if p == 1: # 将白色的点变成空格,方便人眼看 p = ' ' print p, print start += step if __name__ == '__main__': main()

运行结果:

使用Python PIL库实现简单验证码的去噪处理


通过上面的结果已经大致可以看出该图片表示的就是“959c”。

3、去除噪点

由上面的结果也不难看出,除了表示“959c”的“0”,图片中还有其他的“0”代表的“噪点”,我们要尽可能的去除它们,方便后期的识别训练。

对于去除噪点代码实现:

# encoding=utf8 from PIL import Image def sum_9_region_new(img, x, y): '''确定噪点 ''' 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: # y不在边界 if x < 3: # 前两列 return 1 elif x == width - 1: # 右边非顶点 return 1 else: # 具备9领域条件的 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(img): '''收集所有的噪点''' noise_point_list = [] for x in range(img.width): for y in range(img.height): res_9 = 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(img, noise_point_list): '''根据噪点的位置信息,消除二值图片的黑点噪声''' for item in noise_point_list: img.putpixel((item[0], item[1]), 1) def get_bin_table(threshold=115): '''获取灰度转二值的映射table,0表示黑色,1表示白色''' table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(1) return table def main(): image = Image.open('RandomPicture.png') imgry = image.convert('L') table = get_bin_table() binary = imgry.point(table, '1') noise_point_list = collect_noise_point(binary) remove_noise_pixel(binary, noise_point_list) binary.save('finaly.png') if __name__ == '__main__': main()

运行结果:

通过截图可以知道,我们已经去除了图片四周的噪点以及一些孤立的噪点。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/83218f1cb4dec2dadc339a7fd3aa263c.html