|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- import numpy as np
- from PIL import Image
- import matplotlib.pyplot as plt
- import matplotlib.cm as cm
- import scipy.signal as signal
- import cv2 as cv
- import random
- import easygui as g
- import imutils
- import time
- class Point(object):
- def __init__(self,x,y):
- self.x = x
- self.y = y
- def getX(self):
- return self.x
- def getY(self):
- return self.y
- def criterion(p): #定义我们自己种子生长的准则,p=1为一种规则,p=0为一种生长规则
- if p == 1:
- connect = [Point(-1,-1),Point(-1,0),Point(0,-1),Point(0,1),Point(1,1),Point(1,0),Point(-1,1),Point(1,-1)]
- else:
- connect = [Point(-1,0),Point(0,-1),Point(0,1),Point(1,0)]
- return connect
- def gray_distance(image,point1,point2): #返回灰度值之间的差异,太大的我们舍弃
- return abs(int(image[point1.x,point1.y])-int(image[point2.x,point2.y]))
- def seed_growing(image):
- thresh = 3
- #我们自己设置的门限
- label1 = 1 #label = 1这样的话图像中为黑色,容易发现
- seed = [Point(250,100),Point(82,75),Point(20,300)] #定义初始种子点
- image = image[:, :, 0] * 0.11 + image[:, :, 1] * 0.59 + image[:, :, 2] * 0.3
- image = image.astype(np.uint8)
- rows = image.shape[0]
- cols = image.shape[1]
- image_mark = np.full((rows,cols),255)
- seedlist = []
- p=1 #定义我们自己的准则
- connects = criterion(p)
- for i in seed:
- seedlist.append(i)
- while ( len(seedlist) > 0):
- seed_testing = seedlist.pop(0)
- image_mark[seed_testing.x,seed_testing.y] = label1
- for i in range(8): #因为我定义的P为1 所以是8个点,p=0则有四个点
- tempX = seed_testing.x + connects[i].x
- tempY = seed_testing.y + connects[i].y
- if tempX < 0 or tempY < 0 or tempX >=rows or tempY >= cols:
- continue
- gray_dis = gray_distance(image,seed_testing,Point(tempX,tempY))
- if gray_dis < thresh and image_mark[tempX,tempY] == 255:
- seedlist.append(Point(tempX,tempY))
- image_mark[tempX,tempY] = label1
- cv.imshow('seed grow',image_mark.astype(np.uint8))
- cv.waitKey(0)
- def nothing(x):
- pass
- def change_number(image):
- image = image[:, :, 0] * 0.11 + image[:, :, 1] * 0.59 + image[:, :, 2] * 0.3
- image = image.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- rows = image.shape[0]
- cols = image.shape[1]
- min_area = 0
- max_area = 0
- area = rows * cols
- cv.namedWindow('could change threshhold')
- cv.createTrackbar('intensity', 'could change threshhold', 0, 255, nothing)
- count = 0
- # chance =0
- data1 = 699
- data = 0
- while (1):
- cv.imshow('could change threshhold', image) # 返回滑块所在位置对应的值
- medium_number = cv.getTrackbarPos('intensity', 'could change threshhold')
- # if chance == 0:
- image2 =image.copy()
- for i in range(rows):
- for j in range(cols):
- if int(image2[i, j]) < medium_number:
- image2[i, j] = 0
- min_area += 1
- else:
- image2[i, j] = 255
- max_area += 1
- image2 = image2.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- cv.imshow('image2',image2)
- data +=1
- if data ==8: #设置我们自己的时钟,按Q退出
- string = 'gray area is {},white area is {}'.format(min_area * area / (min_area + max_area),max_area * area / (min_area + max_area))
- print(string)
- data = 0
- # data +=1
- # if data == 2:
- # if data1 != medium_number:
- # data1 = medium_number
- # count = 0
- # else:
- # count +=1
- # if count == 2:
- # image3 = image.copy()
- # for i in range(rows):
- # for j in range(cols):
- # if int(image3[i, j]) < medium_number:
- # image3[i, j] = 0
- # min_area += 1
- # else:
- # image3[i, j] = 255
- # max_area += 1
- # image3 = image3.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- # string = 'gray area is {},white area is {}'.format(min_area * area / (min_area + max_area),max_area * area / (min_area + max_area))
- # print(string)
- # count =0
- # data = 0
- # chance +=1
- if cv.waitKey(1) == ord('q'):
- break
- cv.destroyAllWindows()
- def static_number(image): #也进行灰度化
- image = image[:, :, 0] * 0.11 + image[:, :, 1] * 0.59 + image[:, :, 2] * 0.3
- image = image.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- rows = image.shape[0]
- cols = image.shape[1]
- sum2 = []
- for i in range(rows):
- for j in range(cols):
- sum2.append(int(image[i, j]))
- sum2.sort()
- medium_number = sum2[len(sum2)//2] #去中位数的灰度值
- min_area = 0
- max_area = 0
- area = rows * cols
- for i in range(rows):
- for j in range(cols):
- if int(image[i,j]) < medium_number:
- image[i,j] = 0
- min_area +=1
- else:
- image[i,j] = 255
- max_area +=1
- image = image.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- g.msgbox('灰色区域面积为{0},白色面积为{1}'.format(min_area * area /(min_area+max_area),max_area * area/(min_area+max_area) ))
- cv.imshow('static number image',image)
- cv.waitKey(0)
- def myvar(image): #将输入图片转换为灰度图
- image = image[:, :, 0] * 0.11 + image[:, :, 1] * 0.59 + image[:, :, 2] * 0.3
- image = image.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- rows = image.shape[0]
- cols = image.shape[1]
- sum1=[]
- for i in range(rows):
- for j in range(cols):
- sum1.append(int(image[i,j]))
- sum_average = sum(sum1)/len(sum1)
- var_sum=[]
- for i in range(rows):
- for j in range(cols):
- var_sum.append(image[i,j]**2/len(sum1))
- var = sum(var_sum) - sum_average**2
- return var
- def hist_stretch(image): #没做灰度变换
- r_min, r_max = 255, 0
- a=[]
- for i in range(image.shape[0]):
- for j in range(image.shape[1]):
- for k in range(image.shape[2]):
- a.append(image[i,j,k])
- if image[i, j, k] > r_max:
- r_max = image[i, j, k]
- if image[i, j, k] < r_min:
- r_min = image[i, j, k]
- a=np.array(a).reshape(-1)
- a_var=np.var(a)
- r1, s1 = r_min, 0
- r2, s2 = r_max, 255 # 这四个值决定了分段函数的走向
- # k1 = s1 / r1
- # k3 = (255 - s2) / (255 - r2)
- k2 = (s2 - s1) / (r2 - r1) #255 * (最大灰度值-最小灰度值)
- b=[]
- precewise_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
- for i in range(image.shape[0]):
- for j in range(image.shape[1]):
- for k in range(image.shape[2]):
- precewise_img[i, j, k] = k2 * (image[i, j, k] - r1)
- b.append(precewise_img[i,j,k])
- b = np.array(b).reshape(-1,1)
- b_var = np.var(b)
- # g.msgbox('变换前的方差为{},变换后的方差为{}'.format(int(a),int(b)))
- print(a)
- print(b)
- # 原图中做分段线性变化后需要对图像进行归一化操作,并将数据类型转换到np.uint8
- cv.normalize(precewise_img, precewise_img, 0, 255, cv.NORM_MINMAX)
- precewise_img = cv.convertScaleAbs(precewise_img)
- g.msgbox('处理前的图片方差为{one},处理后的方差为{two}'.format(one=myvar(image), two=myvar(precewise_img)))
- cv.imshow('origin image', imutils.resize(image, 480))
- cv.imshow('hist_stretch image', imutils.resize(precewise_img, 480))
- if cv.waitKey(0) == 27:
- cv.destroyAllWindows()
- def muti_liner_stretch(image): #s1,s2分别为灰度级上的两个边界,#该分段线性拉伸法,将灰度级分成三分,一份小于最小灰度级,一份大于最大灰度级,这两部分无定义,直接映射中间部分
- # r_min, r_max = 255, 0
- # for i in range(image.shape[0]): #没做灰度变换
- # for j in range(image.shape[1]):
- # for k in range(image.shape[2]):
- # if image[i, j, k] > r_max:
- # r_max = image[i, j, k]
- # if image[i, j, k] < r_min:
- # r_min = image[i, j, k]
- r1, s1 = 50,100
- r2, s2 = 170,200 #这四个值决定了分段函数的走向
- k1 = s1 / r1
- k3 = (255 - s2) / (255 - r2)
- k2 = (s2 - s1) / (r2 - r1)
- precewise_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
- for i in range(image.shape[0]):
- for j in range(image.shape[1]):
- for k in range(image.shape[2]):
- if r1 <= image[i, j, k] <= r2:
- precewise_img[i, j, k] = k2 * (image[i, j, k] - r1)
- elif image[i, j, k] < r1:
- precewise_img[i, j, k] = k1 * image[i, j, k]
- elif image[i, j, k] > r2:
- precewise_img[i, j, k] = k3 * (image[i, j, k] - r2)
- # 原图中做分段线性变化后需要对图像进行归一化操作,并将数据类型转换到np.uint8
- cv.normalize(precewise_img, precewise_img, 0, 255, cv.NORM_MINMAX)
- precewise_img = cv.convertScaleAbs(precewise_img)
- g.msgbox('处理前的图片方差为{one},处理后的方差为{two}'.format(one=myvar(image),two=myvar(precewise_img))) #函数本身没做灰度化,但是求方差时我做了灰度化
- cv.imshow('origin image', imutils.resize(image, 480))
- cv.imshow('muti_liner_stretch image', imutils.resize(precewise_img, 480))
- if cv.waitKey(0) == 27:
- cv.destroyAllWindows()
- def medium_filter(image): #中值滤波模板为3*3
- image = image[:, :, 0] * 0.11 + image[:, :, 1] * 0.59 + image[:, :, 2] * 0.3
- image = image.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- # kernal_size=np.ones((3,3))
- rows=image.shape[0]
- cols = image.shape[1]
- gray_data = image.copy()
- img_new = []
- for i in range(rows-3): #减去3的原因是自己定义的模板都是3*3
- line = [] #line记录着每一行的信息
- for j in range(cols-3):
- a = gray_data[i:i+3,j:j+3] #此时类型a为np.uint8,转化为array类型方便后续计算
- a=np.array(a)
- a=np.sort(a.reshape(-1))
- line.append(a[4]) #np.multiply表示两个矩阵点乘
- img_new.append(line) #记录着每一行卷积后的结果
- image2=np.array(img_new)
- image2 = (image2 / float(image2.max())) * 255
- # 显示图像
- plt.subplot(2,1,1)
- plt.title('original image')
- plt.imshow(image,cmap=cm.gray)
- plt.axis("off")
- plt.subplot(2,1,2)
- plt.title('after medium image')
- plt.imshow(image2,cmap=cm.gray)
- plt.axis("off")
- plt.show()
- def PepperandSalt(image,percentage): # percentage表示噪声点出现的概率 #进来的第一步是灰度化
- # R = np.mat(image[:, :, 0])
- # G = np.mat(image[:, :, 1])
- # B = np.mat(image[:, :, 2])
- # img_gray2 = R * 0.299 + G * 0.587 + B * 0.114
- img_gray2 = image[:, :, 0] * 0.11 + image[:, :, 1] * 0.59 + image[:, :, 2] * 0.3
- img_gray2 = img_gray2.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- NoiseImg=img_gray2
- rows,cols=NoiseImg.shape
- NoiseNum=int(percentage*rows*cols)
- for i in range(NoiseNum):
- randX=np.random.randint(0,rows)
- randY=np.random.randint(0,cols)
- if random.randint(0,1) == 0:
- NoiseImg[randX,randY]=0
- else:
- NoiseImg[randX,randY]=255
- cv.imshow('Peppernoise image', NoiseImg)
- cv.waitKey(1000)
- def GaussianNoise(image,mean,sigma): #mean表示均值,sigma表示方差 #第一步是灰度化
- # R=np.mat(image[:,:,0])
- # G=np.mat(image[:,:,1])
- # B=np.mat(image[:,:,2])
- # img_gray2 = R*0.299+G*0.587+B*0.114
- img_gray2 = image[:, :, 0] * 0.11 + image[:, :, 1] * 0.59 + image[:, :, 2] * 0.3
- img_gray2 = img_gray2.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- NoiseImg=img_gray2
- rows = NoiseImg.shape[0]
- cols = NoiseImg.shape[1]
- rows,cols=NoiseImg.shape
- for i in range(rows):
- for j in range(cols):
- NoiseImg[i,j]=NoiseImg[i,j]+random.gauss(mean,sigma)
- # NoiseImg = NoiseImg+np.random.normal(mean,sigma,NoiseImg.shape)
- # NoiseImg = NoiseImg - np.full( NoiseImg.shape, np.min( NoiseImg)) # 全填充限定像素值下限(减去最小值,下限重新定义为0)
- # NoiseImg = NoiseImg * 255 / np.max( NoiseImg) #限定像素值上限
- if NoiseImg[i,j]<0:
- NoiseImg[i,j] = 0
- elif NoiseImg[i,j]>255:
- NoiseImg[i,j] = 255
- cv.imshow('guasenoise image', NoiseImg)
- cv.waitKey(1000)
- def salt(image1,number): #number表述噪声点数量
- image = image1.copy()
- rows= image.shape[0]
- cols = image.shape[1]
- for i in range(number):
- x=np.random.randint(0,rows) #np.ranom.randint 取不到右边界,ranodm.randint取得到右边界
- y=np.random.randint(0,cols)
- c=random.randint(0,1)
- if c == 1:
- image[x,y] = 255
- else:
- image[x,y] = 0
- return image
- def convolution(kernal_size, image):
- rows=image.shape[0]
- cols = image.shape[1]
- gray_data = image.copy()
- img_new = []
- for i in range(rows-3): #减去3的原因是自己定义的模板都是3*3
- line = [] #line记录着每一行的信息
- for j in range(cols-3):
- a = gray_data[i:i+3,j:j+3]
- a=np.array(a)
- line.append(np.sum(np.multiply(kernal_size, a))) #np.multiply表示两个矩阵点乘
- img_new.append(line) #记录着每一行卷积后的结果
- return np.array(img_new)
- def mean_image(image): #均值滤波 #进来的第一不也是灰度化
- suanzi = np.ones((3,3))/9 # 创建全1算子(1/9)
- # 打开图像并转化成灰度图像
- image = image[:, :, 0] * 0.11 + image[:, :, 1] * 0.59 + image[:, :, 2] * 0.3
- image = image.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- image2 = convolution(image=image,kernal_size=suanzi)
- # 将结果灰度值转化到0-255
- image2 = (image2/float(image2.max()))*255
- image3=cv.blur(image,(5,5))
- # 显示图像
- plt.subplot(3,1,1)
- plt.title('original image')
- plt.imshow(image,cmap=cm.gray)
- plt.axis("off")
- plt.subplot(3,1,2)
- plt.title('after meaning image')
- plt.imshow(image2,cmap=cm.gray)
- plt.axis("off")
- plt.subplot(3, 1, 3)
- plt.title('function made')
- plt.imshow(image3, cmap=cm.gray)
- plt.axis("off")
- plt.show()
- def func(x,y,sigma=1):
- return 100*(1/(2*np.pi*sigma))*np.exp(-((x-1)**2+(y-1)**2)/(2.0*sigma**2)) #创建高斯函数,该函数中心为(1,1),所以创建3*3比较合适
- def gause_image(image): #高斯滤波,第一步也实现了灰度化
- suanzi = np.fromfunction(func,(3,3),sigma=2) # 创建高斯函数,(1,1)为函数的中心,这里是生成3*3的标准差为2的高斯算子
- # 打开图像并转化成灰度图像
- image = image[:, :, 0] * 0.11 + image[:, :, 1] * 0.59 + image[:, :, 2] * 0.3
- image = image.astype(np.uint8) # GRAY=0.3*R+0.59*G+0.11*B:
- image2 = convolution(image=image, kernal_size=suanzi)
- # 将结果灰度值转化到0-255
- image2 = (image2 / float(image2.max())) * 255
- # 显示图像
- plt.subplot(2, 1, 1)
- plt.title('original image')
- plt.imshow(image, cmap=cm.gray)
- plt.axis("off")
- plt.subplot(2, 1, 2)
- plt.title('after gause image')
- plt.imshow(image2, cmap=cm.gray)
- plt.axis("off")
- plt.show()
- if __name__ == '__main__':
- # image1 = cv.imread('D:\\test.jpg') #读取我们的照片
- # # image_salt = salt(image,2000) #加入噪声
- # # mean_image(image_salt)
- # # gause_image(image_salt)
- # GaussianNoise(image1, mean=2, sigma=14)
- # cv.imshow('salt image', PepperandSalt(image1, percentage=0.01))
- msg = "请输入您想要完成的任务(建议您第一步先打开图片)"
- title = '第二次作业'
- choice = ('打开图片', '退出')
- a = g.buttonbox(msg=msg, title=title, choices=choice)
- if a == '打开图片':
- filename = g.fileopenbox(msg="请打开一个jpg文件")
- img = cv.imread(filename)
- msg1 = "选择您想要实现的功能"
- title1 = '第二次作业'
- choice1 = ('显示噪声图', '滤波', '阈值分割', '分段线性法拉伸', '直方图拉伸', '区域生长法分割','重新选择图片','退出')
- q = 1
- while q:
- b = g.buttonbox(msg=msg1, title=title1, choices=choice1)
- # while b!='退出':
- if b == '显示噪声图':
- msg2 = "选择您想要实现的功能"
- title2 = '第二次作业'
- choice2 = ('灰色椒盐噪声图', '灰色高斯噪声图','退出')
- q1=1
- while q1:
- noise_image_choice = g.buttonbox(msg=msg2, title=title2, choices=choice2)
- if noise_image_choice == '灰色椒盐噪声图':
- PepperandSalt(img, percentage=0.01) #这里设置椒盐噪声点出现的概率为0.01
- elif noise_image_choice == '灰色高斯噪声图':
- GaussianNoise(img, mean=2, sigma=14) #这里设置均值为2,方差为4
- else:
- q1 =0
- elif b == '滤波':
- msg_b = "选择您想要实现的功能"
- title_b = '第二次作业'
- choice_b = ('均值滤波', '高斯滤波','中值滤波')
- q_b = 1
- while q_b:
- b_remove_noise = g.buttonbox(msg=msg_b, title=title_b, choices=choice_b)
- if b_remove_noise == '均值滤波':
- mean_image(salt(img,number=5000)) #salt为自己定义的可以随意增加噪声点的函数,number为自己定义噪声点的数量
- elif b_remove_noise =='高斯滤波':
- gause_image(salt(img,number=5000))
- elif b_remove_noise == '中值滤波':
- medium_filter(salt(img,number=5000))
- else:
- q_b = 0
- elif b == '阈值分割':
- msg_b1 = "选择您想要实现的功能"
- title_b1 = '第二次作业'
- choice_b1 = ('固定阈值', '调节参数窗')
- q_b1 = 1
- while q_b1:
- b_remove_noise1 = g.buttonbox(msg=msg_b1, title=title_b1, choices=choice_b1)
- if b_remove_noise1 == '固定阈值':
- static_number(img)
- elif b_remove_noise1 == '调节参数窗':
- change_number(img)
- else:
- q_b1 = 0
- elif b == '分段线性法拉伸':
- muti_liner_stretch(img)
- elif b == '直方图拉伸':
- hist_stretch(img)
- elif b == '区域生长法分割':
- seed_growing(img)
- elif b == '重新选择图片':
- filename = g.fileopenbox(msg="请打开一个jpg文件")
- img = cv.imread(filename)
- else:
- q = 0
复制代码 |
|