使用Python调整图像大小( 二 )


如果你有兴趣了解更多有关处理图像时幕后发生的事情 , 我鼓励你更多地查看“机器视觉”主题!这绝对是一个蓬勃发展的领域 。
做得足够好 , 就会有很多公司愿意为你的计算机视觉专业知识付出最高的代价 。自动驾驶 , IOT , 监视 , 你命名它;所有基本上依赖于处理图片(通常在Python或C++) 。
一个很好的起点是查看scikit image 。
OpenCVOpenCV可以用来作图像处理 。他使用C++编写并移植到了Python
import cv2def resize(fp: str, scale: Union[float, int]) -> np.ndarray:""" 调整图像大小 , 保持其比例Args:fp (str): 图像文件的路径参数scale (Union[float, int]): 百分比作为参数 。如:53Returns:image (np.ndarray): 按比例缩小的图片"""_scale = lambda dim, s: int(dim * s / 100)im: np.ndarray = cv2.imread(fp)width, height, channels = im.shapenew_width: int = _scale(width, scale)new_height: int = _scale(height, scale)new_dim: tuple = (new_width, new_height)return cv2.resize(src=https://www.isolves.com/it/cxkf/yy/Python/2020-09-27/im, dsize=new_dim, interpolation=cv2.INTER_LINEAR)interpolation参数的选项是cv2包中提供的flags之一:
INTER_NEAREST – 近邻插值INTER_LINEAR – 双线性插值(默认使用)INTER_AREA – 利用像素区域关系重新采样 。它可能是图像抽取的首选方法 。但是当图像被缩放时 , 它类似于INTER_NEAREST方法 。INTER_CUBIC – 一个大于4×4像素邻域的双三次插值INTER_LANCZOS4 – 一个大于8×8像素邻域的Lanczos插值返回后:
resized = resize("checkers.jpg", 50)print(resized.shape)plt.imshow(resized) # 也可以使用 cv2.imshow("name", image)
使用Python调整图像大小

文章插图
 
它做了我们所期望的 。图像从900像素高 , 900像素宽 , 到450×450(仍然有三个颜色通道) 。因为Jupyter Lab的matplotlib着色 , 上面的屏幕截图看起来不太好 。
Pillowpillow库在Image类上有一个调整大小的方法 。它的参数是:
size: (width, height)resample: 默认为BICUBIC. 重采样算法需要的参数 。box: 默认为None 。为一个4元组 , 定义了在参数(0,0 , 宽度 , 高度)内工作的图像矩形 。reducing_gap: 默认为None 。重新采样优化算法 , 使输出看起来更好 。以下是函数:
from PIL import Imagedef resize(fp: str, scale: Union[float, int]) -> np.ndarray:""" 调整图像大小 , 保持其比例Args:fp (str): 图像文件的路径参数scale (Union[float, int]): 百分比作为参数 。如:53Returns:image (np.ndarray): 按比例缩小的图片"""_scale = lambda dim, s: int(dim * s / 100)im = Image.open(fp)width, height = im.sizenew_width: int = _scale(width, scale)new_height: int = _scale(height, scale)new_dim: tuple = (new_width, new_height)return im.resize(new_dim)使用Pillow 的函数与OpenCV非常相似 。唯一的区别是PIL.Image.Image类具有用于访问图像(宽度、高度)的属性大小 。
结果是:
resized = resize("checkers.jpg", 30.5)print(resized.size)resized.show("resized image", resized)
使用Python调整图像大小

文章插图
 
请注意show方法如何打开操作系统的默认程序以查看图像的文件类型 。
创建命令行程序现在我们有了一个调整图像大小的函数 , 现在是时候让它有一个运行调整大小的用户界面了 。
调整一个图像的大小是可以的 。但我们希望能够批量处理图像 。
我们将要构建的接口将是最简单的接口:命令行实用程序 。
Pallets项目是Flask背后的天才社区 , 是一个Jinja模板引擎:Click(https://click.palletsprojects.com/en/7.x/ 。)
pip install clickClick是一个用于制作命令行程序的库 。这比使用普通的argparse或在if __name__ == '__main__':中启动一些if-then逻辑要好得多 。所以 , 我们将使用Click来装饰我们的图像调整器 。
下面是从命令行调整图像大小的完整脚本!
""" resize.py"""from __future__ import annotationsimport osimport globfrom pathlib import Pathimport sysimport clickfrom PIL import Image"""文档:https://pillow.readthedocs.io/en/5.1.x/handbook/image-file-formats.html"""SUPPORTED_FILE_TYPES: list[str] = [".jpg", ".png"]def name_file(fp: Path, suffix) -> str:return f"{fp.stem}{suffix}{fp.suffix}"def resize(fp: str, scale: Union[float, int]) -> Image:""" 调整图像大小 , 保持其比例Args:fp (str): 图像文件的路径参数scale (Union[float, int]): 百分比作为参数 。如:53Returns:image (np.ndarray): 按比例缩小的图片"""_scale = lambda dim, s: int(dim * s / 100)im: PIL.Image.Image = Image.open(fp)width, height = im.sizenew_width: int = _scale(width, scale)new_height: int = _scale(height, scale)new_dim: tuple = (new_width, new_height)return im.resize(new_dim)@click.command()@click.option("-p", "--pattern")@click.option("-s", "--scale", default=50, help="Percent as whole number to scale. eg. 40")@click.option("-q", "--quiet", default=False, is_flag=True, help="Suppresses stdout.")def main(pattern: str, scale: int, quiet: bool):for image in (images := Path().glob(pattern)):if image.suffix not in SUPPORTED_FILE_TYPES:continueim = resize(image, scale)nw, nh = im.sizesuffix: str = f"_{scale}_{nw}x{nh}"resize_name: str = name_file(image, suffix)_dir: Path = image.absolute().parentim.save(_dir / resize_name)if not quiet:print(f"resized image saved to {resize_name}.")if images == []:print(f"No images found at search pattern '{pattern}'.")returnif __name__ == '__main__':main()


推荐阅读