*************彩色图像的直方图均衡化*****************
知识补充:
直方图均衡化只能对单通道图像矩阵进行处理
RGB彩色图像需首相分解成三个R,G,B的单通道矩阵,然后再分别对每个通道进行直方图均衡化,然后再将这三个处理后的通道合并为三通道图像矩阵
YUV通道图像的均衡化
思路:
引入opencv
引入numpy
读取图片
将RGB图像分解为R,G,B三个单通道的矩阵
调用API完成灰度图像的直方图均衡化
将R,G,B三个单通道合并为一个RGB三通道图像矩阵
显示处理后的图像
暂停
引入opencv
引入numpy
读取图片
将图像转化为YUV图像
将YUV图像分解为Y,U,V三个单通道的矩阵
调用API完成灰度图像的直方图均衡化
将Y,U,V三个单通道合并为一个YUV三通道图像矩阵
将YUV图像再转化为RGB图像
显示处理后的图像
暂停
代码实现:
import cv2
import numpy as np
img=cv2.imread('a.jpg',1)
cv2.imshow('img',img)
(b,g,r)=cv2.split(img)#将RGB图像分解为R,G,B三个单通道的矩阵
bH=cv2.equalizeHist(b)
gH=cv2.equalizeHist(g)
rH=cv2.equalizeHist(r)
result=cv2.merge((bH,gH,rH))#将R,G,B三个单通道合并为一个RGB三通道图像矩阵
cv2.imshow('dst',result)
cv2.waitKey(0)
import cv2
import numpy as np
img=cv2.imread('a.jpg',1)
cv2.imshow('img',img)
imgYUV=cv2.cvtColor(img,cv2.COLOR_BGR2YCrCb)
channelYUV=cv2.split(imgYUV)#将YUV图像分解为Y,U,V三个单通道的矩阵
channelYUV[0]=cv2.equalizeHist(channelYUV[0])
channels=cv2.merge(channelYUV)#将Y,U,V三个单通道合并为一个YUV三通道图像矩阵
reuslt=cv2.cvtColor(channels,cv2.COLOR_YCrCb2BGR)#将YUV图像再转化为RGB图像
cv2.imshow('dst',result)
cv2.waitKey(0)
**************图像的修补*************************
知识补充:
找一张有损坏的图像
或生成一张有损坏的图像
思路:
引入opencv
引入numpy
读取图片
修改像素值,制造坏图
保存坏图
显示坏图
暂停
引入opencv
引入numpy
读取坏图
获取图像信息
根据图像信息生成maks蒙板
调用API修复图像
显示修复后的图像
暂停
代码实现:
import cv2
import numpy as np
img=cv2.imread('a.jpg',1)
for i in range(200,300):
img[i,200]=(255,255,255)
img[i,200+1]=(255,255,255)
img[i,200+1]=(255,255,255)
for i in range(150,250):
img[250,i]=(255,255,255)
img[250+1,i]=(255,255,255)
img[250-1,i]=(255,255,255)
cv2.imwrite('ad.jpg',img)
cv2.imshow('d',img)
cv2.waitKey(0)
import cv2
import numpy as np
img=cv2.imread('ad.jpg',1)
imgInfo=img.shape
height=imgInfo[0]
width=imgInfo[1]
paint=np.zeros((height,width,1),np.uint8)
for i in range(200,300):
paint[i,200]=255
paint[i,200+1]=255
paint[i,200+1]=255
for i in range(150,250):
paint[250,i]=255
paint[250+1,i]=255
paint[250-1,i]=255
cv2.imshow('paint',paint)
imgDst=cv2.inpaint(img,paint,3,cv2.INPAINT_TELEA)#调用API修复图片
cv2.imshow('dst',imgDst)
cv2.waitKey(0)
************灰度图像直方图源码************
知识补充:
直方图是为了统计图像中每个像素灰度值出现的概率
横坐标 0-255
纵坐标 出现的概率p
思路:
引入 opencv
引入 numpy
引入 matplotlib
读取图像
获得图像信息
对图像进行灰度化
初始化概率数组
统计图片所有像素值的概率
定义x,y轴
绘制直方图(可以用opecv的绘图方法,也可以用matplot的绘图方法)
显示直方图
暂停
代码实现:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('a.jpg',1)
imgInfo=img.shape
height=imgInfo[0]
width=imgInfo[1]
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
count=np.zeros(256,np.float)
for i in range(height):
for j in range(width):
pixel=gray[i,j]
index=int(pixel)
count[index]+=1
for i in range(255):
count[i]/=height*width
x=np.linspace(0,255,256)
y=count
plt.bar(x,y,0.9,alpha=1,color='b')
plt.show()
cv2.waitKey(0)
**********彩色直方图源码************
知识补充:
彩色图像的直方图,是将图片分为RGB三个颜色通道分别进行绘制
思路:
引入 opencv
引入 numpy
引入 matplotlib
读取图像
获得图像信息
初始化概率数组
统计图片所有像素值的概率
定义x,y轴
绘制直方图(可以用opecv的绘图方法,也可以用matplot的绘图方法)
显示直方图
暂停
代码实现:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('a.jpg',1)
imgInfo=img.shape
height=imgInfo[0]
width=imgInfo[1]
count_b=np.zeros(256,np.float)
count_g=np.zeros(256,np.float)
count_r=np.zeros(256,np.float)
for i in range(height):
for j in range(width):
(b,g,r)=img[i,j]
index_b=int(b)
index_g=int(g)
index_r=int(r)
count_b[index_b]+=1
count_g[index_g]+=1
count_r[index_r]+=1
for i in range(255):
count_b[i]/=height*width
count_g[i]/=height*width
count_r[i]/=height*width
x=np.linspace(0,255,256)
y1=count_b
y2=count_g
y3=count_r
plt.figure()
plt.var(x,y1,0.9,alpha=1,color='b')
plt.figure()
plt.var(x,y2,0.9,alpha=1,color='g')
plt.figure()
plt.var(x,y3,0.9,alpha=1,color='r')
plt.show()
cv2.waitKey(0)
***********直方图的均衡化源码*************
知识补充:
累计概率
灰度值为1的像素出现概率0.2 0.2(累计概率)
灰度值为2的像素出现概率0.3 0.5(累计概率)
灰度值为3的像素出现概率0.1 0.6(累计概率)
比如灰度值为100的累计概率为0.5
使用公式计算一个新的灰度值s
s=255*0.5
然后将图像中所有灰度值为100的像素点重新赋值为s
这就完成了直方图的均衡化
思路:
引入 opencv
引入 numpy
引入 matplotlib
读取图像
获得图像信息
对图像进行灰度化
初始化概率数组
统计图片所有像素值的概率
计算每个像素值得累计概率
根据累计概率计算出新的像素值
遍历图像进行像素值得替换
显示处理后的图像
暂停
代码实现:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('a.jpg',1)
imgInfo=img.shape
height=imgInfo[0]
width=imgInfo[1]
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
count=np.zeros(256,np.float)
for i in range(height):
for j in range(width):
pixel=gray[i,j]
index=int(pixel)
count[index]+=1
for i in range(255):
count[i]/=height*width
sum1=float(0)
for i in range(0,256):
sum+=count[i]
count[i]=sum
map1=np.zeros(256,np.uint16)
for i in range(0,256):
map1[i]=np.uint16(count[i]*255)
for i in range(height):
for j in range(width):
pixel=gray[i,j]
gray[i,j]=map[pixel]
cv2.imshow('dst',gray)
cv2.waitKey(0)
*************彩色直方图均衡化代码**************
知识补充:
思路:
引入 opencv
引入 numpy
引入 matplotlib
读取图像
获得图像信息
对图像进行灰度化
初始化概率数组
统计图片所有像素值的概率
计算每个像素值得累计概率
根据累计概率计算出新的像素值
创建空白画板
遍历图像进行像素值得替换
显示处理后的图像
暂停
代码实现:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('a.jpg',1)
imgInfo=img.shape
height=imgInfo[0]
width=imgInfo[1]
count_b=np.zeros(256,np.float)
count_g=np.zeros(256,np.float)
count_r=np.zeros(256,np.float)
for i in range(height):
for j in range(width):
(b,g,r)=img[i,j]
index_b=int(b)
index_g=int(g)
index_r=int(r)
count_b[index_b]+=1
count_g[index_g]+=1
count_r[index_r]+=1
for i in range(255):
count_b[i]/=height*width
count_g[i]/=height*width
count_r[i]/=height*width
sum_b=float(0)
sum_g=float(0)
sum_r=float(0)
for i in range(0,256):
sum_b+=count_b[i]
sum_g+=count_g[i]
sum_r+=count_r[i]
count_b[i]=sum_b
count_g[i]=sum_g
count_r[i]=sum_r
mapb=np.zeros(256,np.uint16)
mapg=np.zeros(256,np.uint16)
mapr=np.zeros(256,np.uint16)
for i in range(0,256):
mapb[i]=np.uint16(count_b[i]*255)
mapg[i]=np.uint16(count_g[i]*255)
mapr[i]=np.uint16(count_r[i]*255)
dst=np.zeros((height,width,3),np.uint8)
for i in range(height):
for j in range(width):
(b,g,r)=img[i,j]
b=mapb[b]
g=mapb[g]
r=mapb[r]
dst[i,j]=(b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
*************图像的亮度增强***********************
知识补充:
新像素值=原像素值+一个固定增量
思路:
引入 opencv
引入 numpy
读取图像
获得图像信息
创建空白画板
根据公式更新像素值
显示处理后的图像
暂停
代码实现:
import cv2
import numpy as np
img=cv2.imread('a.jpg',1)
imgInfo=img.shape
height=imgInfo[0]
width=imgInfo[1]
cv2.imshow('src',img)
dst=np.zeros((height,width,3),np.uint8)
for i in range(height):
for j in range(width):
(b,g,r)=img[i,j]
bs=int(b)+40
gs=int(g)+40
rs=int(r)+40
if bs>255:
bs=255
if gs>255:
gs=255
if rs>255:
rs=255
dst[i,j]=(bs,gs,rs)
cv2.imshow('dst',dst)
cv2.waitKey(0)
*************图像磨皮美白*****************
知识补充:
新像素值=原像素值*一个系数+一个固定增量
磨皮美白使用双边滤波来实现
思路:
引入 opencv
引入 numpy
读取图像
获得图像信息
创建空白画板
根据公式更新像素值
显示处理后的图像
暂停
引入opencv
读取图片
调用API来实现磨皮美白
代码实现:
import cv2
import numpy as np
img=cv2.imread('a.jpg',1)
imgInfo=img.shape
height=imgInfo[0]
width=imgInfo[1]
cv2.imshow('src',img)
dst=np.zeros((height,width,3),np.uint8)
for i in range(height):
for j in range(width):
(b,g,r)=img[i,j]
bs=int(b*1.3)+10
gs=int(g*1.2)+15
if bs>255:
bs=255
if gs>255:
gs=255
dst[i,j]=(bs,gs,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
import cv2
img=cv2.imread('1.jpg',1)
cv2.imshow('src',img)
dst=cv2.bilateralFilter(img,15,35,35)
cv2.imshow('dst',dst)
cv2.waitKey(0)
********高斯、均值滤波*****************
知识补充:
高斯滤波通过调用API来实现
均值滤波通过源码的形式来实现
滤波的原理与边缘检测相似
用一个滤波核与图像进行卷积运算
均值滤波的原理
定义一个n*n滤波核,在图像上卷积,将卷积得到结果除以n*n,这就得到了均值,然后将计算的均值替换原来的像素值
这就实现了均值滤波
思路:
引入 opencv
引入 numpy
读取图像
调用API实现高斯滤波(类似模糊的效果,可以去除噪声点)
显示处理后的图像
暂停
引入 opencv
引入 numpy
读取图像
显示处理后的图像
暂停
代码实现:
import cv2
import numpy as np
img=cv2.imread('1.jpg',1)
dst=cv2.GaussianBlur(img,(5,5),1.5)
cv2.imshow('src',img)
cv2.waitKey(0)
import cv2
import numpy as np
img=cv2.imread('1.jpg',1)
cv2.imshow('src',img)
cv2.waitKey(0)
imgInfo=img.shape
height=imgInfo[0]
width=imgInfo[1]
dst=np.zeros((height,width,3),np.uint8)
for i in range(3,height-3):
for j in range(3,width-3):
sum_b=int(0)
sum_g=int(0)
sum_r=int(0)
for m in range(-3,3):
for n in range(-3,3):
(b,g,r)=img[i+m,j+n]
sum_b+=int(b)
sum_g+=int(g)
sum_r+=int(r)
b=np.uint8(sum_b/36)
g=np.uint8(sum_g/36)
r=np.uint8(sum_r/36)
dst[i,j]=(b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
*************图像的中值滤波******************
知识补充:
就是取中间值来代替原来像素值得过程
比如定义一个3*3的窗口,然后将该窗口在原图矩阵上滑动,然后对这窗口内9个值进行排序,取中间值来代替原来的像素值
这就是中值滤波的原理
思路:
引入 opencv
引入 numpy
读取图像
获得图像信息
将图像灰度化
创建空白画板
定义窗口
代码实现:
import cv2
import numpy as np
img=cv2.imread('a.jpg',1)
imgInfo=img.shape
height=imgInfo[0]
width=imgInfo[1]
img=cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
cv2.imshow('src',img)
dst=np.zeros((height,width,3),np.uint8)
collect=np.zeros(9,np.uint8)
for i in range(1,height-1):
for j in range(1,width-1):
k=0
for m in range(-1,2):
for n in range(-1,2):
gray=img[i+m,j+n]
collect[k]=gray
k+=1
for k in range(9):
p1=collect[k]
for t in range(k+1,9):
if p1<collect[t]:
mid=collect[t]
collect[t]=p1
p1=mid
dst[i,j]=collect[4]
cv2.imshow('dst',dst)
cv2.waitKey(0)
***********图像美化小结******************
知识补充:
不改变整体颜色的情况下进行直方图均衡化
可以采用YUV的形式,只把Y通道进行直方图的均衡化
高斯滤波
一维高斯率波函数
二维高斯滤波函数
滤波核就是通过高斯滤波函数来进行生成的
滤波的本质
除以16是一个平均的操作
滤波核越靠中间值越大(二高斯特点)
双边滤波
实际上是由一个高斯核加上一个距离核组成
将以上两个核加权求和求出一个新的核
然后用新核与图像进行卷积生成新的像素值
然后用新像素替换原来像素
无论那种滤波本质是一样的, 知识核函数不同而已
*******************机器学习***************
知识补充:
通过让机器学习的方式,来实现某些功能
机器学习=训练样本+特征+分类器
深度学习=训练样本+人工神经网络
机器学习需要一个明确的特征来进行提取
深度学习是通过训练神经网络来自动提取特征(在整个过程中,我们其实并不知道神经网络抽取的是什么样的特征)
haar特征是一个做人脸检测常用的特征
hog特征是做物体检测常用的特征
分类器根据特征来进行分类
常用的分类器
SVM
adbost
机器学
准备样本(任何方式)
将视频分解为图片
获取机器学习的特征
hog特征
由一系列的窗体组成
蓝色的矩形框
红色block模块
绿色的cell模块
要计算在每一个cell中的每一个像素的梯度,幅值和方向
根据幅值和方向进行直方图的统计,然后就得到hog特征
haar特征
分为基础类型,核心类型,普通类型,共14种
由一系列的模板组成
通过这些模板就可以对harr特征进行计算(计算公式如下)
蓝色背景表示图片
黑白矩形框为特征模板
用白色区域覆盖的像素之和-黑色区域覆盖的像素之和就得到了har特征
图中三个公式是等价的
haar特征的使用(遍历整个图像):
遍历步长(一次滑动几个像素)
模板缩放(模板随着滑动按比例放大或缩小)
缩放级数(总共缩放多少次)
利用积分图来加速特征的计算:
B区域包含A区域
C区域包含A区域
D区域包含A,B,C区域
一个小方框内像素值=a-b-c+d
利用分类器根据特征来分类
adaboost由强分类器,弱分类器,node这三个部分组成
前一个基本分类器,分类得出的样本,在下一个分类器中会得到加强
这样得到加强后的全体样本,再次被用来训练下一个基本分类器
训练的终止条件:达到训练次数或达到检测概率
分类器结构
har特征计算完成之后,需要对计算结果进行阈值判决
因此分类的实质就是一个个的判决过程
通过多级级联进行多次判决,根据多级判决结果来进行分类
这里每一级都是强分类器(adaboost的强分类器个数一般是15-20个)
harr特征的计算结果,连续通过这些强分类器(比如都判定是人,我们才把这个目标分到人则这一类)
每个强分类器都会单独进行特征值计算,并将计算结果与自己的阈值进行对比
一个adaboost分类器有若干个强分类器组成,每个强分类器又由若干个弱分类器组成,一个弱分类器有由若干个node节点组成
强分类器的作用:根据阈值对特征计算结果进行判决
弱分类器作用:计算强分类器的特征结果
node:用来计算弱分类器的特正结果
每个harr特征对应一个node节点
也就是说,n个node计算出n个harr特征,然后这个n个harr特征相加得到一个弱分类器特征
n个弱分类器特征相加得到一个强分类器特征
若干个强分类器根据自己的特征和阈值进行判决,若都通过,才行
harr(与阈值1对比)->z(与阈值2对比)->y(与阈值3对比)->x(与阈值4对比)->类别
adaboost分类器训练过程
初始化数据的权值分布
遍历阈值
计算过程
opencv自带的adaboost分类器的文件结构
测试
************视频分解成图片*******************
知识补充:
载入视频
获取视频信息
对视频解码生成图片(parse方法)
展示(imshow)
保存(imwrite)
fps帧率:就是一个视频每秒展示的图片数
宽:每一帧图像的宽度
高:每一帧图像的高度
思路:
引入opencv
调用API载入视频
判断视频是否打开
获取视频信息
读取每一帧信息
保存图片
代码实现:
import cv2
cap=cv.VideoCapture('s')#调用API载入视频
isOpened=cap.isOpened#判断视频是否打开
print(isOpened)
fps=cap.get(cv2.CAP_PROP_FPS)
width=int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height=int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(fps,width,height)
i=0
while isOpened:
if i==10:
break
esle:
i+=1
(flag,frame)=cap.read()#读取每一帧信息,flag表示是否读取成功,frame表示读取的图片信息
fileName='image'+str(i)+'.jpg'
print(fileName)
if flag==True:
cv2.imwrite(fileName,frame,[cv2.IMWRITE_JPEG_QUALITY,100])#imwrite图片名,图片内容,[保存方式,图片质量])
print('end')
********图片合成视频**************
知识点:
视频在存储的时候,并不是将图片一张一张存储,而是将一堆图片压缩编码之后存储的
图片合成视频时,要进行编码操作
视频分解为图片时,要进行解码操作
思路:
引入opencv
读取图片
获取图片信息
调用API创建视频对象
读取图片
将图片写入视频对象
代码实现:
import cv2
img=cv2.imread('image1.jpg')
imgInfo=img.shape
size=(imgInfo[1],imgInfo[0])
fourcc = cv2.VideoWriter_fourcc(*'XVID')
# print(size)
videoWrite=cv2.VideoWriter('snow2.avi',fourcc,5,size)#创建视频对象,cv2.VideoWriter(视频名,编码器号,帧率,图片大小)
for i in range(1,11):
fileName='image'+str(i)+'.jpg'
img=cv2.imread(fileName)
print(img)
videoWrite.write(img)#将图片写入视频对象
print('end')
*******************har特征********************8
知识补充:
特征
就是图像中某个区域的像素点经过四则运算之后得到的结果
这个结果可以是一个具体的值,也可以是一个向量,也可以是一个多维的元素
像素经过运算得到的结果就是特征
像素经过运算之后可能得到各种各样的结果,不论结果的形势如何我们都将它称为特征
特征的本质就是像素运算(其实就是图像矩阵的运算)得到的结果
利用特征区分目标
阈值判决
如果这个特征大于某一个阈值,我们就把它识别为某个目标
通过机器学习得到阈值(判决门限),然后再根据计算得到的特征来进行阈值判决
其实就是通过机器学习来获得判决规则,然后利用该规则来根据特征来进行分类
思路:
代码实现: