python opencv学习教程

说明:本教程是我在学习opencv官方文档中文版时做的笔记,后面会接着更新。

4 图片

img = cv2.imread('messi5.jpg',0) 灰度模式读入图片

cv2.imshow('image',img) 第一个参数是窗口名字,其次才是我们的图像
cv2.waitKey(0) 键盘绑定函数
cv2.destroyAllWindows() 删除建立的窗口。

cv2.namedWindow('image',cv2.WINDOWNORMAL) 可以调整窗口大小

cv2.imwrite('messigray.png',img) 位置在当前项目下

if cv2.waitKey(1) & 0xFF == ord('q'):
break

注:如果你用的是 64 位系统,你需要将 k = cv2.waitKey(0) 这行改成k = cv2.waitKey(0)&0xFF。

==27 Esc退出

5 视频

cap = cv2.VideoCapture(0) 索引号在指定要使用的摄像头。一般的笔记本电脑内置摄像头参数就是 0

cap.isOpened(),来检查是否成功初始化了

cap.set(propId,value) 修改视频的一些属性

ret=cap.set(3,320) ret=cap.set(4,240) 来把宽和高改成 320X240。

6 OpenCV 中的绘图函数

• img:你想要绘制图形的那幅图像。
• color:形状的颜色。如:(255,0,0)代表蓝色。对于灰度图只需要传入灰度值。
• thickness:线条的粗细。如果给一个闭合图形设置为 -1,那么这个图形就会被填充。默认值是 1.
• linetype:线条的类型,8 连接,抗锯齿等。默认情况是 8 连接。cv2.LINE_AA为抗锯齿,这样看起来会非常平滑。

cv2.line(img,(0,0),(511,511),(255,0,0),5) 图片,起点,终点,颜色,粗细

cv2.rectangle(img,(384,0),(510,128),(0,255,0),3) 图片,左上角 右下角 颜色 粗细

cv2.circle(img,(447,63), 63, (0,0,255), -1) 图片 圆心 半径 颜色 -1封闭

cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)

图片 椭圆心 (长轴,短轴) 逆时针旋转角度 顺时针旋转角度 封闭

