在 C++ 中使用来自 OpenCV 矩阵的 Eigen 将图像旋转 90 度
Rotate an image by 90 degrees using Eigen from OpenCV Matrix in C++
如何使用 OpenCV 矩阵中的 Eigen 将图像旋转 90 度,然后在 C++ 中将旋转后的图像转换回 OpenCV 矩阵。 OpenCV 的 rotate
功能需要时间,我想尽快完成。我尝试在 Python 中使用 Numpy rot90
函数,与 C++ 中的 OpenCV rotate
函数相比,它非常快。不幸的是,Numpy 不适用于 C++。我读过 C++ 中还有其他库,例如 Eigen 和 Armadillo,它们可以快速执行这些矩阵运算。这就是我想使用 Eigen 旋转图像并检查时间的原因。
我在 Windows 10 的 i5 机器上测试了 Visual Studio 2019 中的函数。 Python 中的 numpy rot90
函数大约比 OpenCV 快 10 倍rotate
C++ 函数。
我猜函数 warpAffine
更快。至少你应该比较检查。
这里有一个例子:
https://docs.opencv.org/master/dd/d52/tutorial_js_geometric_transformations.html。
cuda 可以使用相同类型的函数:
https://docs.opencv.org/master/db/d29/group__cudawarping.html
编辑:
OpenCV 中的 warpAffine
实际上可以使用英特尔性能基元库中的 ippiWarpAffine*
函数。这可能是可以获得的最快性能。如果您可以 运行 在具有 nvidia gpu 的平台上使用您的软件,则 cuda 版本预计会更快。性能取决于您使用的数据类型。如果你可以使用 8 位无符号图像,你可以更快。
编辑 2:
在评论说 warpAffine 较慢后,我 运行 进行了一些测试,有时它会更快。然而,与 numpy 的旋转相比,没有什么可比的,即使 cv2.flip 或 cv2.transpose 也慢得多。因此,我建议查看 this recommendation on Intel's developer zone,即使用 ippiRotate 和 ippiMirror 函数执行 90 度旋转。如果您真的有兴趣从 Intel cpu 获得最佳性能,那是我的猜测。还要注意多线程,IPP 中的一些函数可以是多线程的。最后,这取决于您是否寻找一种解决方案来旋转单个大图像或多个图像,数据类型,通道数量。使用 IPP 至少您可以使用适合您的数据类型的最佳函数。
此后在 python 中进行了一些试验,以与 numpy 的 rot90
函数进行比较。当然,结果会随着参数的变化而变化,但与 numpy 还是有很大的不同。从我的试验中也看不出 cv2.rotate 如此之快。
100x np.rot90 time : 0.001626729965209961
100x cv2.rotate time : 0.21501994132995605
100x cv2.transpose time : 0.18512678146362305
100x cv2.remap time : 0.6473801136016846
100x cv2.warpAffine time : 0.11946868896484375
import cv2
import numpy as np
import time
img = np.random.randint(0, 255, (1000, 1000, 3)).astype(np.uint8)
##################################
start = time.time()
for i in range(100):
rotated = np.rot90(img)
end = time.time()
print("100x np.rot90 time :", end - start)
##################################
start = time.time()
for i in range(100):
rotated = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)
end = time.time()
print("100x cv2.rotate time :", end - start)
##################################
start = time.time()
for i in range(100):
rotated = cv2.transpose(img, 1)
end = time.time()
print("100x cv2.transpose time :", end - start)
##################################
mapx, mapy = np.meshgrid(np.arange(0, img.shape[1]), np.arange(0, img.shape[0]))
mapx = mapx.transpose()
mapy = mapy.transpose()
start = time.time()
for i in range(100):
rotated = cv2.remap(img, mapx.astype(np.float32), mapy.astype(np.float32), cv2.INTER_NEAREST)
end = time.time()
print("100x cv2.remap time :", end - start)
##################################
rows = img.shape[0]
cols = img.shape[1]
M = cv2.getRotationMatrix2D((rows / 2, cols / 2), 90, 1)
M[0, 2] = 0
M[1, 2] = cols
start = time.time()
for i in range(100):
rotated = cv2.warpAffine(img, M, (rows, cols), flags=cv2.INTER_NEAREST)
end = time.time()
print("100x cv2.warpAffine time :", end - start)
希望对您有所帮助!
如何使用 OpenCV 矩阵中的 Eigen 将图像旋转 90 度,然后在 C++ 中将旋转后的图像转换回 OpenCV 矩阵。 OpenCV 的 rotate
功能需要时间,我想尽快完成。我尝试在 Python 中使用 Numpy rot90
函数,与 C++ 中的 OpenCV rotate
函数相比,它非常快。不幸的是,Numpy 不适用于 C++。我读过 C++ 中还有其他库,例如 Eigen 和 Armadillo,它们可以快速执行这些矩阵运算。这就是我想使用 Eigen 旋转图像并检查时间的原因。
我在 Windows 10 的 i5 机器上测试了 Visual Studio 2019 中的函数。 Python 中的 numpy rot90
函数大约比 OpenCV 快 10 倍rotate
C++ 函数。
我猜函数 warpAffine
更快。至少你应该比较检查。
这里有一个例子:
https://docs.opencv.org/master/dd/d52/tutorial_js_geometric_transformations.html。
cuda 可以使用相同类型的函数:
https://docs.opencv.org/master/db/d29/group__cudawarping.html
编辑:
OpenCV 中的 warpAffine
实际上可以使用英特尔性能基元库中的 ippiWarpAffine*
函数。这可能是可以获得的最快性能。如果您可以 运行 在具有 nvidia gpu 的平台上使用您的软件,则 cuda 版本预计会更快。性能取决于您使用的数据类型。如果你可以使用 8 位无符号图像,你可以更快。
编辑 2:
在评论说 warpAffine 较慢后,我 运行 进行了一些测试,有时它会更快。然而,与 numpy 的旋转相比,没有什么可比的,即使 cv2.flip 或 cv2.transpose 也慢得多。因此,我建议查看 this recommendation on Intel's developer zone,即使用 ippiRotate 和 ippiMirror 函数执行 90 度旋转。如果您真的有兴趣从 Intel cpu 获得最佳性能,那是我的猜测。还要注意多线程,IPP 中的一些函数可以是多线程的。最后,这取决于您是否寻找一种解决方案来旋转单个大图像或多个图像,数据类型,通道数量。使用 IPP 至少您可以使用适合您的数据类型的最佳函数。
此后在 python 中进行了一些试验,以与 numpy 的 rot90
函数进行比较。当然,结果会随着参数的变化而变化,但与 numpy 还是有很大的不同。从我的试验中也看不出 cv2.rotate 如此之快。
100x np.rot90 time : 0.001626729965209961
100x cv2.rotate time : 0.21501994132995605
100x cv2.transpose time : 0.18512678146362305
100x cv2.remap time : 0.6473801136016846
100x cv2.warpAffine time : 0.11946868896484375
import cv2
import numpy as np
import time
img = np.random.randint(0, 255, (1000, 1000, 3)).astype(np.uint8)
##################################
start = time.time()
for i in range(100):
rotated = np.rot90(img)
end = time.time()
print("100x np.rot90 time :", end - start)
##################################
start = time.time()
for i in range(100):
rotated = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)
end = time.time()
print("100x cv2.rotate time :", end - start)
##################################
start = time.time()
for i in range(100):
rotated = cv2.transpose(img, 1)
end = time.time()
print("100x cv2.transpose time :", end - start)
##################################
mapx, mapy = np.meshgrid(np.arange(0, img.shape[1]), np.arange(0, img.shape[0]))
mapx = mapx.transpose()
mapy = mapy.transpose()
start = time.time()
for i in range(100):
rotated = cv2.remap(img, mapx.astype(np.float32), mapy.astype(np.float32), cv2.INTER_NEAREST)
end = time.time()
print("100x cv2.remap time :", end - start)
##################################
rows = img.shape[0]
cols = img.shape[1]
M = cv2.getRotationMatrix2D((rows / 2, cols / 2), 90, 1)
M[0, 2] = 0
M[1, 2] = cols
start = time.time()
for i in range(100):
rotated = cv2.warpAffine(img, M, (rows, cols), flags=cv2.INTER_NEAREST)
end = time.time()
print("100x cv2.warpAffine time :", end - start)
希望对您有所帮助!