Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyibadou authored Apr 23, 2024
1 parent 3bb21c9 commit ac4f414
Show file tree
Hide file tree
Showing 10 changed files with 424 additions and 0 deletions.
79 changes: 79 additions & 0 deletions 226+陈易+武汉/01.灰度化_二值化_最临近插值法.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import cv2
import numpy as np
from skimage.color import rgb2gray
import matplotlib.pyplot as plt
from PIL import Image

"""
灰度化:将RGB转为Gray
浮点算法:Gray = R0.3 + G0.59 +B0.11
整数算法:Gray = (R30 + G59 + B11)/100
移位方法:Gray = (R76 + G151 + B*28)>>8
平均值法:Gray = (R + G + B)/3
仅取绿色:Gray = G
"""
# 灰度化 ①
img = cv2.imread("lenna.png") # cv2.imread()接口读图像,读进来直接是BGR 格式数据格式在 0~255
h,w = img.shape[:2] # 获取图片的high和wide
print("h:",h)
print("w:",w)
img_gray = np.zeros([h,w],img.dtype) # 创建一张与原图片大小一样的单通道图片,img.dtype获取图像数据类型
# 获取每行每列各个点的RGB值 到 m
for i in range(h):
for j in range(w):
m = img[i,j] # 将img图片第i行,第j列的RGB值赋值到m
img_gray[i,j] = int(m[0]*0.11 + m[1]*0.59 + m[2]*0.3) # 计算每个像素点的灰度值。!!!注意这里计算的顺序为 BGR
# print("第",i,"行,第",j,"列的灰度值为",img_gray)
print("m",m)
print("img_gray",img_gray)
cv2.imshow("image show gray",img_gray) # 固定写法
cv2.waitKey(3000) # 因闪退而添加的一行。 cv2.waitKey()参数是指等待的时间,默认单位为ms,为0时表示无限长时间

# 灰度化 ②
plt.subplot(221) # 表示将整个图像窗口分为2行2列, 当前位置为1
img2 = plt.imread("lenna.png")
plt.imshow(img2) # 展示原图
print("img2:",img2)
# plt.show() # 因闪退而添加的一行。

img_gray2 = rgb2gray(img2) # 将真彩色图像 RGB 转换为灰度图像
plt.subplot(222) # 表示将整个图像窗口分为2行2列, 当前位置为2
plt.imshow(img_gray2, cmap='gray') # 展示转换后的图,imshow固定写法
print("---image gray2----")
print(img_gray2)
# plt.show() # 因闪退而添加的一行。
""" 说明
cv2.cvtColor(p1,p2) 是颜色空间转换函数,p1是需要转换的图片,p2是转换成何种格式。
cv2.COLOR_BGR2RGB 将BGR格式转换成RGB格式
cv2.COLOR_BGR2GRAY 将BGR格式转换成灰度图片
"""
# 二值化 只有两个值
img_two = np.where(img_gray2 >= 0.5,1,0) # where(条件,符合条件得到的结果,不符合条件得到的结果)
print("img_two:",img_two) # 查看转换后的结果
print(img_two.shape) # 查看行数和列数

plt.subplot(223) # 表示将整个图像窗口分为2行2列, 当前位置为3
plt.imshow(img_two,cmap="gray") # 展示二值化的结果,imshow固定写法
plt.show()


def chazhi(image):
h,w,channels = image.shape # 获取长宽和通道
emptyImage = np.zeros((800,800,channels),np.uint8) #创建1000×1000的图,与image通道一致
Nh = 800/h # 倍率
Nw = 800/w # 倍率
for i in range(800):
for j in range(800):
x = int(i/Nh + 0.5) # int 向下取整
y = int(j/Nw + 0.5)
emptyImage[i,j] = image[x,y]
return emptyImage

image = cv2.imread("lenna.png")
zoom = chazhi(image) # 调用函数,将执行的结果返回到zoom变量中
print("zoom",zoom)
print("zoom.shape",zoom.shape)
cv2.imshow("nearest interp",zoom) # cv2.imshow固定写法
cv2.imshow("image",image) # cv2.imshow固定写法
cv2.waitKey(0)
40 changes: 40 additions & 0 deletions 226+陈易+武汉/02.双线性插值.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import numpy as np
import cv2

"""
双线性插值法
"""

