【问题标题】:Shear an image without cropping在不裁剪的情况下剪切图像
【发布时间】:2018-07-02 05:42:20
【问题描述】:

我正在尝试使用 python 对图像进行剪切变换。我正在使用 skimage (scikit-image),opencv 或类似的也可以完成我认为的工作。问题是每当我尝试使用仿射变换和扭曲(skimage)进行剪切时,图像会出现“裁剪”或“裁剪”(“剪切”图像的某些部分丢失),这对于剪切变换移动像素(涉及像素的平移)。我需要支持图像比例的“画布”,以便“剪切”图像适合新图像,但保留输入图像的所有信息(附加图像)

【问题讨论】:

    标签: python scikit-image


    【解决方案1】:

    我遇到了同样的麻烦,我终于设法找到了一个与我测试的图像配合得很好的解决方案。我使用的是我想在图像上应用剪切、旋转和平移变换的事实。

    1. 首先,我们计算旋转所需的空间(不需要 计算如果不使用)。
    2. 其次,我们计算图像的最后一个像素所需的空间,该像素将通过剪切在图像中具有最大平移。
    3. 第三,我们需要计算必要的平移,以补偿剪切将移动图像中心这一事实。

    如果您希望所有图像的尺寸相同,请使用 45 度角,因为这个角度需要更多空间。

    import numpy as np
    import cv2
    
    #Parameters of the affine transform:
    angle = 45; #Angle in degrees.
    shear = 1;
    translation = 5;
    
    type_border = cv2.BORDER_CONSTANT;
    color_border = (255,255,255);
    
    original_image = cv2.imread(name_image_file);
    rows,cols,ch = original_image.shape;
    
    #First: Necessary space for the rotation
    M = cv2.getRotationMatrix2D((cols/2,rows/2), angle, 1);
    cos_part = np.abs(M[0, 0]); sin_part = np.abs(M[0, 1]);
    new_cols = int((rows * sin_part) + (cols * cos_part)); 
    new_rows = int((rows * cos_part) + (cols * sin_part));
    
    #Second: Necessary space for the shear
    new_cols += (shear*new_cols);
    new_rows += (shear*new_rows);
    
    #Calculate the space to add with border
    up_down = int((new_rows-rows)/2); left_right = int((new_cols-cols)/2);
    
    final_image = cv2.copyMakeBorder(original_image, up_down, up_down,left_right,left_right,type_border, value = color_border);
    rows,cols,ch = final_image.shape;
    
    #Application of the affine transform.
    M_rot = cv2.getRotationMatrix2D((cols/2,rows/2),angle,1);
    translat_center_x = -(shear*cols)/2;
    translat_center_y = -(shear*rows)/2;
    
    M = M_rot + np.float64([[0,shear,translation + translat_center_x], [shear,0,translation + translat_center_y]]);
    final_image  = cv2.warpAffine(final_image , M, (cols,rows),borderMode = type_border, borderValue = color_border);
    

    示例(我将“cv2.copyMakeBorder”和“cv2.getRotationMatrix2D”的边框设置为白色): 角度 = -45 度。剪切 = -0.5

    【讨论】:

    • 奇怪,它对我的​​图像中的负角和剪切不起作用,您使用的是哪个版本的 cv?
    • @Ilya.K. :在 2018 年的那个时候,可能在 OpenCV 3.4 版左右(不过那是很久以前的事了)。怎么做的原则应该保持不变,但也许他们改变了他们的功能。
    猜你喜欢
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    相关资源
    最近更新 更多