说明:本教程是我在学习opencv官方文档中文版时做的笔记,后面会接着更新。
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退出
cap = cv2.VideoCapture(0) 索引号在指定要使用的摄像头。一般的笔记本电脑内置摄像头参数就是 0
cap.isOpened()
,来检查是否成功初始化了
cap.set(propId,value)
修改视频的一些属性
ret=cap.set(3,320) ret=cap.set(4,240)
来把宽和高改成 320X240。
• 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)` 图片上绘制文字
创建图像与窗口并将窗口与回调函数绑定
img=np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
窗口,回调函数
cv2.getTrackbarPos() 函数的一个参数是滑动条的名字,第二个参数是滑动条被放置窗口的名字,第三个参数是滑动条的默认位置。第四个参数是滑动条的最大值,第五个函数是回调函数,每次滑动条的滑动都会调用回调函数。回调函数通常都会含有一个默认参数,就是滑动条的位置。
滑动条的另外一个重要应用就是用作转换按钮。创建一个转换按钮,只有当装换按钮指向 ON 时,滑动条的滑动才有用。
[外链图片转存失败(img-v1F514BE-1565693696911)(E:\CV\笔记\调色板.png)]
获取的像素值,对 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 - 立方插值.
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()
转换颜色空间:
cv2.cvtColor(input_image,flag)
flag就是转换类型
BGR↔Gray 的转换, flag 是 cv2.COLOR_BGR2GRAY
BGR↔HSV 的转换, flag 是 cv2.COLOR_BGR2HSV
扩展缩放图片尺寸:,
[外链图片转存失败(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)
cv2.threshhold()。这个函数的第一个参数就是原图像,原图
像应该是灰度图。第二个参数就是用来对像素值进行分类的阈值。第三个参数
就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值。OpenCV
提供了多种不同的阈值方法,这是有第四个参数来决定的。这些方法包括:
• cv2.THRESH_BINARY
• cv2.THRESH_BINARY_INV
• cv2.THRESH_TRUNC
• cv2.THRESH_TOZERO
• cv2.THRESH_TOZERO_INV
函数有两个返回值,第一个为 retVal,我们后面会解释。第二个就是
阈值化之后的结果图像了。
#11 为 Block size, 2 为 C 值
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,11,2)
用到的函数还是 cv2.threshold(),但是需要多传入一个参数
(flag):cv2.THRESH_OTSU。这时要把阈值设为 0。然后算法会找到最
优阈值,这个最优阈值就是返回值 retVal。如果不使用 Otsu 二值化,返回的
retVal 值与设定的阈值相等。
ret,th = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
#创建 5x5 的平均滤波器核
kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)
blur = cv2.blur(img,(5,5))
#0是指根据窗口大小(5,5)来计算高斯函数标准
blur = cv2.GaussianBlur(img,(5,5),0)
给原始图像加上 50% 的噪声然后再使用中值模糊
median = cv2.medianBlur(img,5)
#9 邻域直径,两个 75 分别是空间高斯函数标准差,灰度值相似性高斯函数标准差
blur = cv2.bilateralFilter(img,9,75,75)
卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是 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()
先进性腐蚀再进行膨胀就叫做开运算。就像我们上面介绍的那样,它被用
来去除噪声。这里我们用到的函数是 cv2.morphologyEx()。
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
先膨胀再腐蚀。它经常被用来填充前景物体中的小洞,或者前景物体上的
小黑点。
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
形态学梯度
其实就是一幅图像膨胀与腐蚀的差别。结果看上去就像前景物体的轮廓。
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
原始图像与进行开运算之后得到的图像的差。下面的例子是用一个 9x9 的
核进行礼帽操作的结果。
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
17.6 黑帽
进行闭运算之后得到的图像与原始图像的差。
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
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()
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()
• 学习找轮廓,绘制轮廓等
• 函数: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)
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]])
使用掩模
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()