img = cv2.imread("lenna.png")
def bilinear_interpolation(img,out_img): #bilinear_interpolation 双线性插值
src_h,src_w,channel = img.shape # 获取原图片数据
dst_h,dst_w = out_img[1],out_img[0] # 目标图片的 高和宽
print("src_h,src_w原图的行高和宽:",src_h,src_w) # 打印原图高和宽
print("dst_h,dsr_w目标图的行高和宽:",dst_h,dst_w) # 打印目标图高和宽
if src_h == dst_h and src_w == dst_w: # 如果原图和目标图高和宽一致
return img.copy()
dst_img = np.zeros((dst_h,dst_w,3),dtype=np.uint8) # 创建目标图片
scale_x,scale_y = float(src_w) / dst_w,float(src_h) / dst_h # 计算缩放比例
for i in range(channel):
for dst_y in range(dst_h):
for dst_x in range(dst_w):
# 目标q图x,y在原图中的位置(中心点重合),src_x,src_y是目标图在原图中对应的点
src_x = (dst_x + 0.5) * scale_x - 0.5
src_y = (dst_y + 0.5) * scale_y - 0.5
# 找src_x,src_y 周边四个像素点的x0,x1,y0,y1
src_x0 = int(np.floor(src_x)) # np.floor()返回不大于输入参数的最大整数。(向下取整)
src_x1 = min(src_x0 + 1 ,src_w - 1) # x1是x0右边的像素点,min限制x1的范围
src_y0 = int(np.floor(src_y))
src_y1 = min(src_y0 + 1 ,src_h -1) # y1是y0下边的像素点,min限制y1的范围
# 先做两个src_x,src_y x坐标方向的插值
temp0 = (src_x1 - src_x) * img[src_y0,src_x0,i] + (src_x - src_x0) * img[src_y0,src_x1,i]
temp1 = (src_x1 - src_x) * img[src_y1,src_x0,i] + (src_x - src_x0) * img[src_y1,src_x1,i]
# 在做src_x,src_y y坐标方向的插值,得到src_x,src_y的像素值,赋值给目标图
dst_img[dst_y,dst_x,i] = int((src_y1 - src_y) * temp0 + (src_y -src_y0) * temp1)
return dst_img

if __name__ == "__main__": # 主函数入口,被引用时,下面的代码不被运行
img = cv2.imread("lenna.png")
dst = bilinear_interpolation(img,(700,700)) # bilinear_interpolation 双线性插值
cv2.imshow("bilinear_interpolation双线性插值:",dst)
cv2.waitKey()
41 changes: 41 additions & 0 deletions 226+陈易+武汉/03.直方图均衡化.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# encoding=UTF-8

import cv2
from matplotlib import pyplot as plt
import numpy as np

# 获取灰度图片
img = cv2.imread("lenna.png",1)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 变换为单通道
cv2.imshow("gray",gray)
cv2.waitKey()
# 灰度图像直方图均衡化
dst = cv2.equalizeHist(gray) # GBK 报错SyntaxError: encoding problem: gbk

# 直方图,cv2.calcHist()函数统计图像直方图信息
hist = cv2.calcHist([dst],[0],None,[256],[0,256])
plt.figure() # 创建一个图像
plt.hist(dst.ravel(),256) # plt.hist()绘制直方图,src.ravel()可以将二维图像拉平为一维数组
# plt.show() # 闪退。以下是解决方案
plt.ion() # 显示直方图
plt.pause(15) # 显示秒数
plt.close()
# 对比均衡化前后图片
# np.vstack():在竖直方向上堆叠 np.hstack():在水平方向上平铺
cv2.imshow("Histogram Equalization",np.hstack([gray,dst]))
cv2.waitKey(0)

# 彩色图直方图均衡化
img = cv2.imread("lenna.png",1) # 获取图片
cv2.imshow("src",img)
cv2.waitKey()
# 彩色图像均衡化,需要分解通道 对每一个通道均衡化
(b,g,r) = cv2.split(img) # 对图像进行拆分
# 分别均衡化 B G R
bh = cv2.equalizeHist(b)
gh = cv2.equalizeHist(g)
rh = cv2.equalizeHist(r)
# 合并每一个通道
result = cv2.merge((bh,gh,rh))
cv2.imshow("均衡化合并后的图",result)
cv2.waitKey()
34 changes: 34 additions & 0 deletions 226+陈易+武汉/04.sobel边缘检查.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import cv2
import numpy as np

img = cv2.imread("lenna.png",0) # 读取图片

'''
Sobel函数求完导数后会有负值,还有会大于255的值。
而原图像是uint8,即8位无符号数(范围在[0,255]),所以Sobel建立的图像位数不够,会有截断。
因此要使用16位有符号的数据类型,即cv2.CV_16S。
'''
x = cv2.Sobel(img,cv2.CV_16S, 1,0) # 1,0表示横向
y = cv2.Sobel(img,cv2.CV_16S, 0,1) # 0,1表示纵向

'''
在经过处理后,别忘了用convertScaleAbs()函数将其转回原来的uint8形式。
否则将无法显示图像,而只是一副灰色的窗口。
dst = cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])
其中可选参数alpha是伸缩系数,beta是加到结果上的一个值。结果返回uint8类型的图片。
'''
absx = cv2.convertScaleAbs(x)
absy = cv2.convertScaleAbs(y)

