图像缩放算法 计算机视觉技术算法 概念+原理+实现Python版
图像缩放算法
前言概念原理步骤效果生成测试图片源码具体算法实现源码总结
前言
图像缩放是计算机视觉中的基础几何变换操作。图像缩放通过缩放矩阵将图像按照指定比例进行放大或缩小,同时调整图像尺寸。缩放操作涉及坐标变换和像素值插值,需要保持图像的宽高比。图像缩放在图像处理、特征提取、数据增强等领域有广泛应用。将详细介绍图像缩放的概念、原理和实现方法。
计算机视觉技术算法 概念+原理+实现
微信视频号:计算机视觉技术
微信公众号:计算机视觉技术




概念
图像缩放是一种几何变换,将图像的尺寸按照指定的缩放因子进行调整。对于原始图像中的每个像素位置(x, y),缩放后的新坐标为:

其中和分别是水平和垂直方向的缩放因子。如果缩放因子大于1,图像被放大;如果缩放因子小于1,图像被缩小;如果缩放因子等于1,图像尺寸不变。
图像缩放后会出现两个问题:一是缩放后的像素坐标可能不是整数,需要通过插值方法计算像素值;二是缩小图像时会出现信息丢失,放大图像时会出现模糊。
原理
图像缩放的工作原理分为两个主要步骤:坐标变换和像素插值。
坐标变换步骤根据缩放因子计算输出图像中的每个像素在原始图像中的对应位置。为了保持图像的质量,我们采用逆向映射的方式,即遍历输出图像的每个像素,计算它在原始图像中的对应位置。逆向映射可以避免输出图像中出现空洞。
缩放计算使用比例关系:输出图像的每个像素位置除以缩放因子,得到原始图像中的对应坐标。如果缩放因子为2,则输出图像的第200个像素对应原始图像的第100个像素。
像素插值步骤处理坐标不是整数的情况。由于缩放后的坐标可能落在原始图像的四个像素之间,需要通过插值方法计算该位置的像素值。双线性插值是常用的方法,它使用周围四个像素的值进行加权平均,能够提供较好的图像质量,避免锯齿效应。
步骤
图像缩放的具体实现步骤如下:
- 确定缩放因子(放大或缩小)
- 计算缩放后图像的宽度和高度
- 创建新的图像数组
- 遍历输出图像的每个像素:
- 将像素坐标除以缩放因子,计算原始图像中的对应坐标
- 判断坐标是否在原始图像范围内
- 如果在范围内,使用双线性插值计算像素值
- 如果超出范围,保持像素为黑色(或其他背景色)
- 输出缩放后的图像
效果

