# 基于python的Opencv项目实战
相关代码(我都运行过!)
链接:https://pan.baidu.com/s/10p3qrBcMkjXscTAw3Xpm1g
提取码:KKKK
听说失效了:再来一个:
链接: https://pan.baidu.com/s/1wi9MrBvAhGxyAj1i0NAukQ 提取码: tj2h 复制这段内容后打开百度网盘手机App,操作更方便哦
* 环境配置:(代码里也有)
* python 3.6
* opencv-contrib-python=3.4.1.15
* opencv-python=3.4.1.15
## 1.图像基本操作
### 1.1 图像构成
* 一般分为有颜色图像和无颜色图像
* 像素点在[0,255]之间,值越小越黑,反之亦然
* 彩色图像:有颜色通道,一般读取的图像即为(h,w,c)
* 如RGB,BGR:(xx,xx,xx)
* 灰度图像:即无通道,一般读取的图像即为(h,w)
### 1.2 数据读取-图像
import cv2
opencv读取的彩色图片的颜色通道格式是BGR
所以如果要用其他函数展示opencv读取的图片,最好要转变成相同的格式,如RGB,BGR等
* img = cv2.imread(filepath,cv2.IMREAD_COLOR)
* cv2.IMREAD_COLOR:彩色图像
* cv2.IMREAD_GRAYSCALE:灰度图像
* 一般显示图片
'''
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
'''
### 1.3 数据读取-视频
* cv2.VideoCapture可以捕获摄像头,用数字来控制不同的设备,例如0,1。
* 如果是视频文件,直接指定好路径即可。
* 具体代码看文件!
### 1.4 截取部分图像数据
也即处理nparray数据,对应位置切片即可
* cat=img[0:50,0:200]
### 1.5 颜色通道提取
* b,g,r=cv2.split(img)
or
* b1,g1,r1=img[:,:,0],img[:,:,1],img[:,:,2]
### 1.6 边界填充
* cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType)
* borderType:
- BORDER_REPLICATE:复制法,也就是复制最边缘像素。
- BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
- BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
- BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
- BORDER_CONSTANT:常量法,常数值填充。
### 1.7 数值计算
'''
相当于% 256
防止超过255,则进行mod运算,防止溢出
(img_cat + img_cat2)[:5,:,0]
'''
''''
防止超过255,则进行取上界运算,防止溢出
cv2.add(img_cat,img_cat2)[:5,:,0]
'''
### 1.8 图像融合
要相同大小的图片才可以进行
* img_dog = cv2.resize(img_dog, (500, 414))
‘’‘
R = a*x1+b*x2+b
融合的方式:有权重有偏置
res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)
重新改变大小,进行比值计算
x4倍,y4倍扩大
res = cv2.resize(img, (0, 0), fx=4, fy=4)
plt.imshow(res)
’‘’
## 2.图像处理
### 2.1 图像阈值
#### ret, dst = cv2.threshold(src, thresh, maxval, type)
- src: 输入图,只能输入单通道图像,通常来说为灰度图
- dst: 输出图
- ret: 返回阈值
- thresh: 阈值
- maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
- type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
- cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
- cv2.THRESH_BINARY_INV THRESH_BINARY的反转
- cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
- cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0
- cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转
eg:
* ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
### 2.2图像平滑
类似卷积操作
* 均值滤波=简单的平均卷积操作
* blur = cv2.blur(img, (3, 3))
* 方框滤波=基本和均值一样,可以选择归一化,只是多了一个参数
* -1:表示处理后的颜色通道数是一致的
* box = cv2.boxFilter(img,-1,(3,3), normalize=True)
* box = cv2.boxFilter(img,-1,(3,3), normalize=False)
* 不选择归一化,则像素点可以超过255
* 高斯滤波=高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
* 离中心点越接近的值是其可能性越大,充分考虑到不同像素点对中心点的影响
* aussian = cv2.GaussianBlur(img, (5, 5), 1)
* 中值滤波=相当于用中值代替
* median = cv2.medianBlur(img, 5) # 中值滤波
* 展示所有的图片,使用np的堆叠功能
* 水平堆叠:hsres = np.hstack((blur,aussian,median))
* 垂直堆叠:vsres = np.vstack((blur,aussian,median))
### 2.3形态学
字面意思理解即可,实在不行运行代码看效果!
#### 2.3.1 腐蚀操作
* kernel = np.ones((3,3),np.uint8)
* erosion = cv2.erode(img,kernel,iterations = 1)
#### 2.3.2 膨胀操作
* kernel = np.ones((3,3),np.uint8)
* dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 5)
#### 2.3.3 开运算与闭运算
* 开运算:先腐蚀,再膨胀
* kernel = np.ones((5,5),np.uint8)
* opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
* 闭运算:先膨胀,再腐蚀
* kernel = np.ones((5,5),np.uint8)
* closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
#### 2.3.4 梯度运算
梯度=膨胀-腐蚀,也就相当于找图片不同像素点之间的差异大小,类似求导的感觉,所以叫梯度
* gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)
#### 2.3.5 礼帽与黑帽
- 礼帽 = 原始输入-开运算结果 = 原始输入-(先腐蚀,再膨胀)
- tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
- 黑帽 = 闭运算-原始输入 = (先膨胀,再腐蚀)-原始输入
- blackhat = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)
### 2.4 图像梯度
* Sobel算子:计算像素点之间的差异大小,一般有从x方向和y方向
* dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
- ddepth:图像的深度,一般为-1
- dx和dy分别表示水平和竖直方向,判断是计算x方向还是y方向,通过指定0or1
- ksize是Sobel算子的大小
* sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
* sobelxy = cv2.convertScaleAbs(sobelxy)
* 分别计算x和y,再求和,效果更好
* cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3) 效果不太行
* Scharr算子:类似Sobel算子,只是数值略有不同
* scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
* scharrx = cv2.convertScaleAbs(scharrx)
* Laplacian算子:考虑到二阶导,但对噪音点敏感
* laplacian = cv2.Laplacian(img,cv2.CV_64F)
* laplacian = cv2.convertScaleAbs(la placian)
### 2.5 Canny边缘检测
- 1) 使用高斯滤波器,以平滑图像,滤除噪声。
- 2) 计算图像中每个像素点的梯度强度和方向。
- 3) 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应(如人脸检测的框的确定)。
- 4) 应用双阈值(Double-Threshold=minval,maxval)检测来确定真实的和潜在的边缘。
- 5) 通过抑制孤立的弱边缘最终完成边缘检测。
- v1=cv2.Canny(img,minval,maxval)
### 2.6 图像金字塔
也即对图像进行提取特征的操作,放大或者缩小图像
* 高斯金字塔
* 向下采样方法(缩小):图像与高斯核卷积,再去除所有偶数行与列
* 向上采样方法(放大):图像在每个方向扩大用来的两倍(右,下,右下),用0填充,再使用高斯核卷积卷积
* up=cv2.pyrUp(img)
* down=cv2.pyrDown(img)
* 拉普拉斯金字塔
* L = G-pyrUp(pyrdown(G))
* down=cv2.pyrDown(img)
* down_up=cv2.pyrUp(down)
* l_1=img-down_up
### 2.7 图像轮廓
#### 2.7.1 提取轮廓
* cv2.findContours(img,mode,method)
* mode:轮廓检索模式
- RETR_EXTERNAL :只检索最外面的轮廓;
- RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;
- RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
- RETR_TREE:检索所