'''
由于Sobel算子是在两个方向计算的,最后还需要用cv2.addWeighted(...)函数将其组合起来
。其函数原型为:
dst = cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
其中alpha是第一幅图片中元素的权重,beta是第二个的权重, (与上面的alpha和beta不是一个东西)
gamma是加到最后结果上的一个值。
'''
dst = cv2.addWeighted(absx,0.5,absy,0.5,0)
cv2.imshow("absx",absx)
cv2.imshow("absy",absy)
cv2.imshow("dst",dst)
cv2.waitKey()
29 changes: 29 additions & 0 deletions 226+陈易+武汉/05.高斯噪声.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import cv2
import random

def GaussNoise(src,means,sigma,percetage):
NoiseImg = src # 拿到要处理的图片
NoiseNum = int(percetage * src.shape[0] * src.shape[1]) # 计算要处理的像素点数
for i in range(NoiseNum):
# 每次取一个随机点
# 把一张图片的像素用行和列表示的话,randX代表随机生成的行,ranY代表随机生成的列
# 高斯噪声图片边缘不处理,故-1
# random.randint()生成随机整数
randX = random.randint(0,src.shape[0]-1)
randY = random.randint(0,src.shape[1]-1)
# 在原像素值灰度值上加价随机数
NoiseImg[randX,randY] = NoiseImg[randX,randY] + random.gauss(means,sigma)
# 如果灰度值小于0则强制为0,如果灰度值大于255则强制为255
if NoiseImg[randX,randY] < 0:
NoiseImg[randX,randY] = 0
elif NoiseImg[randX,randY] > 255:
NoiseImg[randX,randY] = 255
return NoiseImg
img = cv2.imread("lenna.png",0)
img_guass = GaussNoise(img,2,4,0.8) # 高斯噪声图
img = cv2.imread('lenna.png') # 原图
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图
cv2.imshow("img",img)
cv2.imshow("img_guass",img_guass)
cv2.imshow("img2",img2)
cv2.waitKey()
25 changes: 25 additions & 0 deletions 226+陈易+武汉/06.椒盐噪声.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import cv2
import random

def JiaoYanNoise(src,percetage):
NoiseImg = src # 拿到要处理的图片
NoiseNum = int(percetage * src.shape[0] * src.shape[1]) # 计算要处理的像素点数
for i in range(NoiseNum):
# 每次取一个随机点
# 把一张图片的像素用行和列表示的话,randX代表随机生成的行,ranY代表随机生成的列
# random.random()生成随机浮点数
randX = random.randint(0,src.shape[0]-1)
randY = random.randint(0,src.shape[1]-1)
# 随机取到一个像素,一般几率为0,一般几率为255
if random.random() <= 0.5:
NoiseImg[randX,randY] = 0
else :
NoiseImg[randX,randY] = 255
return NoiseImg

img = cv2.imread("lenna.png",1) # 原图的灰度图 0是灰度,1是彩色
img_JiaoYan = JiaoYanNoise(img,0.2) # 椒盐噪声图
# img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图
cv2.imshow("img",img)
cv2.imshow("JiaoYanNoise",img_JiaoYan)
cv2.waitKey()
40 changes: 40 additions & 0 deletions 226+陈易+武汉/07.噪声函数合集.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import cv2 as cv
import numpy as np
from PIL import Image
from skimage import util

'''
def random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs):
功能:为浮点型图片添加各种随机噪声
参数:
image:输入图片(将会被转换成浮点型),ndarray型
mode: 可选择,str型,表示要添加的噪声类型
gaussian:高斯噪声
localvar:高斯分布的加性噪声,在“图像”的每个点处具有指定的局部方差。
poisson:泊松噪声
salt:盐噪声,随机将像素值变成1
pepper:椒噪声,随机将像素值变成0或-1,取决于矩阵的值是否带符号
s&p:椒盐噪声
speckle:均匀噪声(均值mean方差variance),out=image+n*image
seed: 可选的,int型,如果选择的话,在生成噪声前会先设置随机种子以避免伪随机
clip: 可选的,bool型,如果是True,在添加均值,泊松以及高斯噪声后,会将图片的数据裁剪到合适范围内。如果是False,则输出矩阵的值可能会超出[-1,1]
mean: 可选的,float型,高斯噪声和均值噪声中的mean参数,默认值=0
var: 可选的,float型,高斯噪声和均值噪声中的方差,默认值=0.01(注:不是标准差)
local_vars:可选的,ndarry型,用于定义每个像素点的局部方差,在localvar中使用
amount: 可选的,float型,是椒盐噪声所占比例,默认值=0.05
salt_vs_pepper:可选的,float型,椒盐噪声中椒盐比例,值越大表示盐噪声越多,默认值=0.5,即椒盐等量
--------
返回值:ndarry型,且值在[0,1]或者[-1,1]之间,取决于是否是有符号数
'''

