opencv 使用cv.rotate和cv.warpAffine时旋转图像的差异

ss2ws0br  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(121)

我已经观察到使用cv.warpAffine方法的旋转与使用cv.rotate方法的旋转之间存在差异。生成的图像是不同的-而cv.rotate是完美的,即没有图像部分被裁切的旋转图像,cv.warpAffine生成具有图像裁切部分的图像。随附了两种方法的示例图像和结果。
配置方式:Python:3.9.13; OpenCv-Python 4.7.0; Windows 10操作系统

  • 样品 *:

原文:
x1c 0d1x的数据
cv.rotate:



cv.warpAffine:


  • 重现问题的代码 *
>>> img = cv.imread(<path to image>, cv.IMREAD_GRAYSCALE)
>>> rot_img = cv.rotate(img, cv.ROTATE_90_COUNTERCLOCKWISE)
>>> cv.imwrite('cv_rotate.jpg', rot_img)
True
>>> img_center = (img.shape[1]//2, img.shape[0]//2)
>>> M = cv.getRotationMatrix2D(img_center, 90, 1)
>>> rot_img = cv.warpAffine(img, M, (img.shape[0], img.shape[1]))
>>> cv.imwrite('cv_warpAffine.jpg', rot_img)
True

字符串
我希望这两种方法都能生成相同的输出。为什么会有区别呢?我尝试了其他几种方法,预计我会把(row,col)格式和(x,y)格式搞混(为什么OpenCV在生成ndarray输出时使用不同的样式,我不知道),但这些方法都不起作用。谁能告诉我这里有什么问题吗?

0md85ypi

0md85ypi1#

如果您只需要90度旋转,请坚持使用cv.rotate()。这以90度的步长旋转。它不会重新采样或插值。
在评论中,Cris Luengo建议使用np.rot90(),这可能是一个非常便宜的操作,因为numpy可以计算新的步幅并给予原始数据的视图。cv.rotate()没有这样做,因为内部使用的cv::Mat不如numpy数组灵活。
如果旋转中心正确,则可以使用cv.getRotationMatrix2D()获得所需的结果。
如果你选择了 * 矩形 * 的中心,这将只是围绕该点旋转图像,并导致你已经看到的结果:结果是绿色矩形,红色矩形表示图像内容。


的数据
如果源和结果的左上原点重合,则矩形的90度旋转的“正确”旋转中心取决于矩形的边长和旋转方向。考虑两个正方形,矩形的每个边长各一个。旋转中心位于一个或另一个正方形的中心,这取决于方向。

...
>>> ih, iw = img.shape[:2]
>>> img_center = (iw-1)/2, (iw-1)/2
>>> M = cv.getRotationMatrix2D(img_center, +90, 1)
...

个字符

您也可以从原语构建自己的转换:

def translate(tx=0, ty=0):
    T = np.eye(3)
    T[:2, 2] = (tx, ty)
    return T

def rotate(angle):
    T = np.eye(3)
    T[:2, :] = cv.getRotationMatrix2D((0,0), angle, 1)
    # it's rotating counterclockwise in X-right, Y-down
    return T

angle = 90

(ih, iw) = img.shape[:2]
ow,oh = ih,iw # only valid for 90 degree rotation

icx, icy = (iw-1)/2, (ih-1)/2
ocx, ocy = (ow-1)/2, (oh-1)/2

T = translate(+ocx, +ocy) @ rotate(angle) @ translate(-icx, -icy)

rot_img = cv.warpAffine(img, M=T[:2], dsize=(ow, oh))



为了扭曲 * 点 * 而不是图像,有一个用于仿射变换的函数cv.transform()
点需要以形状为(N, 2)(N, 1, 2)的numpy数组的形式给出。
对于透视变换,有cv.perspectiveTransform()。它负责“除以w”。

相关问题