1.moments()
cv::moments ( InputArray array,
bool binaryImage = false
)
array:输入数组,可以是光栅图像(单通道,8-bit或浮点型二维数组),或者是一个二维数组(1 X N或N X 1),二维数组类型为Point或Point2f
binaryImage:默认值是false,如果为true,则所有非零的像素都会按值1对待,也就是说相当于对图像进行了二值化处理,阈值为1,此参数仅对图像有效。
opencv中提供了moments()来计算图像中的中心矩(最高到三阶),HuMoments()用于由中心矩计算Hu矩.同时配合函数contourArea函数计算轮廓面积和arcLength来计算轮廓或曲线长度
2.cv2.merge
合并单通道成多通道(不能合并多个多通道图像)
3.cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst
参数说明:
src - 原图
dst - 目标图像。当参数dsize不为0时,dst的大小为size;否则,它的大小需要根据src的大小,参数fx和fy决定。dst的类型(type)和src图像相同
dsize - 目标图像大小。当dsize为0时,它可以通过以下公式计算得出:
所以,参数dsize和参数(fx, fy)不能够同时为0
fx - 水平轴上的比例因子。当它为0时,计算公式如下:
fy - 垂直轴上的比例因子。当它为0时,计算公式如下:
interpolation - 插值方法。共有5种:
1)INTER_NEAREST - 最近邻插值法
2)INTER_LINEAR - 双线性插值法(默认)
3)INTER_AREA - 基于局部像素的重采样(resampling using pixel area relation)。对于图像抽取(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。
4)INTER_CUBIC - 基于4x4像素邻域的3次插值法
5)INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值
4. cv2.cvtColor() 颜色空间转换函数
ret, frame = cap.read()返回值含义:
参数ret 为True 或者False,代表有没有读取到图片
第二个参数frame表示截取到一帧的图片
camera = cv2.VideoCapture(0)
ret, frame = camera.read()
5. cv2.threshold(src, x, y, Methods)
图像的二值化,是把图像显现出黑和白的效果。
使用阈值(threshold)函数,将RGB图像转为二值图。
src:指原图像,该原图像为灰度图
x:指用来对像素值进行分类的阈值
y:指当像素值高于(有时小于)阈值时应该被赋予的新的像素值
Methods:指不同的阈值方法,这些方法包括:cv2.THRESH_BINARY、cv2.THRESH_BINARY_INV、
cv2.THRESH_TRUNC、 cv2.THRESH_TOZERO、 cv2.THRESH_TOZERO_INV。
cv2.threshold()函数的作用是将一幅灰度图二值化,基本用法如下:
#ret:暂时就认为是设定的thresh阈值,mask:二值化的图像
ret,mask = cv2.threshold(img2gray,175,255,cv2.THRESH_BINARY)
plt.imshow(mask,cmap=‘gray’)
上面代码的作用是,将灰度图img2gray中灰度值小于175的点置0,灰度值大于175的点置255
具体用法如下:
threshold(src, thresh, maxval, type[, dst])->ret,dst
src::灰度图
thresh:阈值
maxval:最大值
type:阈值类型
对于最后一个参数,常见的阈值类型有:
THRESH_BINARY=0,THRESH_BINARY_INV,THRESH_TRUNC,THRESH_TOZERO,THRESH_TOZERO_INV,THRESH_OTSU,THRESH_TRIANGLE,THRESH_MASK
他们的作用参见下表:
threshold函数有两个返回值,其中第二个返回值(这里是mask)是二值化后的灰度图。当我们指定了阈值参数thresh,第一个返回值ret就是我们指定的thresh。换句话说,我们可以不指定阈值参数thresh。
通常情况,我们一般不知道设定怎样的阈值thresh才能得到比较好的二值化效果,只能去试。如对于一幅双峰图像(理解为图像直方图中存在两个峰),我们指定的阈值应尽量在两个峰之间的峰谷。这时,就可以用第四个参数THRESH_OTSU,它对一幅双峰图像自动根据其直方图计算出合适的阈值(对于非双峰图,这种方法得到的结果可能不理想)。
对于双峰图,我们需要多传入一个参数cv2.THRESH_OTSU,并且把阈值thresh设为0,算法会找到最优阈值,并作为第一个返回值ret返回。
比如0,0,0代表黑色,255,255,255代表白色;纯蓝:0,0,255;255,0,0代表红色;绿色0,255,0
6.cv2.findContours()函数来查找检测物体的轮廓
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img,contours,-1,(0,0,255),3)
cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),所以读取的图像要先转成灰度的,再转成二值图
opencv2返回两个值:contours:hierarchy。注:opencv3会返回三个值,分别是img, countours, hierarchy
函数的原型为cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
参数
第一个参数是寻找轮廓的图像;
第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):
cv2.RETR_EXTERNAL表示只检测外轮廓
cv2.RETR_LIST检测的轮廓不建立等级关系
cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
cv2.RETR_TREE建立一个等级树结构的轮廓。
第三个参数method为轮廓的近似办法
cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
返回值
cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。
contour返回值
cv2.findContours()函数首先返回一个list,list中每个元素都是图像中的一个轮廓,用numpy中的ndarray表示。这个概念非常重要。在下面drawContours中会看见。通过
[python] view plain copy
print (type(contours))
print (type(contours[0]))
print (len(contours))
可以验证上述信息。会看到本例中有两条轮廓,一个是五角星的,一个是矩形的。每个轮廓是一个ndarray,每个ndarray是轮廓上的点的集合。
由于我们知道返回的轮廓有两个,因此可通过
cv2.drawContours(img,contours,0,(0,0,255),3)
和
cv2.drawContours(img,contours,1,(0,255,0),3)
分别绘制两个轮廓,关于该参数可参见下面一节的内容。同时通过
[python] view plain copy
print (len(contours[0]))
print (len(contours[1]))
输出两个轮廓中存储的点的个数,可以看到,第一个轮廓中只有4个元素,这是因为轮廓中并不是存储轮廓上所有的点,而是只存储可以用直线描述轮廓的点的个数,比如一个“正立”的矩形,只需4个顶点就能描述轮廓了。
hierarchy返回值
此外,该函数还可返回一个可选的hiararchy结果,这是一个ndarray,其中的元素个数和轮廓个数相同,每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0] ~hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,则该值为负数。
通过
print (type(hierarchy))
print (hierarchy.ndim)
print (hierarchy[0].ndim)
print (hierarchy.shape)
得到
[python] view plain copy
3
2
(1, 2, 4)
可以看出,hierarchy本身包含两个ndarray,每个ndarray对应一个轮廓,每个轮廓有四个属性。
global 标志实际上是为了提示 python 解释器,表明被其修饰的变量是全局变量。这样解释器就可以从当前空间 (current scope) 中读写相应变量了。
7.cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
第一个参数:img是原图
第二个参数:(x,y)是矩阵的左上点坐标
第三个参数:(x+w,y+h)是矩阵的右下点坐标
第四个参数:(0,255,0)是画线对应的rgb颜色
第五个参数:2是所画的线的宽度
8.cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) ->hist
计算一组数组的直方图
imaes:输入的图像
channels:选择图像的通道
mask:掩膜,是一个大小和image一样的np数组,其中把需要处理的部分指定为1,不需要处理的部分指定为0,一般设置为None,表示处理整幅图像
histSize:使用多少个bin(柱子),一般为256
ranges:像素值的范围,一般为[0,255]表示0~255
注意,除了mask,其他四个参数都要带[]号。
第一个参数必须用方括号括起来。
第二个参数是用于计算直方图的通道,这里使用灰度图计算直方图,所以就直接使用第一个通道;
第三个参数是Mask,这里没有使用,所以用None。
第四个参数是histSize,表示这个直方图分成多少份(即多少个直方柱)。第二个例子将绘出直方图,到时候会清楚一点。
第五个参数是表示直方图中各个像素的值,[0.0, 256.0]表示直方图能表示像素值从0.0到256的像素。
9.归一化函数cv2.normalize()
cv2.normalize(src[, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]]) → dst
src-输入数组。
dst-与SRC大小相同的输出数组。
α-范数值在范围归一化的情况下归一化到较低的范围边界。
β-上限范围在范围归一化的情况下;它不用于范数归一化。
范式-规范化类型(见下面的细节)。
dType——当输出为负时,输出数组具有与SRC相同的类型;否则,它具有与SRC相同的信道数和深度=CVH-MatthAsHead(DyType)。
面具-可选的操作面具。
这个函数提供了四种归一化方式,可根据需要选择以下四个参数,下面重点说下这四种归一化方式。
NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化。
NORM_INF: 归一化数组的(切比雪夫距离)L∞范数(绝对值的最大值)
NORM_L1 : 归一化数组的(曼哈顿距离)L1-范数(绝对值的和)
NORM_L2: 归一化数组的(欧几里德距离)L2-范数
10.cv2.calBackProject()直方图反射投影
cv2.calcBackProject(images, channels, hist, ranges, scale, dst=None)
它可以用来干什么呢?图象分割或者在图象中搜索我们感兴趣的部分。简单来说说,它会输出与输入图象同样大小的图像,其中的每个像素值代表了输入图象上对应点属于目标的概率。更简单来说输出图像的像素值越高的点就越可能代表我们要搜索的目标。这个算法通常和camshift算法一起使用。
通常的使用情况是,我们有一张小的图片,我们要在大的图片找到与小的图片近似的部分(先看这句话吧)。
具体的实现,首先我们要为一张抱哈我们查找目标的图像创建直方图,最好是颜色直方图,因为颜色比灰度有更好的辨识度。接着我们再把这个颜色直方图投影到输入图象来寻找我们的目标,也就是找到输入图象的每一个像素点的像素值在直方图中对应的概率,最后设置适当的阈值进行二值化。
函数的第一个参数是输入图象,注意加中括号。
第二个参数是信道。
第三个参数是图象的直方图。
第四个是直方图的变化范围。
第五个是输出反投影的可选比例因子。
最后一个注意的是这里的直方图要先做归一化处理,再使用。然后看一下具体的例子。反向投影的结果包含了:以每个输入图像像素点为起点的直方图对比结果。可以把它看成是一个二维的浮点型数组,二维矩阵,或者单通道的浮点型图像。如果输入图像和模板图像一样大,那么反向投影相当于直方图对比。如果输入图像比模板图像还小,直接罢工~~
11.cv2.getStructuringElement()
这个函数的第一个参数表示内核的形状,有三种形状可以选择。
矩形:MORPH_RECT;
交叉形:MORPH_CROSS;
椭圆形:MORPH_ELLIPSE;
第二和第三个参数分别是内核的尺寸以及锚点的位置。一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得
getStructuringElement函数的返回值: 对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心点。element形状唯一依赖锚点位置,其他情况下,锚点只是影响了形态学运算结果的偏移。
代码:
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))
12.dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
参数 描述
src 原图像
dst 目标图像,与原图像尺寸和通过数相同
ddepth 目标图像的所需深度
kernel 卷积核(或相当于相关核),单通道浮点矩阵;如果要将不同的内核应用于不同的通道,请使用拆分将图像拆分为单独的颜色平面,然后单独处理它们。
anchor 内核的锚点,指示内核中过滤点的相对位置;锚应位于内核中;默认值(-1,-1)表示锚位于内核中心。
detal 在将它们存储在dst中之前,将可选值添加到已过滤的像素中。类似于偏置。
borderType 像素外推法,参见BorderTypes
13.np.argmax()
找最大值
14.cv2.convexHull(max_cont, returnPoints=False)
returnPoints 默认值为 True。它会返回凸包上点的坐标。如果设置为 False,就会返回与凸包点对应的轮廓上的点。
15.defect = cv2.convexityDefects(cnt,hull)
它会返回一个数组,每一行的值为[起点,终点,最远的点,到最远点的近似距离]。我们可以在一张图上显示它。我们将起点和终点用一天绿线连接,在最远点画一个圆圈。记住返回的前三个值是点在轮廓中的索引,所以要到轮廓中去找到它们: