在完成毕业设计后我再也没有碰过图像处理相关的东西,进入公司后也是作为前端开发学习和工作(于是乎才有了 Vue 的学习笔记),但是当我再开始做图像处理相关的事情时,我发现自己全然忘却了怎么调用函数,于是乎决定整理一份。
本人习惯import cv2 as cv
,所以下面的调用均以 cv 为准,格式中 dst 为目标图像的 mat 对象,src 为原始图像的 mat 对象(就是用 imread 读进去的那个)
获取图片的尺寸#
print 一下 src.shape,可以发现结果为(高度,宽度,通道数)
,那么获取图片的高度和宽度可以使用以下语句实现:
src_height, src_width = src.shape[0:2]
图像缩放函数 resize ()#
常用函数格式:
dst = cv.resize(src, dsize)
其中 dsize 为类似于(int(source_width / 2), int(source_height / 2))
形式的元组,代表了图片的放缩倍率,例子中是保持长宽比放缩了一半,参数可调。
图像颜色转换函数 cvtColor ()#
常用函数格式:
dst = cv.cvtColor(src, colorCode)
其中 colorCode 部分在库中有对应代码,例如cv.COLOR_RGB2GRAY
这样子的。
该函数常用于灰度化等。
图像降噪常用方法高斯模糊 GaussianBlur ()#
常用函数格式:
dst = cv.GaussianBlur(src, ksize, sigmaX)
ksize 为卷积核的大小,只能为正奇数元组,例如 (3, 3)、(5, 5) 这样子,通俗来讲就是邻域大小,对某个像素点周围多少像素在内的区域做处理,ksize 越大得到的越模糊。
sigmaX 实际上是σX
,指的是在图像 X 向的标准差,为必要参数,如果未指定σY
,则根据 X 的来设定
图像二值化函数 threshold ()#
常用函数格式:
dst = cv.threshold(src, thresh, maxval, type)
其中 thresh 为阈值,maxval 为被设置的最大值,仅当 type 为cv.THRESH_BINARY
或cv.THRESH_BINARY_INV
时生效
type 为二值化方法,在库中有对应值,如下所示:
cv.THRESH_BINARY
:当前点大于 thresh 时设置为 maxval 的值,否则为 0。
cv.THRESH_BINARY_INV
:当前点值大于阈值时,设置为 0,否则设置为 Maxval
THRESH_TRUNC
:当前点值大于阈值时,设置为阈值,否则不改变
THRESH_TOZERO
:当前点值大于阈值时,不改变,否则设置为 0
THRESH_TOZERO_INV
:当前点值大于阈值时,设置为 0,否则不改变
Canny 算子边缘检测 Canny ()#
常用函数格式:
dst = cv.Canny(src, thresh1, thresh2)
其中,像素值低于 thresh1 的会认为不是边缘,像素值高于 thresh2 的会认为是边缘,像素值为两个阈值之间的像素点若与被认为是边缘的像素点相邻,则也被认为是边缘。
轮廓检测 findContours () 与轮廓绘制 drawContours ()#
常用函数格式:
contours, hierarchy = cv.findContours(src, mode, method)
dst = cv.drawContours(src, contours, contoursIdx, color, thickness)
在 findContours 中,mode 为轮廓检索方式,例如cv.RETR_TREE
可以完全建立轮廓层级关系,method 为轮廓表示方式,例如cv.CHAIN_APPROX_SIMPLE
就是以尽量少的像素点表示轮廓。
在 drawContours 中,contours 就是上一步检测出的轮廓,contoursIdx 指绘制的轮廓编号,若为 - 1 则是绘制所有的轮廓,color 指颜色,可以用类似 (255, 0, 0) 这样的格式表示一个 RGB 颜色,thickness 指轮廓线的宽度,是一个非必须参数。
通常来讲对边缘检测之后的图进行轮廓检测,得到的轮廓效果一般很好。
霍夫变换 HoughLines ()#
常用函数格式:
lines = cv.HoughLines(src, rho, theta,thresh)
输出为一组检测到的直线,rho 为以像素为单位的距离精度,theta 为以弧度为单位的角度精度,这里使用了极坐标来表示直线,thresh 为阈值。在实际使用时若无特殊情况则一般为 1, np.pi/ 180, 0
该函数用于直线检测,应用场景为求角度进行旋正,例如以下代码用于旋转直线斜率对应的角度:
lines = cv.HoughLines(img_canny, 1, np.pi / 180, 0)
for rho, theta in lines[0]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * a)
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * a)
if x1 == x2 or y1 == y2:
continue
t = float(y2 - y1) / (x2 - x1)
rotate_angle = math.degrees(math.atan(t))
img_result = ndimage.rotate(img_resize, rotate_angle)