mmcv和openCV两个库imcrop()和imresize()方法的对应【基础分析】
创始人
2024-03-20 20:34:21
0

🥇 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连
🎉 声明: 作为全网 AI 领域 干货最多的博主之一,❤️ 不负光阴不负卿 ❤️

0-9

文章目录

    • MMCV 全家桶
    • mmcv.imresize(img, (1000, 600), return_scale=True) 方法实现
    • 对应的 openCV 的 cv2.resize 方法
    • mmcv 中 imcrop(img, bboxes, scale=1.0, pad_fill=None) 方法
    • mmcv/image/geometric.py 文件分析
    • 📙 精选专栏

MMCV 全家桶

  • https://github.com/open-mmlab/mmcv/blob/master/README_zh-CN.md

是一个用于训练深度学习模型的基础库

1-90

有很多star数量较高的集成仓库方便开发者进行模型训练和部署的全流程搭建

1-9

mmcv.imresize(img, (1000, 600), return_scale=True) 方法实现

mmcv.imresize(img, (1000, 600), return_scale=True)

源码链接如下

  • https://github.com/open-mmlab/mmcv/blob/b9bdfeb6f6aa67372d18b2ed5a10de28fc179d11/mmcv/image/geometric.py

cv2_interp_codes = {'nearest': cv2.INTER_NEAREST,'bilinear': cv2.INTER_LINEAR,'bicubic': cv2.INTER_CUBIC,'area': cv2.INTER_AREA,'lanczos': cv2.INTER_LANCZOS4
}def imresize(img,size,return_scale=False,interpolation='bilinear',out=None,backend=None):"""Resize image to a given size.Args:img (ndarray): The input image.size (tuple[int]): Target size (w, h).return_scale (bool): Whether to return `w_scale` and `h_scale`.interpolation (str): Interpolation method, accepted values are"nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2'backend, "nearest", "bilinear" for 'pillow' backend.out (ndarray): The output destination.backend (str | None): The image resize backend type. Options are `cv2`,`pillow`, `None`. If backend is None, the global imread_backendspecified by ``mmcv.use_backend()`` will be used. Default: None.Returns:tuple | ndarray: (`resized_img`, `w_scale`, `h_scale`) or`resized_img`."""h, w = img.shape[:2]if backend is None:backend = imread_backendif backend not in ['cv2', 'pillow']:raise ValueError(f'backend: {backend} is not supported for resize.'f"Supported backends are 'cv2', 'pillow'")if backend == 'pillow':assert img.dtype == np.uint8, 'Pillow backend only support uint8 type'pil_image = Image.fromarray(img)pil_image = pil_image.resize(size, pillow_interp_codes[interpolation])resized_img = np.array(pil_image)else:resized_img = cv2.resize(img, size, dst=out, interpolation=cv2_interp_codes[interpolation])if not return_scale:return resized_imgelse:w_scale = size[0] / wh_scale = size[1] / hreturn resized_img, w_scale, 

对应的 openCV 的 cv2.resize 方法

resized_img = cv2.resize(img, size, dst=out, interpolation=cv2_interp_codes[interpolation])

mmcv 中 imcrop(img, bboxes, scale=1.0, pad_fill=None) 方法

调用方式

bboxes = np.array([10, 10, 100, 120])
patch = mmcv.imcrop(img, bboxes)
  • mmcv/image/geometric.py 源码实现