img = cv.imread("lenna.png") # 原图
noise_gs_img=util.random_noise(img,mode='gaussian') # 高斯噪声图 util.random_noise(img,mode='gaussian',mean=0, var=0.01)
noise_gs_img1=util.random_noise(img,mode='poisson') # 泊松噪声图
noise_gs_img2=util.random_noise(img,mode='s&p') # 椒盐噪声图
cv.imshow("img", img)
cv.imshow("gauss",noise_gs_img)
cv.imshow("poisson",noise_gs_img1)
cv.imshow("s&p",noise_gs_img2)
#cv.imwrite('lenna_noise.png',noise_gs_img)
cv.waitKey(0)
cv.destroyAllWindows() # #销毁全部窗口
82 changes: 82 additions & 0 deletions 226+陈易+武汉/08.PCA_numpy_detail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# -*- coding:utf-8 -*-
# import numpy as np
"""
实用PCA求样本矩阵X的K介降维矩阵Z
"""
import numpy as np
class CPCA(object):
"""
用PCA求样本矩阵X的K介降维矩阵Z
Note:请保证输入的样本矩阵X shape=(m,n),m 行样例,n个特征
"""
def __init__(self, X, K):
"""
:param X: 样本矩阵X
:param K: X的降维矩阵的阶数,即X要特征降维成K阶
"""
self.X = X # 样本矩阵
self.K = K # K阶降维矩阵的K值
self.centrX = [] # 矩阵X的中心化
self.C = [] # 样本集的协方差矩阵C
self.U = [] # 样本矩阵X的降维转置矩阵
self.Z = [] # 样本矩阵X的降维矩阵Z
# 开始计算
self.centrX = self._centralized() # 中心化,调用中心化函数
self.C = self._cov() # 求协方差矩阵
self.U = self._U() # 求样本矩阵X的降维转置矩阵
self.Z = self._Z() # Z = X * U
def _centralized(self):
"""矩阵X的中心化"""
print("样本矩阵X:\n",self.X)
centrX = []
# 计算特征均值。 np.array:可以从python列表创建数组 np.mean:用于计算数组中元素的平均值
mean = np.array([np.mean(attr) for attr in self.X.T]) # 样本集的特征均值
print("样本集的特征均值:\n",mean)
centrX = self.X - mean # 样本集的中心化。样本数值 - 特征均值
print("样本矩阵X的中心化centrX:\n",centrX)
return centrX

def _cov(self):
"""求样本矩阵X的协方差矩阵C"""
# 样本集的样例总数 shape函数的功能是读取矩阵的长度,比如shape[0]就是读取矩阵第0维度的长度,相当于行数,是图片的高度
#shape[1]就是读取矩阵第1维度的长度,相当于列数,是图片的宽度
ns = np.shape(self.centrX)[0]
# 样本矩阵的协方差矩阵C
C = np.dot(self.centrX.T, self.centrX) / (ns - 1) # dot求两个向量的积, ns -1为无偏估计
print("样本矩阵X的协方差矩阵为C:",C)
return C

def _U(self):
"""求X的降维转置矩阵U,shape(n,k) n是X的特征维度总数 k是降维矩阵的特征维度"""
a,b = np.linalg.eig(self.C) # 特征值赋值给a,对应特征向量赋值给b。
print("样本集的协方差矩阵C的特征值:\n",a)
print("样本集的协方差矩阵C的特征向量:\n",b)
# 给出特征值降序的topK 的索引序列
ind = np.argsort(-1 * a)
# 构件K阶降维的降维转置矩阵U
UT = [b[:, ind[i]] for i in range(self.K)]
U = np.transpose(UT)
print("%d阶降维转换矩阵U:\n" %self.K,U) # 为什么要转置
return U

def _Z(self):
"""按照Z=XU求降维矩阵Z"""
Z = np.dot(self.X, self.U)
print("样本矩阵X的降维矩阵Z:\n",Z)
return Z

if __name__ == '__main__':
'10样本3特征的样本集, 行为样例,列为特征维度'
X = np.array([[10, 15, 29],
[15, 46, 13],
[23, 21, 30],
[11, 9, 35],
[42, 45, 11],
[9, 48, 5],
[11, 21, 14],
[8, 5, 15],
[11, 12, 21],
[21, 20, 25]])
K = np.shape(X)[1] - 1
print('样本集(10行3列,10个样例,每个样例3个特征):\n', X)
pca = CPCA(X,K)
Loading

0 comments on commit ac4f414

Please sign in to comment.