文章目录
前言
本程序主要应用于栅格图像的处理,采用递归思想实现种子填充算法。
一、算法实现
# -*- coding = utf-8 -*-
# @time:2021/5/25 23:33
# Author:scw
# @File:Seed_Filling.py
# @Software:PyCharm
# Environment:Python3.6
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm
import sys
# 更改递归深度
sys.setrecursionlimit(100000)
class Seed_Filling_S(object):
def __init__(self):
self.wide = None
self.height = None
self.photolist = []
self.queue = []
self.area_limit = 40
self.char = 1
self.label = 0
# 读取文本数据并预处理
def DataInput(self):
fphoto = open("bi-image.txt", "r")
for line in fphoto.readlines():
line = line.replace('\n', '')
line = line.strip(',')
line = line.split(",")
line = [eval(i) for i in line] # 将字符类型改为整型
self.photolist.append(line)
self.height = len(self.photolist)
self.wide = len(self.photolist[0])
fphoto.close()
# print(self.height)
# print(self.wide)
def Gray_Level_Judge(self, i, j):
if i != -1 and i != self.height and j != -1 and j != self.wide:
if self.photolist[i][j] == 255:
self.queue.append([i, j])
self.label += 1
self.photolist[i][j] = self.label
Seed_Filling_S.Gray_Level_Judge(self, i - 1, j)
Seed_Filling_S.Gray_Level_Judge(self, i, j + 1)
Seed_Filling_S.Gray_Level_Judge(self, i + 1, j)
Seed_Filling_S.Gray_Level_Judge(self, i, j - 1)
else:
return -1
else:
return -1
# 种子填充
def Seed_filling(self):
# 面积阈值的确定
char = input("是否更改面积阈值:[Y/N]")
if char in ['y', 'Y']:
self.area_limit = eval(input("请输入面积阈值大小:"))
else:
print("默认阈值为40")
# 遍历
for i in range(self.height):
for j in range(self.wide):
# 确保在边界内部实现递归
if self.photolist[i][j] == 255 and i != -1 and j != -1 and i != self.height and j != self.wide:
self.queue.append([i, j])
self.label += 1 # 记录当前面积大小
self.photolist[i][j] = self.label # 以当前面积对其赋值,以免重复遍历
# 设置递归基例为返回真值
if self.char:
self.char = Seed_Filling_S.Gray_Level_Judge(self, i - 1, j)
self.char = 1 # 更新
if self.char:
self.char = Seed_Filling_S.Gray_Level_Judge(self, i, j + 1)
self.char = 1
if self.char:
self.char = Seed_Filling_S.Gray_Level_Judge(self, i + 1, j)
self.char = 1
if self.char:
self.char = Seed_Filling_S.Gray_Level_Judge(self, i, j - 1)
else:
continue
# 面积是否舍弃确定
if self.label < self.area_limit:
for list in self.queue:
self.photolist[list[0]][list[1]] = 0
self.label = 0 # 更新标签值
self.queue.clear() # 清空当前队列
# 更新后的文本内容写入
def Print_txt(self):
f = open("bi-image_end.txt", "w")
for i in range(self.height):
for j in range(self.wide):
if self.photolist[i][j] == 0:
f.write('0' + ',')
else:
self.photolist[i][j] = 255 # 二值化,将非0情况统一为255
f.write('255' + ',')
f.write('\n')
f.close()
# 输出图片
def Print_bmp(self):
plt.imsave('bi-image_end.bmp', np.array(self.photolist).reshape(self.height, self.wide), cmap=cm.gray)
def main(self):
Seed_Filling_S.DataInput(self) # 数据载入与预处理
Seed_Filling_S.Seed_filling(self) # 种子填充
Seed_Filling_S.Print_txt(self) # 输出文本
Seed_Filling_S.Print_bmp(self) # 输出图片
if __name__ == "__main__":
d = Seed_Filling_S()
d.main()
二、原始数据文件
在程序中读取的为影像的文本文件,由于文本文件不易查看,这里不再附录,另附图像转文本程序:
#导入Image方法
from PIL import Image
#打开图片
im=Image.open('bi-image.bmp')
#获取图片宽和高
width=im.size[0]
height=im.size[1]
#将图片转化为文本
fh=open('bi-image.txt', 'w')
for i in range(height):
for j in range(width):
#获取(j,i)像素点值
col=im.getpixel((j,i))
colsum=col
if(colsum==0):
#黑色
fh.write('0'+',')#在黑色像素点处用数字0代替
else:
fh.write('255'+',')#在非黑色像素点处用空格255代替
fh.write('\n')
fh.close()
三、输出