You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

429 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from cv2 import Laplacian
import numpy as np
import cv2
import math
### 计算处理
# 逻辑与
def and_operation(path1,path2):
X=cv2.imread(path1,0)
Y=cv2.imread(path2,0)
result=X&Y
print(np.sum(result))
return result
# 逻辑或
def or_operation(path1,path2):
X=cv2.imread(path1,0)
Y=cv2.imread(path2,0)
result=X|Y
print(np.sum(result))
return result
# 逻辑非
def not_operation(path1):
X=cv2.imread(path1,0)
result=~X
print(np.sum(result))
return result
# 加法运算
def ope_add(path1,path2):
X=cv2.imread(path1,0)
Y=cv2.imread(path2,0)
result = cv2.add(X,Y)
print(np.sum(result))
return result
# 减法运算
def ope_subtract(path1,path2):
X=cv2.imread(path1,0)
Y=cv2.imread(path2,0)
result = cv2.subtract(X,Y)
print(np.sum(result))
return result
# 乘法运算
def ope_multiply(path1,path2):
X=cv2.imread(path1,0)
Y=cv2.imread(path2,0)
result = cv2.multiply(X,Y)
print(np.sum(result))
return result
# 除法运算
def ope_divide(path1,path2):
X=cv2.imread(path1,0)
Y=cv2.imread(path2,0)
result = cv2.divide(X,Y)
print(np.sum(result))
return result
### 几何变换
# 翻转
def Flip(path1):
src=cv2.imread(path1,1)
#水平镜像
horizontal=cv2.flip(src,1)
#垂直镜像
vertical=cv2.flip(src,0)
#对角镜像 ,并保存
cross=cv2.flip(src,-1)
return cross
# 仿射变换
def affine_trans(path1):
# 获取图像shape
src=cv2.imread(path1,1)
rows, cols = src.shape[: 2]
post1=np.float32([[50,50],[200,50],[50,200]])
post2=np.float32([[10,100],[200,50],[100,250]])
M=cv2.getAffineTransform(post1,post2)
result = cv2.warpAffine(src,M,(rows,cols))
return result
### 形态学
# 腐蚀
def erosion(path):
src = cv2.imread(path, cv2.IMREAD_UNCHANGED)
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
erosion=cv2.erode(src,kernel)
return erosion
# 膨胀
def dilation(path):
src = cv2.imread(path, cv2.IMREAD_UNCHANGED)
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
dilation=cv2.dilate(src,kernel)
return dilation
# 开运算
def morph_open(path):
src = cv2.imread(path, cv2.IMREAD_UNCHANGED)
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
open = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)
return open
# 闭运算
def morph_close(path):
src = cv2.imread(path, cv2.IMREAD_UNCHANGED)
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(10,10),(-1,-1))
dilation=cv2.dilate(src,kernel)
close=cv2.erode(dilation,kernel)
return close
### 图像增强
## 空域平滑
# 邻域平均法
def neighbor_aver(path):
img=cv2.imread(path,1)
result=cv2.blur(img,(5,5))
return result
#中值滤波法
def median_filter(path):
img=cv2.imread(path,1)
result=cv2.medianBlur(img,5)
return result
## 空域锐化
# Roberts梯度算子
def roberts(path):
img=cv2.imread(path,0)
height,width=img.shape[:2]
result = np.zeros((height,width))
for i in range(1,height-1):
for j in range (1,width-1):
result[i][j]=np.abs(img[i][j]-img[i+1][j+1])+np.abs(img[i+1][j]-img[i][j+1])
return result
## 频域平滑
# 理想低通滤波器
def lowpass_filter(path):
img=cv2.imread(path,0)
src=np.fft.fft2(img)
src_shift=np.fft.fftshift(src)
#src_trans=20*np.log(np.abs(src_c))
height,width=img.shape[:2]
u=np.floor(height/2)
v=np.floor(width/2)
img_trans=np.zeros((height,width))
d0=90
for i in range(height):
for j in range(width):
d = np.sqrt((i-u)**2 + (j-v)**2)
if d<=d0:
img_trans[i][j]=1
#iimg_trans=src_c*img_trans
iimg_trans=np.multiply(src_shift,img_trans)
iimg_shift=np.fft.ifftshift(iimg_trans)
iimg=np.fft.ifft2(iimg_shift)
img_back=np.abs(iimg)
#img_back=np.real(iimg)
img_back=(img_back-np.amin(img_back))/(np.amax(img_back)-np.amin(img_back))
return img_back
#巴特沃斯低通滤波器
def butterworth_low_filter(path):
img=cv2.imread(path,0)
src=np.fft.fft2(img)
src_shift=np.fft.fftshift(src)
#src_trans=20*np.log(np.abs(src_c))
height,width=img.shape[:2]
u=np.floor(height/2)
v=np.floor(width/2)
img_trans=np.zeros((height,width))
d0=90
rank=2
for i in range(height):
for j in range(width):
d = np.sqrt((i-u)**2 + (j-v)**2)
img_trans[i][j]=1/(1+0.414*(d/d0)**(2*rank))
#iimg_trans=src_c*img_trans
iimg_trans=np.multiply(src_shift,img_trans)
iimg_shift=np.fft.ifftshift(iimg_trans)
iimg=np.fft.ifft2(iimg_shift)
img_back=np.abs(iimg)
#img_back=np.real(iimg)
img_back=(img_back-np.amin(img_back))/(np.amax(img_back)-np.amin(img_back))
return img_back
## 频域锐化
# 理想高通滤波器
def highpass_filter(path):
img=cv2.imread(path,0)
src=np.fft.fft2(img)
src_shift=np.fft.fftshift(src)
#src_trans=20*np.log(np.abs(src_c))
height,width=img.shape[:2]
u=np.floor(height/2)
v=np.floor(width/2)
img_trans=np.zeros((height,width))
d0=90
for i in range(height):
for j in range(width):
d = np.sqrt((i-u)**2 + (j-v)**2)
if d>d0:
img_trans[i][j]=1
#iimg_trans=src_c*img_trans
iimg_trans=np.multiply(src_shift,img_trans)
iimg_shift=np.fft.ifftshift(iimg_trans)
iimg=np.fft.ifft2(iimg_shift)
img_back=np.abs(iimg)
#img_back=np.real(iimg)
img_back=(img_back-np.amin(img_back))/(np.amax(img_back)-np.amin(img_back))
return img_back
#巴特沃斯高通滤波器
def butterworth_high_filter(path):
img=cv2.imread(path,0)
src=np.fft.fft2(img)
src_shift=np.fft.fftshift(src)
#src_trans=20*np.log(np.abs(src_c))
height,width=img.shape[:2]
u=np.floor(height/2)
v=np.floor(width/2)
img_trans=np.zeros((height,width))
d0=90
rank=2
for i in range(height):
for j in range(width):
d = np.sqrt((i-u)**2 + (j-v)**2)
img_trans[i][j]=1/(1+0.414*(d0/d)**(2*rank))
#iimg_trans=src_c*img_trans
iimg_trans=np.multiply(src_shift,img_trans)
iimg_shift=np.fft.ifftshift(iimg_trans)
iimg=np.fft.ifft2(iimg_shift)
img_back=np.abs(iimg)
#img_back=np.real(iimg)
img_back=(img_back-np.amin(img_back))/(np.amax(img_back)-np.amin(img_back))
return img_back
### 边缘检测
# Roberts算子
def robs(path):
img = cv2.imread(path,0)
# 2. Roberts算子
kernelx=np.array([[-1,0],[0,1]],dtype=int)
kernely=np.array([[0,-1],[1,0]],dtype=int)
# 3. 卷积操作
x=cv2.filter2D(img,cv2.CV_16S,kernelx)
y=cv2.filter2D(img,cv2.CV_16S,kernely)
# 4. 数据格式转换
absX=cv2.convertScaleAbs(x)
absY=cv2.convertScaleAbs(y)
Roberts=cv2.addWeighted(absX,0.5,absY,0.5,0)
return Roberts
#Sobel算子
def sob(path):
img = cv2.imread(path,0)
# 2. Roberts算子
kernelx=cv2.Sobel(img,cv2.CV_16S,1,0)
kernely=cv2.Sobel(img,cv2.CV_16S,0,1)
# 3. 卷积操作
x=cv2.filter2D(img,cv2.CV_16S,kernelx)
y=cv2.filter2D(img,cv2.CV_16S,kernely)
# 4. 数据格式转换
absX=cv2.convertScaleAbs(x)
absY=cv2.convertScaleAbs(y)
Sobel=cv2.addWeighted(absX,0.5,absY,0.5,0)
return Sobel
#Laplacian算子
def lap(path):
# 1.读取图像
img = cv2.imread(path,0)
# 2. 高斯滤波
img=cv2.GaussianBlur(img,(5,5),0,0)
# 3. 拉普拉斯算法
dst=cv2.Laplacian(img,cv2.CV_16S,ksize=3)
# 4. 数据格式转换
Laplacian=cv2.convertScaleAbs(dst)
return Laplacian
#LoG边缘算子
def log(path):
# 1.读取图像
img = cv2.imread(path,0)
# 2. 边缘扩充处理图像并使用高斯滤波处理该图像
image=cv2.copyMakeBorder(img,2,2,2,2,borderType=cv2.BORDER_REPLICATE)
image=cv2.GaussianBlur(image,(3,3),0,0)
# 3. 使用Numpy定义LoG算子
m1=np.array([[0,0,-1,0,0],[0,-1,-2,-1,0],[-1,-2,16,-2,-1],[0,-1,-2,-1,0],[0,0,-1,0,0]])
# 4. 卷积运算
# 为了使卷积对每个像素都进行运算,原图像的边缘像素要对准模板的中心。
# 由于图像边缘扩大了2像素因此要从位置2到行(列)-2
image1=np.zeros(image.shape)
rows=image.shape[0]
cols=image.shape[1]
for i in range(2,rows-2):
for j in range(2,cols-2):
image1[i,j]=np.sum(m1*image[i-2:i+3,j-2:j+3])
# 5. 数据格式转换
image1=cv2.convertScaleAbs(image1)
return image1
### 图像噪声
# 噪声描述器
def noise_desc(path):
image = cv2.imread(path,0)
output = np.zeros(image.shape, np.uint8)
# 遍历图像,获取叠加噪声后的图像
for i in range(image.shape[0]):
for j in range(image.shape[1]):
if image[i][j]<100:
# 添加食盐噪声
output[i][j]=255
elif image[i][j]>200:
# 添加胡椒噪声
output[i][j]=0
else:
# 不添加噪声
output[i][j]=image[i][j]
print(np.sum(output))
return output
# 均值类滤波器
def aver_filter(path):
image = cv2.imread(path,0)
output = np.zeros(image.shape, np.uint8)
# 遍历图像,进行均值滤波
for i in range(image.shape[0]):
for j in range(image.shape[1]):
# 计算均值,完成对图片src的几何均值滤波
ji = 1.0
for n in range(-1,2):
# 防止越界
if 0 <= j + n < image.shape[1]:
ji *= image[i][j + n]
output[i][j] = int(math.pow(ji,1/3))
# 滤波器的大小为1*3
######### End #########
# 展示均值滤波后的图片
return output
#排序统计类滤波器
def sort_filter(path):
image = cv2.imread(path,0)
# 待输出的图片
output = np.zeros(image.shape, np.uint8)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
# 最大值滤波器
max=0
for m in range(-1, 2):
for n in range(-1, 2):
# 防止越界
if 0 <= i + m < image.shape[0] and 0 <= j + n < image.shape[1]:
if max<image[i+m][j+n]:
max=image[i+m][j+n]
# 更新最大值
output[i][j]=max
return output
#选择性滤波器
def opt_filter(path):
image = cv2.imread(path,0)
output = np.zeros(image.shape, np.uint8)
max=200
for i in range(image.shape[0]):
for j in range(image.shape[1]):
if image[i][j] <= max:
output[i][j] = 0
else:
output[i][j] = image[i][j]
return output
### 图像进阶
# 线条变化检测
def line_change(path):
img = cv2.imread(path)
img = cv2.GaussianBlur(img, (3, 3), 0)
edges = cv2.Canny(img, 50, 150, apertureSize=3)
# 使用HoughLines算法
# rho为1
# theta为np.pi/2
# threshold为 118
# 其他的默认
######### Begin #########
lines = cv2.HoughLines(edges, 1, np.pi/2, 118)
######### end ##########
result = img.copy()
for i_line in lines:
for line in i_line:
rho = line[0]
theta = line[1]
if (theta < (np.pi / 4.)) or (theta > (3. * np.pi / 4.0)): # 垂直直线
pt1 = (int(rho / np.cos(theta)), 0)
pt2 = (int((rho - result.shape[0] * np.sin(theta)) / np.cos(theta)), result.shape[0])
cv2.line(result, pt1, pt2, (0, 0, 255))
else:
pt1 = (0, int(rho / np.sin(theta)))
pt2 = (result.shape[1], int((rho - result.shape[1] * np.cos(theta)) / np.sin(theta)))
cv2.line(result, pt1, pt2, (0, 0, 255), 1)
minLineLength = 200
maxLineGap = 15
# 使用HoughLinesP算法
# rho为1
# theta为np.pi/2
# threshold为 118
# 并设置上面提供的minLineLength和maxLineGap
# 其他的默认
######### Begin #########
linesP = cv2.HoughLinesP(edges, 1, np.pi / 180, 80, minLineLength, maxLineGap)
######### end ##########
result_P = img.copy()
for i_P in linesP:
for x1, y1, x2, y2 in i_P:
cv2.line(result_P, (x1, y1), (x2, y2), (0, 255, 0), 3)
return result_P