``font=cv2.FONT_HERSHEY_SIMPLEXcv2.putText(img,‘OpenCV’,(10,500), font, 4,(255,255,255),2)` 图片上绘制文字

7 把鼠标当画笔

创建图像与窗口并将窗口与回调函数绑定

img=np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle) 窗口,回调函数

8 用滑动条做调色板

cv2.getTrackbarPos() 函数的一个参数是滑动条的名字,第二个参数是滑动条被放置窗口的名字,第三个参数是滑动条的默认位置。第四个参数是滑动条的最大值,第五个函数是回调函数,每次滑动条的滑动都会调用回调函数。回调函数通常都会含有一个默认参数,就是滑动条的位置。

滑动条的另外一个重要应用就是用作转换按钮。创建一个转换按钮,只有当装换按钮指向 ON 时,滑动条的滑动才有用。

[外链图片转存失败(img-v1F514BE-1565693696911)(E:\CV\笔记\调色板.png)]

9 图像的基础操作

获取的像素值,对 BGR 返回值为 B,G,R 的值。对灰度图像返回他的灰度值,对RGB返回一个集合

修改像素值(不推荐使用)

img[100,100]=[255,255,255]

图像的属性包括:行,列,通道,图像数据类型,像素数目等

img.shape 可以获取图像的形状。返回值是一个包含行数,列数,通道数的元组

注意:如果图像是灰度图,返回值仅有行数和列数。所以通过检查这个返回值就可以知道加载的是灰度图还是彩色图

img.size 可以返回图像的像素数目

img.dtype 返回的是图像的数据类型.

b,g,r=cv2.split(img) BGR 拆分成单个通道
img=cv2.merge(b,g,r) 合并BGR通道

警告:cv2.split() 是一个比较耗时的操作。只有真正需要时才用它,能用
Numpy 索引就尽量用

b=img[:,:,0]
假如使所有像素的红色通道值都为 0,你不必先拆分再赋值。你可以直接使用 Numpy 索引,这会更快。

cv2.resize() 改变图文大小

img1 = cv2.resize(img1,(400,600),interpolation = cv2.INTER_CUBIC)

Note: 参数interpolation不能少

CV_INTER_NN - 最近邻插值,

CV_INTER_LINEAR - 双线性插值 (缺省使用)

CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法…

CV_INTER_CUBIC - 立方插值.

10 图像上的算术运算

OpenCV 的加法是一种饱和操作,而 Numpy 的加法是一种模操作。

图像合并:计算公式如下:g (x) = (1-α) f0 (x) + αf1 (x)

dst=cv2.addWeighted(img1,0.7,img2,0.3,0)
cv2.imshow('dst',dst)

检测程序效率:

e1 = cv2.getTickCount()

#your code execution

e2 = cv2.getTickCount()
time = (e2 - e1)/ cv2.getTickFrequency()

13 颜色空间转换

​ 转换颜色空间:

cv2.cvtColor(input_image,flag) flag就是转换类型

BGR↔Gray 的转换, flag 是 cv2.COLOR_BGR2GRAY
BGR↔HSV 的转换, flag 是 cv2.COLOR_BGR2HSV

14 几何变换

扩展缩放图片尺寸:,

[外链图片转存失败(img-b54B5hDX-1565693696911)(E:\CV\笔记\扩展缩放.png)]

平移:

img = cv2.imread('C:\\122.jpg')  
M = np.float32([[1, 0, 10], [0, 1, 50]])
moveImage = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
#[1, 0, 10]代表右移10像素,[0, 1, 50]代表下移50像素
#shape[0],shape[1]代表图片高长

旋转:

rows,cols=img.shape
# 参数1旋转中心,2旋转角度,3旋转后的缩放因子
# 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
M=cv2.getRotationMatrix2D((cols/2,rows/2),45,0.6)
# 第三个参数是输出图像的尺寸中心
dst=cv2.warpAffine(img,M,(2*cols,2*rows))
cv2.imshow('dst',dst)
15 图像阈值
15.1 简单阈值

cv2.threshhold()。这个函数的第一个参数就是原图像,原图
像应该是灰度图。第二个参数就是用来对像素值进行分类的阈值。第三个参数
就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值。OpenCV
提供了多种不同的阈值方法,这是有第四个参数来决定的。这些方法包括:
• cv2.THRESH_BINARY
• cv2.THRESH_BINARY_INV
• cv2.THRESH_TRUNC
• cv2.THRESH_TOZERO
• cv2.THRESH_TOZERO_INV

函数有两个返回值,第一个为 retVal,我们后面会解释。第二个就是
阈值化之后的结果图像了。

15.2 自适应阈值
#11 为 Block size, 2 为 C 值
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,11,2)
15.3 Otsu’s 二值化

用到的函数还是 cv2.threshold(),但是需要多传入一个参数
(flag):cv2.THRESH_OTSU。这时要把阈值设为 0。然后算法会找到最
优阈值,这个最优阈值就是返回值 retVal。如果不使用 Otsu 二值化,返回的
retVal 值与设定的阈值相等。

ret,th = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
16 图像平滑(模糊)
2D 卷积
#创建 5x5 的平均滤波器核
kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)
图像模糊
16.1 平均

blur = cv2.blur(img,(5,5))

16.2 高斯模糊
#0是指根据窗口大小(5,5)来计算高斯函数标准
blur = cv2.GaussianBlur(img,(5,5),0)
16.3 中值模糊

给原始图像加上 50% 的噪声然后再使用中值模糊

median = cv2.medianBlur(img,5)

16.4 双边滤波
#9 邻域直径,两个 75 分别是空间高斯函数标准差,灰度值相似性高斯函数标准差
blur = cv2.bilateralFilter(img,9,75,75)
17 形态学转换
17.1腐蚀、膨胀

卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是 1,那么中心元素就保持原来的像素值,否则就变为零。

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

img = cv2.imread('C://tupian//fushi.png')

#创建5x5 的卷积核
kernel = np.ones((2,2),np.uint8)

# 腐蚀
erosion = cv2.erode(img,kernel,iterations=1)

# 膨胀
dilation = cv2.dilate(img,kernel,iterations=1)

plt.subplot(221),plt.imshow(img,'gray')
plt.subplot(222),plt.imshow(erosion,'gray')
plt.subplot(223),plt.imshow(dilation)
plt.show()
17.2 开运算

先进性腐蚀再进行膨胀就叫做开运算。就像我们上面介绍的那样,它被用
来去除噪声。这里我们用到的函数是 cv2.morphologyEx()。

opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

17.3 闭运算

先膨胀再腐蚀。它经常被用来填充前景物体中的小洞,或者前景物体上的
小黑点。

closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

17.4 形态学梯度

形态学梯度
其实就是一幅图像膨胀与腐蚀的差别。结果看上去就像前景物体的轮廓。

gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

17.5 礼帽

原始图像与进行开运算之后得到的图像的差。下面的例子是用一个 9x9 的
核进行礼帽操作的结果。
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

17.6 黑帽

进行闭运算之后得到的图像与原始图像的差。
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

18 图像梯度
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread("C:\\tupian\\tidu.png")
laplacian = cv2.Laplacian(img,cv2.CV_64F)

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)

plt.subplot(221),plt.imshow(img,'gray')
plt.title('Original')
plt.subplot(222),plt.imshow(laplacian,cmap='gray')
plt.title('Laplacian'),plt.xticks([0,100,200])
plt.subplot(223),plt.imshow(sobelx,cmap='gray')
plt.title('Sobel X')
plt.subplot(224),plt.imshow(sobely,cmap='gray')
plt.show()
19 Canny边缘检测
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('messi5.jpg',0)
#100,200表示像素值得上下限
edges = cv2.Canny(img,100,200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()
20 轮廓

• 学习找轮廓,绘制轮廓等

• 函数:cv2.findContours(),cv2.drawContours()

函数 cv2.findContours() 有三个参数,第一个是输入图像,第二个是 轮廓检索模式,第三个是轮廓近似方法。返回值有三个,第一个是图像,第二个 是轮廓,第三个是(轮廓的)层析结构。轮廓(第二个返回值)是一个 Python 列表,其中存储这图像中的所有轮廓。每一个轮廓都是一个 Numpy 数组,包 含对象边界点(x,y)的坐标。

函数 cv2.drawContours() 可以被用来绘制轮廓。它可以根据你提供 的边界点绘制任何形状。它的第一个参数是原始图像,第二个参数是轮廓,一 个 Python 列表。第三个参数是轮廓的索引(在绘制独立轮廓是很有用,当设 置为 -1 时绘制所有轮廓)。接下来的参数是轮廓的颜色和厚度等。

ret,thresh = cv2.threshold(imgray,127,255,0) image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
img = cv2.drawContours(img, contours, 3, (0,255,0), 3)

边界矩形:

直边界矩形 一个直矩形(就是没有旋转的矩形)。它不会考虑对象是否旋转。 所以边界矩形的面积不是最小的。可以使用函数 cv2.boundingRect() 查 找得到。 (x,y)为矩形左上角的坐标,(w,h)是矩形的宽和高。

x,y,w,h = cv2.boundingRect(cnt) 
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

旋转的边界矩形 这个边界矩形是面积最小的,因为它考虑了对象的旋转。用 到的函数为 cv2.minAreaRect()。返回的是一个 Box2D 结构,其中包含 矩形左上角角点的坐标(x,y),矩形的宽和高(w,h),以及旋转角度。但是 要绘制这个矩形需要矩形的 4 个角点,可以通过函数 cv2.boxPoints() 获 得。

x,y,w,h = cv2.boundingRect(cnt) 
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

最小外接圆 函数 cv2.minEnclosingCircle() 可以帮我们找到一个对象的外切圆。 它是所有能够包括对象的圆中面积最小的一个。

(x,y),radius = cv2.minEnclosingCircle(cnt) 
center = (int(x),int(y)) 
radius = int(radius) 
img = cv2.circle(img,center,radius,(0,255,0),2)

椭圆拟合 使用的函数为 cv2.ellipse(),返回值其实就是旋转边界矩形的内切圆。

ellipse = cv2.fitEllipse(cnt) 
im = cv2.ellipse(im,ellipse,(0,255,0),2)

直线拟合 我们可以根据一组点拟合出一条直线,同样我们也可以为图像中的白色点 拟合出一条直线。

rows,cols = img.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt,  cv2.DIST_L2,0,0.01,0.01) 
lefty = int((-x*vy/vx) + y) 
righty = int(((cols-x)*vy/vx)+y) 
img = cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)
22 直方图

Short Way(简单方法):使用 Matplotlib 中的绘图函数。

img = cv2.imread('home.jpg',0)
plt.hist(img.ravel(),256,[0,256])
plt.show()

注: 参数2表示将256个像素值分为多少组

​ 参数3表示要统计的灰度值范围

Long Way(复杂方法,速度快):使用 OpenCV 绘图函数

img = cv2.imread('C:\\127.jpg')
color = ('b','g','r')
for i,col in enumerate(color):
    histr = cv2.calcHist([img],[i],None,[256],[0,256])
    plt.plot(histr,color = col)
    plt.xlim([0,256])
plt.show()

注:cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])

  1. images: 原图像(图像格式为 uint8 或 float32)。中括号 [] 括起来,例如:[img]。
  2. channels: 需要中括号 如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
  3. mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。如果想统计图像某一部分的直方图,需要制作一个掩模图像,并使用它
  4. histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
  5. ranges: 像素值范围,通常为 [0,256]

使用掩模

img = cv2.imread('home.jpg',0)
//create a mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv2.bitwise_and(img,img,mask = mask)
//  Calculate histogram with mask and without mask
//  Check third argument for mask
hist_full = cv2.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv2.calcHist([img],[0],mask,[256],[0,256])
plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask,'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full),plt.plot(hist_mask)
plt.xlim([0,256])
plt.show()

你可能感兴趣的:(OpenCV,python,opencv学习教程,学习笔记)