小强学Python+OpenCV之-1.4.1平移、旋转、缩放、翻转-之实践

小强学Python+OpenCV之-1.4.1平移、旋转、缩放、翻转-之实践

下面,我们对于本节的主题图片分别进行平移、旋转、缩放、翻转操作。
这里写图片描述

平移

首先,我们创建python脚本translation.py,并加入以下代码:

# 导入库
import numpy as np
import argparse
import cv2

# 定义平移translate函数
def translate(image, x, y):
    # 定义平移矩阵
    M = np.float32([[1, 0, x], [0, 1, y]])
    shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

    # 返回转换后的图像
    return shifted


# 构造参数解析器
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())

# 加载图像并显示
image = cv2.imread(args["image"])
cv2.imshow("Original", image)

# 将原图分别做上、下、左、右平移操作
shifted = translate(image, 0, 100)
cv2.imshow("Shifted Down", shifted)
shifted = translate(image, 0, -100)
cv2.imshow("Shifted Up", shifted)
shifted = translate(image, 50, 0)
cv2.imshow("Shifted Right", shifted)
shifted = translate(image, -50, 0)
cv2.imshow("Shifted Left", shifted)
cv2.waitKey(0)

执行脚本

python translation.py --image trip.jpg

显示如下:
Down

Up

Right

Left

旋转

创建python脚本rotation.py,并输入以下内容:

# 导入库
import numpy as np
import argparse
import cv2

# 定义旋转rotate函数
def rotate(image, angle, center=None, scale=1.0):
    # 获取图像尺寸
    (h, w) = image.shape[:2]

    # 若未指定旋转中心,则将图像中心设为旋转中心
    if center is None:
        center = (w / 2, h / 2)

    # 执行旋转
    M = cv2.getRotationMatrix2D(center, angle, scale)
    rotated = cv2.warpAffine(image, M, (w, h))

    # 返回旋转后的图像
    return rotated

# 构造参数解析器
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())

# 加载图像并显示
image = cv2.imread(args["image"])
cv2.imshow("Original", image)

# 将原图旋转不同角度
rotated = rotate(image, 45)
cv2.imshow("Rotated by 45 Degrees", rotated)
rotated = rotate(image, -45)
cv2.imshow("Rotated by -45 Degrees", rotated)
rotated = rotate(image, 90)
cv2.imshow("Rotated by 90 Degrees", rotated)
rotated = rotate(image, -90)
cv2.imshow("Rotated by -90 Degrees", rotated)
rotated = rotate(image, 180)
cv2.imshow("Rotated by 180 Degrees", rotated)
cv2.waitKey(0)

执行脚本

python rotation.py --image trip.jpg

45

-45

90

-90

180

缩放

这里我们要取一张尺寸较小,但比较清晰的图像。用来比较放大和缩小之间的质量是否有损失。

创建python脚本resize.py,并输入以下内容:

# 导入库
import argparse
import cv2

# 定义缩放resize函数
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
    # 初始化缩放比例,并获取图像尺寸
    dim = None
    (h, w) = image.shape[:2]

    # 如果宽度和高度均为0,则返回原图
    if width is None and height is None:
        return image

    # 宽度是0
    if width is None:
        # 则根据高度计算缩放比例
        r = height / float(h)
        dim = (int(w * r), height)

    # 如果高度为0
    else:
        # 根据宽度计算缩放比例
        r = width / float(w)
        dim = (width, int(h * r))

    # 缩放图像
    resized = cv2.resize(image, dim, interpolation=inter)

    # 返回缩放后的图像
    return resized


# 构造参数解析器
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())

# 加载参数并显示(由于原图较大,我们先将原图缩小)
image = cv2.imread(args["image"])
cv2.imshow("Original", image)

# 创建插值方法数组
methods = [
    ("cv2.INTER_NEAREST", cv2.INTER_NEAREST),
    ("cv2.INTER_LINEAR", cv2.INTER_LINEAR),
    ("cv2.INTER_AREA", cv2.INTER_AREA),
    ("cv2.INTER_CUBIC", cv2.INTER_CUBIC),
    ("cv2.INTER_LANCZOS4", cv2.INTER_LANCZOS4)]

# 循环执行插值方法数组中的各个方法
for (name, method) in methods:
    # 放大3倍
    resized = resize(image, width=image.shape[1] * 3, inter=method)
    cv2.imshow("ZoomIn Method: {}".format(name), resized)
    # 缩小2倍
    resized = resize(image, width=image.shape[1] /2, inter=method)
    cv2.imshow("ZoomOut Method: {}".format(name), resized)
    cv2.waitKey(0)

执行脚本

python resize.py --image motor.jpg

使用cv2.INTER_NEAREST插值方法,缩小和放大后的图分别如下:

ZoomOut Method:cv2.INTER_NEAREST

ZoomIn Method:cv2.INTER_NEAREST

使用cv2.INTER_LINEAR插值方法,缩小和放大后的图分别如下:

ZoomOut Method:cv2.INTER_LINEAR

ZoomIn Method:cv2.INTER_LINEAR

使用cv2.INTER_AREA插值方法,缩小和放大后的图分别如下:

ZoomOut Method:cv2.INTER_AREA

ZoomIn Method:cv2.INTER_AREA

使用cv2.INTER_CUBIC插值方法,缩小和放大后的图分别如下:

ZoomOut Method:cv2.INTER_CUBIC

ZoomIn Method:cv2.INTER_CUBIC

使用cv2.INTER_LANCZOS4插值方法,缩小和放大后的图分别如下:

ZoomOut Method:cv2.INTER_LANCZOS4

ZoomIn Method:cv2.INTER_LANCZOS4

总结

  1. 在一般情况下, cv2.INTER_NEAREST速度最快,但质量不高。如果资源非常有限,可以考虑使用。否则不选这个,尤其在上采样(增加)图像的大小时。
  2. 当增加(上采样)图像的大小时,可以考虑使用 cv2.INTER_LINEAR 和 cv2.INTER_CUBIC两种插值方法。 cv2.INTER_LINEAR 方法比 cv2.INTER_CUBIC 方法稍快,但无论哪个效果都不错。
  3. 当减小(下采样)的图像的大小,OpenCV的文档建议使用 cv2.INTER_AREA。PS.我感觉其实下采样各种方法都差不多,取速度最快的(cv2.INTER_NEAREST)就好。

翻转

创建python脚本flip.py,并输入以下内容:

# 导入库
import argparse
import cv2

# 构造参数解析器
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help = "Path to the image")
args = vars(ap.parse_args())

# 加载图像并显示
image = cv2.imread(args["image"])
cv2.imshow("Original", image)

# 横向翻转图像
flipped = cv2.flip(image, 1)
cv2.imshow("Flipped Horizontally", flipped)

# 纵向翻转图像
flipped = cv2.flip(image, 0)
cv2.imshow("Flipped Vertically", flipped)

# 同时在横向和纵向翻转图像
flipped = cv2.flip(image, -1)
cv2.imshow("Flipped Horizontally & Vertically", flipped)
cv2.waitKey(0)

执行脚本python flip.py --image motor.jpg
flip

总结

  1. 本节我们使用了函数,函数的定义为:
    a) def translate(image, x, y): 使用def定义,跟函数名及形参,然后是冒号
    b) 函数体缩进一个tab
    c) 如果有嵌套语句,依次缩进
  2. 缩放要注意保持纵横比。
  3. 缩放时,下采样的插值算法选择比较宽松,可选择cv2.INTER_AREA。上采样时,要根据情况选择。在一般情况下选择cv2.INTER_LINEAR。资源紧张时选择 cv2.INTER_NEAREST。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值