forked from iwater2018/badou-ai-special-2024
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3bb21c9
commit ac4f414
Showing
10 changed files
with
424 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() # #销毁全部窗口 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Oops, something went wrong.