def imcrop(img, bboxes, scale=1.0, pad_fill=None):"""Crop image patches.3 steps: scale the bboxes -> clip bboxes -> crop and pad.Args:img (ndarray): Image to be cropped.bboxes (ndarray): Shape (k, 4) or (4, ), location of cropped bboxes.scale (float, optional): Scale ratio of bboxes, the default value1.0 means no padding.pad_fill (Number | list[Number]): Value to be filled for padding.Default: None, which means no padding.Returns:list[ndarray] | ndarray: The cropped image patches."""chn = 1 if img.ndim == 2 else img.shape[2]if pad_fill is not None:if isinstance(pad_fill, (int, float)):pad_fill = [pad_fill for _ in range(chn)]assert len(pad_fill) == chn_bboxes = bboxes[None, ...] if bboxes.ndim == 1 else bboxesscaled_bboxes = bbox_scaling(_bboxes, scale).astype(np.int32)clipped_bbox = bbox_clip(scaled_bboxes, img.shape)patches = []for i in range(clipped_bbox.shape[0]):x1, y1, x2, y2 = tuple(clipped_bbox[i, :])if pad_fill is None:patch = img[y1:y2 + 1, x1:x2 + 1, ...]else:_x1, _y1, _x2, _y2 = tuple(scaled_bboxes[i, :])if chn == 1:patch_shape = (_y2 - _y1 + 1, _x2 - _x1 + 1)else:patch_shape = (_y2 - _y1 + 1, _x2 - _x1 + 1, chn)patch = np.array(pad_fill, dtype=img.dtype) * np.ones(patch_shape, dtype=img.dtype)x_start = 0 if _x1 >= 0 else -_x1y_start = 0 if _y1 >= 0 else -_y1w = x2 - x1 + 1h = y2 - y1 + 1patch[y_start:y_start + h, x_start:x_start + w,...] = img[y1:y1 + h, x1:x1 + w, ...]patches.append(patch)if bboxes.ndim == 1:return patches[0]else:return patches

依赖方法

def bbox_clip(bboxes, img_shape):"""Clip bboxes to fit the image shape.Args:bboxes (ndarray): Shape (..., 4*k)img_shape (tuple[int]): (height, width) of the image.Returns:ndarray: Clipped bboxes."""assert bboxes.shape[-1] % 4 == 0cmin = np.empty(bboxes.shape[-1], dtype=bboxes.dtype)cmin[0::2] = img_shape[1] - 1cmin[1::2] = img_shape[0] - 1clipped_bboxes = np.maximum(np.minimum(bboxes, cmin), 0)return clipped_bboxesdef bbox_scaling(bboxes, scale, clip_shape=None):"""Scaling bboxes w.r.t the box center.Args:bboxes (ndarray): Shape(..., 4).scale (float): Scaling factor.clip_shape (tuple[int], optional): If specified, bboxes that exceed theboundary will be clipped according to the given shape (h, w).Returns:ndarray: Scaled bboxes."""if float(scale) == 1.0:scaled_bboxes = bboxes.copy()else:w = bboxes[..., 2] - bboxes[..., 0] + 1h = bboxes[..., 3] - bboxes[..., 1] + 1dw = (w * (scale - 1)) * 0.5dh = (h * (scale - 1)) * 0.5scaled_bboxes = bboxes + np.stack((-dw, -dh, dw, dh), axis=-1)if clip_shape is not None:return bbox_clip(scaled_bboxes, clip_shape)else:return scaled_bboxes

mmcv/image/geometric.py 文件分析

从头文件的import和基础代码分析,可以看到 mmcv 中是把 openCV 和 PIL 两个库的 image 处理集成到 geometric.py 各个方法中

import numbers
import warnings
from typing import Optional, Tupleimport cv2
import numpy as npfrom ..utils import to_2tuple
from .io import imread_backendtry:from PIL import Image
except ImportError:Image = None

📙 精选专栏


  • 🍊 深度学习模型训练推理——基础环境搭建推荐博文查阅顺序【基础安装—认真帮大家整理了】——【1024专刊】

计算机视觉领域 八大专栏、不少干货、有兴趣可了解一下

  • ❤️ 图像风格转换 —— 代码环境搭建 实战教程【关注即可阅】!
  • 💜 图像修复-代码环境搭建-知识总结 实战教程 【据说还行】
  • 💙 超分重建-代码环境搭建-知识总结 解秘如何让白月光更清晰【脱单神器】
  • 💛 YOLO专栏,只有实战,不讲道理 图像分类【建议收藏】!
  • 🍊 深度学习:环境搭建,一文读懂

  • 🍊 深度学习:趣学深度学习

  • 🍊 落地部署应用:模型部署之转换-加速-封装

  • 🍊 CV 和 语音数据集:数据集整理

  • 🍊 点赞 👍 收藏 ⭐留言 📝 都是博主坚持写作、更新高质量博文的最大动力!

9-9

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...