1. cv2.GaussianBlur()
def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None):
"""
使用高斯滤波器模糊图像
Argument:
src: 原图像
dst: 目标图像
ksize: 高斯核的大小;(width, height);两者都是正奇数;如果设为0,则可以根据sigma得到;
sigmaX: X方向的高斯核标准差;
sigmaY: Y方向的高斯核标准差;
如果sigmaY设为0,则与sigmaX相等;
如果两者都为0,则可以根据ksize来计算得到;
(推荐指定ksize,sigmaX,sigmaY)
borderType: pixel extrapolation method
"""
参考: https://www.cnblogs.com/chenzhen0530/p/10742536.html
https://blog.csdn.net/wuqindeyunque/article/details/103694900
2. cv2.imshow() 用来在窗口上显示图像。代码如下:
img = cv2.imread('3.jpg',1)
cv2.imshow('imshow',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.namedWindow()函数可以指定窗口是否可以调整大小。在默认情况下,标志为cv2.WINDOW_AUTOSIZE。但是,如果指定标志为cv2.WINDOW_Normal,则可以调整窗口的大小。当图像尺寸太大,并在窗口中添加跟踪条时,这些操作可以让我们的工作更方便一点。
cv2.waitKey(0): 是一个和键盘绑定的函数,它的作用是等待一个键盘的输入(因为我们创建的图片窗口如果没有这个函数的话会闪一下就消失了,所以如果需要让它持久输出,我们可以使用该函数)。它的参数是毫秒级。该函数等待任何键盘事件的指定毫秒。如果您在此期间按下任何键,程序将继续进行。我们也可以将其设置为一个特定的键。
cv2.destroyALLWindows(): 销毁我们创建的所有窗口。如果要销毁任何特定窗口,请使用函数cv2.destroyWindow(),其中传递确切的窗口名称作为参数。(应该是使用创建窗口时所使用的窗口名称,字符串类型。)
参考: https://blog.csdn.net/weixin_38383877/article/details/82659779
3. waitKey() 用于等待一段时间,接受用户按键。如果参数是 0, 那么循环就只执行一次,然后一直等待用户按键。如果参数不是 0,那么每次等待参数给定的 ms,如果没有按键,那么继续循环。
ord() 函数用来获得按键对应的 ASCII 码,用来和 waitKey() 返回值进行对比。
if cv2.waitKey(1) & 0xFF == ord("q"):
参考: https://blog.csdn.net/qq_39377418/article/details/101393007
https://www.runoob.com/python/python-func-ord.html
4. release() 用来释放视频,然后再调用 cv2.destroyAllWindows() 来关闭所有窗口。
参考: https://www.jianshu.com/p/949683764115
5. imutils.resize() 用来改变图像大小,但是不改变长宽比例。
参考: https://www.jianshu.com/p/bb34ddf2a947
6. cv2.cvtColor() 用来转换图像色彩。
def cvtColor(src, code, dst=None, dstCn=None):
"""
转换图像的颜色空间
Argument:
src: 原图像;
code: 指定颜色空间转换类型;
dst: 目标图像;与原图像大小深度一致;
dstCn: 指定目标图像通道数;默认None,则会根据src、code自动计算;
"""
参考: https://www.cnblogs.com/chenzhen0530/p/10741264.html
7. cv2.absdiff() 用来对图像求差,主要是对于灰度图。用来比较两幅图像的差别。
参考: https://blog.csdn.net/u014737138/article/details/80388482
https://zhuanlan.zhihu.com/p/42940310
8. cv2.threshold() 阈值函数。
def threshold(src, thresh, maxval, type, dst=None):
"""
设置固定级别的阈值应用于多通道矩阵
例如,将灰度图像变换二值图像,或去除指定级别的噪声,或过滤掉过小或者过大的像素点;
Argument:
src: 原图像
dst: 目标图像
thresh: 阈值
type: 指定阈值类型;下面会列出具体类型;
maxval: 当type指定为THRESH_BINARY或THRESH_BINARY_INV时,需要设置该值;
"""
参考: https://www.cnblogs.com/chenzhen0530/p/10742540.html
https://www.cnblogs.com/yinliang-liang/p/9293310.html
9. cv2.dilate() 形态学膨胀。用于白色增大。
dst = cv2.dilate(src,kernel,anchor,iterations,borderType,borderValue)
src: 输入图像对象矩阵,为二值化图像
kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得
anchor:锚点,默认为(-1,-1)
iterations:腐蚀操作的次数,默认为1
borderType: 边界种类
borderValue:边界值
参考: https://www.cnblogs.com/silence-cho/p/11069903.html
https://zhuanlan.zhihu.com/p/110330329
https://www.aiuai.cn/aifarm350.html
https://www.cnblogs.com/my-love-is-python/p/10394908.html
10. cv2.findContours() 查找轮廓,最好使用原图像的拷贝。
参考: https://www.cnblogs.com/wmy-ncut/p/9889294.html
https://blog.csdn.net/gaoranfighting/article/details/34877549
11. imutils.grab_contours 返回轮廓,是配合 cv2.findContours() 使用的。cv2.findContours()在就版本返回两个值,在新版本返回3个值,通过imutils.grab_contours 把返回中的轮廓拿到。
参考: https://blog.csdn.net/nima1994/article/details/90542992
13. cv2.contourArea() 对轮廓线求面积。
参考: https://blog.csdn.net/greatwall_sdut/article/details/108862018
14. cv2.boundingRect() 对找到的形状用最小的矩形框起来。
参考: https://www.cnblogs.com/Anita9002/p/8033101.html
15. cv2.rectangle() 用于在图像上画出一个矩形。
参考: https://blog.csdn.net/Gaowang_1/article/details/103087922
16. cv2.putText() 用于在图像上增加文字
参考: https://blog.csdn.net/GAN_player/article/details/78155283
17. cv2.FONT_HERSHEY_SIMPLEX 字体效果可以参考:
https://blog.csdn.net/hgkdzbf6/article/details/102093323
18. 形态学详细使用,包括不同的核的效果。
参考: https://blog.csdn.net/sunny2038/article/details/9137759
19. cv2.flip 图像翻转。
flip(src, flipCode[, dst])
flipCode Anno
1 水平翻转
0 垂直翻转
-1 水平垂直翻转
参考: https://blog.csdn.net/JNingWei/article/details/78753607
20. 从矩阵中取出一部分。
Mat() [15/29]
cv::Mat::Mat ( const Mat & m,
const Range & rowRange,
const Range & colRange = Range::all()
)
roi = frame[0 : 300, 0: 300]
注意第一组参数是 height / row,第二组参数是 width / col. 注意这个范围是 左闭右开的。
参考:https://docs.opencv.org/master/d3/d63/classcv_1_1Mat.html#a92a3e9e5911a2eb0cf0950a0a9670c76
21. 保持长宽比转换图像后,获得转换后的尺寸。
ret, frame = capture.read()
width = 500
frame = imutils.resize(frame, width)
height = frame.shape[1]
print("width %d, height %d\n" % (frame.shape[0], frame.shape[1]))
参考: https://vimsky.com/zh-tw/examples/detail/python-method-imutils.resize.html
22. 彩色图像转为 HSV 格式,主要用于图像前处理,然后会对某个颜色区间去做检测,主要用于去背景处理后的,物体检测。
色相(H):色彩的顏色名稱,如紅色、黃色等。
飽和度(S):色彩的純度,越高色彩越純,低則逐漸變灰,數值為0-100%。
明度(V):亮度,數值為0-100%。
hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
参考: https://shengyu7697.github.io/blog/2020/03/22/Python-OpenCV-rgb-to-hsv/
https://blog.csdn.net/u012193416/article/details/79312798
https://docs.opencv.org/3.4/da/d97/tutorial_threshold_inRange.html
23. 转换数组为 uint8 类型
skin = np.array([0, 20, 70], dtype = np.uint8)
参考: https://numpy.org/doc/stable/reference/generated/numpy.array.html
24. 检查数据是否在范围内,在范围内就设置为 255,不在范围内就设置为 0。也是一种对图像二值化的方法。
◆ inRange()
void cv::inRange ( InputArray src,
InputArray lowerb,
InputArray upperb,
OutputArray dst
)
Python:
dst = cv.inRange( src, lowerb, upperb[, dst] )
#include <opencv2/core.hpp>
Checks if array elements lie between the elements of two other arrays.
The function checks the range as follows:
For every element of a single-channel input array:
dst(I)=lowerb(I)0≤src(I)0≤upperb(I)0
For two-channel arrays:
dst(I)=lowerb(I)0≤src(I)0≤upperb(I)0∧lowerb(I)1≤src(I)1≤upperb(I)1
and so forth.
That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the specified 1D, 2D, 3D, ... box and 0 otherwise.
When the lower and/or upper boundary parameters are scalars, the indexes (I) at lowerb and upperb in the above formulas should be omitted.
mask = cv2.inRange(hsv, skin_low, skin_up)
25. 画轮廓线
contours = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = imutils.grab_contours(contours)
cv2.drawContours(frame, contours, -1, (0, 255, 0), 3)
参考: https://stackoverflow.com/questions/48948769/how-to-draw-contours-using-opencv-in-python
26. 计算轮廓周长或曲线长度
◆ arcLength()
double cv::arcLength ( InputArray curve,
bool closed
)
Python:
retval = cv.arcLength( curve, closed )
#include <opencv2/imgproc.hpp>
Calculates a contour perimeter or a curve length.
The function computes a curve length or a closed contour perimeter.
Parameters
curve Input vector of 2D points, stored in std::vector or Mat.
closed Flag indicating whether the curve is closed or not.
cv2.arcLength(cnt,True)
参考: https://docs.opencv.org/master/d3/dc0/group__imgproc__shape.html#ga8d26483c636be6b35c3ec6335798a47c
https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.html
27. 用更少顶点的曲线或多边形来逼近给定的曲线或多边形
◆ approxPolyDP()
void cv::approxPolyDP ( InputArray curve,
OutputArray approxCurve,
double epsilon,
bool closed
)
Python:
approxCurve = cv.approxPolyDP( curve, epsilon, closed[, approxCurve] )
#include <opencv2/imgproc.hpp>
Approximates a polygonal curve(s) with the specified precision.
The function cv::approxPolyDP approximates a curve or a polygon with another curve/polygon with less vertices so that the distance between them is less or equal to the specified precision. It uses the Douglas-Peucker algorithm http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
Parameters
curve Input vector of a 2D point stored in std::vector or Mat
approxCurve Result of the approximation. The type should match the type of the input curve.
epsilon Parameter specifying the approximation accuracy. This is the maximum distance between the original curve and its approximation.
closed If true, the approximated curve is closed (its first and last vertices are connected). Otherwise, it is not closed.
epsilon = 0.0005 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
28. 寻找轮廓的凸包,可以用来手势识别
hull = cv2.convexHull(cnt)
参考: https://www.cnblogs.com/jclian91/p/9728488.html
https://kk665403.pixnet.net/blog/post/403518029-%5Bpython%5D-%E5%88%A9%E7%94%A8opencv%E7%B9%AA%E8%A3%BD%E5%87%B8%E5%8C%85(convexhull)-%E8%BC%AA%E5%BB%93(contour
29. 显示凸包,因为凸包是一维的,需要增加一维,才能通过 drawContours 显示出来。
hull = cv2.convexHull(cnt)
hull_list = []
hull_list.append(hull)
cv2.drawContours(frame, hull_list, -1, (0, 0, 255), 3)
参考: https://stackoverflow.com/questions/36683556/drawing-convex-hull-of-the-biggest-contour-using-opencv-c
https://docs.opencv.org/3.4/d7/d1d/tutorial_hull.html
https://docs.opencv.org/master/d7/d1d/tutorial_hull.html
30. 生成一个二维数组。
kernel = np.ones((3, 3), np.uint8)
返回的是一个二维数组
[[1 1 1]
[1 1 1]
[1 1 1]]
参考: https://numpy.org/doc/stable/reference/generated/numpy.ones.html
31. shape 不仅仅指的是一个图像的高度,宽度,像素通道数,其实也是指的图像本身矩阵的行数,列数,表示每个像素的数组长度。
通道数,灰度时候为 1, RGB 为 3, RGBA 为 4,RGB555 和 RGB565 是 2。 其实这样看就是字节数,用几个字节来表示像素。
RGB一个像素点的打印如下:
[22 22 15]
RGB 一行打印如下:
[[22 22 15]
[18 21 13]
...
[127 126 127]]
RGB 图像打印如下:
[[[22 22 15]
[18 21 13]
...
[127 126 127]]
...
[[10 15 16]
[15 13 12]
...
[5 5 5]]]
参考:https://blog.csdn.net/qq_28618765/article/details/78618724
https://blog.csdn.net/mvtechnology/article/details/9008499
32. 打印异常
import traceback
try:
2/0
except Exception as e:
traceback.print_exc()
参考: https://blog.csdn.net/feiyang5260/article/details/86661103
33. 用 lambda 来获取轮廓当中面积最大的那个:
cnt = max(contours, key = lambda x: cv2.contourArea(x))
参考: https://www.cnblogs.com/bjwu/articles/9028399.html
34. 凸性缺陷 函数是 convexityDefects
convexityDefects()
void cv::convexityDefects ( InputArray contour,
InputArray convexhull,
OutputArray convexityDefects
)
Python:
convexityDefects = cv.convexityDefects( contour, convexhull[, convexityDefects] )
epsilon = 0.0005 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
hull = cv2.convexHull(approx, returnPoints = False)
defects = cv2.convexityDefects(approx, hull)
如上: 首先对图像简化成简易多边形,然后是生成凸包,最后生成凸性缺陷。
打印 hull如下:
[[165]
[163]
[128]
[124]
...
[209]
[208]
[168]
[166]]
打印 defects 如下:
[[[166 168 167 114]]
[[168 208 189 10549]]
[[209 243 229 11994]]
...
[[122 124 123 114]]
[[124 128 125 181]]
[[128 163 152 1784]]
[[163 165 164 186]]]
defects 四个数是起始点,结束点,最远点,最远点到 hull 的距离。这些数值都是索引,用来索引的。
approx 打印如下:
[[[193 92]]
[[192 92]]
...
[[192 109]]
[[193 109]]]
for i in range(defects.shape[0]):
s, e, f, d = defects[i, 0]
start = tuple(approx[s][0])
end = tuple(approx[e][0])
far = tuple(approx[f][0])
pt = (100, 180)
如上,当 i = 0 的时候, sefd 从 defects 里面取出 第一行,第一列的数组,[166 168 167 114], 即 s = 166, e = 168, f = 167, d = 114。然后 start = tuple(approx[s][0]),即 从 approx 里面取出 166行 0 列的数组,然后转为元组。 这个数组只有两个数值,估计就是像素点的 x, y 值。
参考: https://docs.opencv.org/master/d3/dc0/group__imgproc__shape.html#gada4437098113fd8683c932e0567f47ba
https://docs.opencv.org/master/d7/d1d/tutorial_hull.html
https://zhuanlan.zhihu.com/p/56360621
https://vimsky.com/zh-tw/examples/detail/python-method-cv2.convexityDefects.html
https://zhuanlan.zhihu.com/p/140384182
35. 手势识别,需要用到凸包和缺陷。
可以参考:
https://blog.csdn.net/qq_41562704/article/details/88975569
https://zhuanlan.zhihu.com/p/140384182
https://www.pythonf.cn/read/29390
https://blog.csdn.net/weixin_44885615/article/details/97811684
36. putText 中文,使用 pil
import cv2
import numpy
from PIL import Image, ImageDraw, ImageFont
class EspVisionUtil:
@staticmethod
def cv2ImgAddText(img, txt, left, top, color = (0, 255, 0), size = 20):
# 判断是 opencv 的图片,就转换RGB因为 PIL 和 CV 的颜色格式不同
if (isinstance(img, numpy.ndarray)):
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 创建绘图对象
draw = ImageDraw.Draw(img)
# 字体格式
fontStyle = ImageFont.truetype("SourceHanSansCN-Light.otf", size,
encoding = "utf-8")
# 绘制文本
draw.text((left, top), txt, color, font = fontStyle)
# 转换 opencv 格式
return cv2.cvtColor(numpy.asarray(img), cv2.COLOR_RGB2BGR)
参考: https://blog.csdn.net/ctwy291314/article/details/91492048
https://www.cnblogs.com/vipstone/p/8998249.html
https://blog.csdn.net/javastart/article/details/88796482
https://blog.csdn.net/zizi7/article/details/70145150
https://www.cnblogs.com/arkenstone/p/6961453.html
https://www.cnblogs.com/YouXiangLiThon/p/7815124.html
https://blog.csdn.net/qq_41895190/article/details/90513453
https://zhuanlan.zhihu.com/p/161385206