在图像+轮廓旋转后,覆盖的轮廓与OpenCV中的warpAffine不对齐

时间:2016-10-14 02:21:25

标签: opencv image-processing image-rotation affinetransform satellite-image

为了100%可重复,整个代码(和使用的图像)都在下面。enter image description here

以下是代码中的步骤。

  1. 我在图像上叠加轮廓([[386, 330], [398, 320], [382, 300], [370, 310], [386, 330]])。这样做很好。

  2. 使用warpAffine

  3. 将图像旋转θ(= 90)
  4. 在完全相同尺寸和相同旋转功能的虚拟图像中旋转轮廓中的每个点。

  5. 找到旋转点的坐标。

  6. 在旋转的图像上叠加旋转点。

  7. 我预计他们会排队,但他们

    可能是什么原因?

    #! /usr/bin/env python                                                                                             
    import numpy as np
    import cv2
    from shapely.geometry.polygon import LinearRing
    
    theta = 90
    image_path = 'image.tiff'
    orig_image = cv2.imread(image_path)
    
    wnd_str = 'unrotated'
    cv2.namedWindow(wnd_str,cv2.WINDOW_NORMAL)
    cv2.moveWindow(wnd_str, 0, 0)
    
    rows,cols, channels = orig_image.shape
    print 'Loaded image shape {}'.format(orig_image.shape)
    
    blank_image = np.zeros((rows, cols, 3), np.uint8)
    print 'Blank image shape {}'.format(blank_image.shape)
    
    M = cv2.getRotationMatrix2D((rows/2, cols/2), theta, 1.0)
    rot_image = cv2.warpAffine(orig_image, M, (rows, cols), flags=cv2.INTER_CUBIC+cv2.BORDER_CONSTANT)
    print 'Rotated image shape {}'.format(rot_image.shape)
    
    white = (255, 255, 255)
    
    #contours overlayed on unrotated image                                                                             
    pts = [[386, 330], [398, 320], [382, 300], [370, 310], [386, 330]]
    poly_pts = []
    for p in pts: poly_pts.append(p)
    poly_pts = np.array(poly_pts[0:-1], np.int32)
    poly_pts = poly_pts.reshape((-1,1,2))
    
    cv2.polylines(orig_image, [poly_pts], True, white, 1)
    cv2.imshow(wnd_str, orig_image)
    cv2.waitKey(0)
    
    #generate contours for the rotated image                                                                           
    rot_poly_pts = []
    for p in pts:
        x, y = p
    
        blank_image = np.zeros((rows, cols, 3), np.uint8)
    
        blank_image[x,y] = (255, 255, 255)
        blank_image_affine = cv2.warpAffine(blank_image, M, (rows, cols), flags=cv2.INTER_CUBIC+cv2.BORDER_CONSTANT)
    
        rotated_y, rotated_x, rotated_z = np.unravel_index(blank_image_affine.argmax(), blank_image_affine.shape)
    
        rot_poly_pts.append([rotated_x, rotated_y])
    
    rot_poly_pts = np.array(rot_poly_pts[0:-1], np.int32)
    rot_poly_pts = rot_poly_pts.reshape((-1,1,2))
    cv2.polylines(rot_image, [rot_poly_pts], True, white, 1)
    
    wnd_str = 'rotated {}'.format(theta)
    cv2.namedWindow(wnd_str,cv2.WINDOW_NORMAL)
    cv2.moveWindow(wnd_str, 0, 0)
    cv2.imshow(wnd_str, rot_image)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    
      [1]: https://i.stack.imgur.com/pyxmq.png
    

    这里是具有对齐轮廓的原始图像 enter image description here

    这里是旋转后的图像和叠加。 enter image description here

1 个答案:

答案 0 :(得分:1)

wrapAffine生成两边都有裁剪像素的图像。这个过程的有效替代方法是转置然后翻转。

dst = cv2.flip(img.transpose(1,0,2),0)

dst  = destination image;
img  = source image;

img.transpose(col,row,channel) = 1,0,2对应于此顺序,因为我们只想转置行和列并保持通道不受影响。

cv2.flip =用于对抗转置操作期间引起的镜像效果。根据您的源图片(横向或纵向)将旗帜改为01