imutils
对一系列OpenCV函数进行二次封装,执行基本任务,如平移、旋转、调整大小和骨架提取。
1.安装
这个包假设您已经安装了NumPy和OpenCV(如果您打算使用opencv2matplotlib函数,还安装了matplotlib)。
要安装库,只需使用以下命令:
pip install imutils
2.对OpenCV函数的二次封装
让我们继续,看看我们可以用这个包做什么。
2.1平移
平移是指图像在x或y方向上的平移。要在OpenCV中平移图像,你需要提供(x, y)的平移量,表示为(tx, ty)以构造平移矩阵M:
M = [ 1 0 t x 0 1 t y ] M =
[ 1 0 t x 0 1 t y ] \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y\end{bmatrix} [1001txty]
M=[1001txty]
然后,您需要应用函数cv2. warpaffine
。
我们不再手工构造平移矩阵M,只需要调用imutils
的translate
函数。
import imutils
import cv2
img = cv2.imread("translate.png")
cv2.imshow("src", img)
# 向右平移图像25像素,向上平移图像75像素
translate_img = imutils.translate(img, 25, -75)
cv2.imshow("translate_img", translate_img)
cv2.waitKey()
2.2旋转
在OpenCV中旋转图像是通过调用cv2.getRotationMatrix2D
和cv2.warpAffine
来完成的。需要进一步注意提供图像旋转点的(x, y)坐标。这些调用会迅速增加计算,使代码变得笨重且可读性较差。imutils
中的rotate
函数可以帮助解决这个问题。
import imutils
import cv2
img = cv2.imread("translate.png")
cv2.imshow("src", img)
# 在角度上循环以旋转图像
for angle in range(0, 360, 90):
# 旋转图像并显示它
rotated = imutils.rotate(img, angle=angle) # 旋转后的图像在原图尺寸里面的部分,会丢失信息
# rotated = imutils.rotate_bound(img, angle=angle) # 旋转后的图像的最小外接矩形
cv2.imshow("Angle=%d" % (angle), rotated)
cv2.waitKey()
2.3缩放
在OpenCV中调整图像大小是通过调用cv2.resize
函数来完成的。然而,需要特别注意imutils.resize
确保长宽比是不变的。imutils
的这个resize
函数保持了长宽比,并提供了关键字参数width和height,以便图像可以调整到预期的宽度/高度,同时(1)保持长宽比,(2)确保图像的尺寸不必由开发人员显式计算。
另一个可选关键字参数inter
,也可以用于指定插值方法。
import imutils
import cv2
img = cv2.imread("translate.png")
cv2.imshow("src", img)
# 在不同的宽度上循环以调整图像的大小
for width in (400, 300, 200, 100):
# 调整图像大小并显示它
resized = imutils.resize(img, width=width)
cv2.imshow("Width=%dpx" % (width), resized)
cv2.waitKey()
2.4骨架化
骨架化是在图像中构建物体的“拓扑骨架”的过程,该物体被假定为黑色背景下的白色物体。OpenCV没有提供显式构造骨架的函数,但提供了形态和二进制函数来实现这一点。
为方便起见,可以利用imutils
的skeletonize
函数来构造图像的拓扑骨架。
第一个参数size是结构化元素内核的大小。一个可选参数structuring
,可以用来控制结构化元素-它默认为cv2.MORPH_RECT
,但可以是任何有效的结构元素。
import imutils
import cv2
logo = cv2.imread("pyimagesearch.jpg")
cv2.imshow("src", logo)
# 骨架提取
gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)
skeleton = imutils.skeletonize(gray, size=(3, 3))
cv2.imshow("Skeleton", skeleton)
cv2.waitKey()
2.5 Matplotlib显示图片
在OpenCV的Python绑定中,图像以BGR顺序表示为NumPy数组。当使用cv2.imshow
时,这工作得很好。但是,如果您打算使用Matplotlib,因为plt.imshow
函数假设图像是RGB顺序的。调用cv2.cvtColor
将解决这个问题,或者您可以使用opencv2matplotlib
函数。
import imutils
import cv2
import matplotlib.pyplot as plt
logo = cv2.imread("translate.png")
cv2.imshow("src", logo)
# 错误用法:显示图像时不转换颜色空间
plt.figure("Incorrect")
plt.imshow(logo)
# 正确用法:在使用plt.imshow之前转换颜色空间
plt.figure("Correct")
plt.imshow(imutils.opencv2matplotlib(logo))
plt.show()
cv2.waitKey()
3.imutils的源码
3.1平移
def translate(image, x, y):
# 定义平移矩阵并执行平移操作
M = np.float32([[1, 0, x], [0, 1, y]])
shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
# 返回平移后的图像
return shifted
3.2旋转
def rotate(image, angle, center=None, scale=1.0):
# 获取图像宽高
(h, w) = image.shape[:2]
# 如果center为None,则将其初始化为图像的中心
if center is None:
center = (w // 2, h // 2)
# 旋转实现
M = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(image, M, (w, h))
# 返回旋转后的图像
return rotated
3.3缩放
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
# 初始化要调整大小的图像的尺寸并获取图像大小
dim = None
(h, w) = image.shape[:2]
# 如果width和height都为None,则返回原始图像
if width is None and height is None:
return image
# 检查width是否为None
if width is None:
# 计算高度的比率和构造尺寸
r = height / float(h)
dim = (int(w * r), height)
# 否则,height为None
else:
# 计算宽度的比率和构造尺寸
r = width / float(w)
dim = (width, int(h * r))
# 调整图像大小
resized = cv2.resize(image, dim, interpolation=inter)
# 返回调整后的图像
return resized
3.4骨架化
def skeletonize(image, size, structuring=cv2.MORPH_RECT):
# 确定面积(即图像中的总像素数),
# 初始化输出的骨架图像,构造形态结构元素
area = image.shape[0] * image.shape[1]
skeleton = np.zeros(image.shape, dtype="uint8")
elem = cv2.getStructuringElement(structuring, size)
# 继续循环直到从图像中移除所有像素
while True:
# 使用结构元素腐蚀和膨胀图像
eroded = cv2.erode(image, elem)
temp = cv2.dilate(eroded, elem)
# 从原始图像中减去临时图像,然后在骨架和临时图像之间取位“或”
temp = cv2.subtract(image, temp)
skeleton = cv2.bitwise_or(skeleton, temp)
image = eroded.copy()
# 如果图像中没有更多的“白色”像素,那么就退出循环
if area == area - cv2.countNonZero(image):
break
# 返回骨架提取后的结果
return skeleton
3.5Matplotlib显示图片
def opencv2matplotlib(image):
# OpenCV以BGR顺序表示图像;然而,Matplotlib期望图像在RGB顺序,所以简单地从BGR转换为RGB并返回
return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
参考目录
https://www.pyimagesearch.com/2015/02/02/just-open-sourced-personal-imutils-package-series-opencv-convenience-functions/