图像下采样与扭曲方法(一)

在模型训练中往往需要合成一些假数据来添加到数据中,来增强训练效果,但是合成的样本和真实样本有的时候相差太远,因此使用下采样和扭曲的方法来模拟真实场景的图片。


一、随机扭曲场
二、波浪形扭曲


前言

使用opencv + python的方法来进行实现


一、随机扭曲场

通过为每个像素生成随机位移向量来创建扭曲,类似透过毛玻璃或热浪观察的效果。这种方法产生无规律的、自然扰动般的扭曲,每次运行结果都不同,适合模拟真实世界中的不规则形变和数据增强。

代码如下(示例):

    def perspective_warp_downsample(image_path, scale_factor=0.4):
        img = cv2.imread(image_path)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

        # 下采样
        height, width = img.shape[:2]
        new_size = (int(width * scale_factor), int(height * scale_factor))
        downsampled = cv2.resize(img, new_size, interpolation=cv2.INTER_AREA)

        rows, cols = downsampled.shape[:2]

        # 源点(原图的四个角)
        src_points = np.float32([[0, 0], [cols - 1, 0], [0, rows - 1], [cols - 1, rows - 1]])
        # 目标点(创建透视扭曲)
        dst_points = np.float32([
            [10, 15],  # 左上角
            [cols - 15, 8],  # 右上角
            [5, rows - 10],  # 左下角
            [cols - 8, rows - 12]  # 右下角
        ])

        M = cv2.getPerspectiveTransform(src_points, dst_points)

        # 应用透视变换
        warped = cv2.warpPerspective(downsampled, M, (cols, rows))

        return downsampled, warped

二、波浪形扭曲

使用正弦/余弦函数创建规则的周期性波动效果,类似水面涟漪或布面褶皱。这种扭曲平滑连续且有规律,通过调整振幅和频率可以控制波浪的起伏程度,适合模拟自然波动和创建艺术化变形。

代码如下(示例):

def wave_warp_downsample(image_path, scale_factor=0.4, wave_amplitude=3, wave_frequency=0.05):
    # 读取并下采样
    img = cv2.imread(image_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    # 下采样
    height, width = img.shape[:2]
    new_size = (int(width * scale_factor), int(height * scale_factor))
    downsampled = cv2.resize(img, new_size, interpolation=cv2.INTER_LANCZOS4)

    # 创建波浪扭曲
    rows, cols = downsampled.shape[:2]

    # 创建网格
    x, y = np.meshgrid(np.arange(cols), np.arange(rows))

    # 创建波浪效果
    wave_x = wave_amplitude * np.sin(wave_frequency * y)
    wave_y = wave_amplitude * np.cos(wave_frequency * x)

    # 应用扭曲
    map_x = x + wave_x
    map_y = y + wave_y

    warped = cv2.remap(downsampled, map_x.astype(np.float32), map_y.astype(np.float32),
                       cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT)

    return downsampled, warped

主函数
def main():
    test_img = np.random.randint(0, 255, (500, 500, 3), dtype=np.uint8)
    cv2.imwrite('test_image.jpg', test_img)

    methods = {
        '仿射变换': basic_downsample_and_warp,
        '透视变换': perspective_warp_downsample,
        '随机扭曲': random_warp_field_downsample,
        '波浪扭曲': wave_warp_downsample
    }

    plt.figure(figsize=(15, 10))

    for i, (name, method) in enumerate(methods.items(), 1):
        original, warped = method('test_image.jpg')

        plt.subplot(2, 4, i)
        plt.title(f'{name} - 下采样')
        plt.imshow(original)
        plt.axis('off')

        plt.subplot(2, 4, i + 4)
        plt.title(f'{name} - 扭曲后')
        plt.imshow(warped)
        plt.axis('off')

    plt.tight_layout()
    plt.show()


if __name__ == "__main__":
    main()




Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