从处理结果可以观察到,图像中的所有物体都按照2倍的比例进行了放大。矩形、圆形和线条都保持了原有的形状,只是尺寸增大了。由于图像按照宽高比统一缩放,物体的形状和比例没有发生畸变。图像放大后,边缘变得更加平滑,这是因为双线性插值方法对像素值进行了平滑处理,避免了锯齿效应。文本笔画也相应变粗,但仍然保持清晰可读。放大后的图像尺寸从200×400变为400×800,对比图片采用上下居中排列的方式展示,便于直观比较缩放效果。
生成测试图片源码
生成测试图片的程序创建了一个200×400像素的黑色背景图像,并在其上绘制了多种几何形状。程序绘制了多个矩形、圆形和线条,这些形状具有不同的大小和位置,便于观察缩放效果。程序还绘制了一些嵌套的形状,如圆内有圆、矩形内有矩形等,这样可以更好地展示缩放操作对复杂结构的影响。
程序最后在图像底部100像素处居中绘制了"BUTIANYUN.COM"文本。整个测试图像包含了直线、曲线、封闭图形等不同类型的几何元素,能够全面展示图像缩放算法的效果。
import cv2import numpy as npdefgenerate_test_image(): image = np.zeros((200, 400, 3), dtype=np.uint8) cv2.rectangle(image, (175, 40), (225, 80), (255, 255, 255), -1) cv2.circle(image, (100, 60), 25, (255, 255, 255), -1) cv2.circle(image, (300, 60), 25, (255, 255, 255), -1) cv2.rectangle(image, (50, 100), (125, 140), (255, 255, 255), -1) cv2.rectangle(image, (275, 100), (350, 140), (255, 255, 255), -1) cv2.circle(image, (200, 60), 12, (200, 200, 200), -1) cv2.line(image, (25, 150), (375, 150), (255, 255, 255), 2) cv2.circle(image, (200, 120), 20, (200, 200, 200), -1) cv2.circle(image, (200, 120), 10, (255, 255, 255), -1) cv2.rectangle(image, (190, 110), (210, 130), (180, 180, 180), -1) cv2.circle(image, (87, 120), 10, (200, 200, 200), -1) cv2.circle(image, (312, 120), 10, (200, 200, 200), -1) small_circles = [ (75, 110), (90, 130), (100, 120), (110, 115), (290, 110), (305, 130), (315, 120), (325, 115) ]for x, y in small_circles: cv2.circle(image, (x, y), 2, (255, 255, 255), -1) cv2.line(image, (150, 170), (250, 170), (200, 200, 200), 2) font = cv2.FONT_HERSHEY_SIMPLEX text = 'BUTIANYUN.COM' font_scale = 0.6 thickness = 1 text_size = cv2.getTextSize(text, font, font_scale, thickness)[0] text_x = (400 - text_size[0]) // 2 text_y = 200 - 100 + text_size[1] // 2 cv2.putText(image, text, (text_x, text_y), font, font_scale, (255, 255, 255), thickness, cv2.LINE_AA) cv2.imwrite('butianyun_computer_vision_input.png', image) print('测试图片已生成:butianyun_computer_vision_input.png')if __name__ == '__main__': generate_test_image()
具体算法实现源码
具体实现代码中包含了图像缩放的完整实现过程。程序首先读取输入图像,然后调用缩放函数对图像进行2倍放大。缩放函数使用双线性插值方法保持图像质量。
缩放函数首先根据缩放因子计算新的图像尺寸,然后创建相应大小的输出图像。函数采用逆向映射的方式,遍历输出图像的每个像素位置,计算该位置在原始图像中的对应坐标。逆向映射可以避免输出图像中出现空洞。
对于每个输出像素,函数将其坐标除以缩放因子,得到原始图像中的对应坐标。函数检查计算出的坐标是否在原始图像范围内,如果超出范围则保持像素为黑色。如果在范围内,函数使用双线性插值计算像素值。
双线性插值首先找出原始坐标周围四个整数像素的位置,然后根据坐标的小数部分计算四个像素的权重,最后通过加权平均得到插值结果。这种方法能够在缩放后保持较好的图像质量,避免出现锯齿效应。
主函数创建一个画布,宽度取输入图像和输出图像宽度的最大值,高度为两者之和。将原始图像放置在上方居中位置,将缩放后的图像放置在下方居中位置。这样生成的对比图片采用上下居中排列的方式,便于直观比较缩放效果。合并后的图片保存为PNG格式的对比图。
# 图像缩放算法是计算机视觉中的基础几何变换操作。该算法通过缩放矩阵# 将图像按照指定比例进行放大或缩小,同时调整图像尺寸。缩放操作涉及# 坐标变换和像素值插值,需要保持图像的宽高比。图像缩放在图像# 处理、特征提取、数据增强等领域有广泛应用。该算法通过双线性插值保# 持图像质量,避免锯齿效应。############################################################# 微信公众号:计算机视觉技术# 微信视频号:计算机视觉技术# 网站 :BUTIANYUN.COM############################################################import cv2import numpy as npdefresize_image(image, scale_factor): height, width = image.shape new_height = int(height * scale_factor) new_width = int(width * scale_factor) resized = np.zeros((new_height, new_width), dtype=np.uint8)for i in range(new_height):for j in range(new_width): original_x = j / scale_factor original_y = i / scale_factorif original_x < width - 1and original_y < height - 1: x1 = int(original_x) x2 = min(x1 + 1, width - 1) y1 = int(original_y) y2 = min(y1 + 1, height - 1) dx = original_x - x1 dy = original_y - y1 top = (1 - dx) * image[y1, x1] + dx * image[y1, x2] bottom = (1 - dx) * image[y2, x1] + dx * image[y2, x2] resized[i, j] = int((1 - dy) * top + dy * bottom)return resizeddefmain(): input_image = cv2.imread('butianyun_computer_vision_input.png', cv2.IMREAD_GRAYSCALE)if input_image isNone: print('无法读取输入图片')return resized_image = resize_image(input_image, scale_factor=2) cv2.imwrite('butianyun_computer_vision_output.png', resized_image)# Combine original and resized images vertically# Create a canvas with width = max(width_input, width_output) input_height, input_width = input_image.shape output_height, output_width = resized_image.shape max_width = max(input_width, output_width) total_height = input_height + output_height combined = np.zeros((total_height, max_width), dtype=np.uint8)# Place input image at top center input_x_offset = (max_width - input_width) // 2 combined[0:input_height, input_x_offset:input_x_offset+input_width] = input_image# Place resized image below, centered output_x_offset = (max_width - output_width) // 2 combined[input_height:total_height, output_x_offset:output_x_offset+output_width] = resized_image cv2.imwrite('image_resize_comparison.png', combined)if __name__ == '__main__': main()
总结
图像缩放通过缩放因子和双线性插值实现图像尺寸的调整。缩放操作采用逆向映射方式,遍历输出图像的每个像素,计算其在原始图像中的对应位置,然后使用双线性插值计算像素值。这种方法避免了输出图像中出现空洞,同时保持了较好的图像质量。图像缩放在图像处理、特征提取、数据增强等领域有广泛应用。


评论