OpenCV实验(5):图像缩放

实验要求:
1)实现一个图像缩放函数,可以对输入图像进行任意倍数的缩放;
2)采用双线性插值进行重采样;
3)X,Y方向的缩放倍数参函数参数的形式传入;
4)可以只考虑输入图像为3通道,8位深度的情况;
5)不能调用图像处理库的缩放函数来完成;

参考函数:void Scale(const MyImage &input, MyImage &output, double sx, double sy);

实验思路:
1.其实这个和OpenCV实验(4)中的缩放是一样的,也都是双线性插值
2.由于函数要求传入imgDst也就是输出图像,所以为了传入一个维度相同的imgDst,写了一个makeImgDst的函数,会发现这个是明智之举
3.实验4和5的双线性插值根据
https://blog.csdn.net/pentiumCM/article/details/104720100

实验效果:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

实验代码:

import numpy as np
import cv2 as cv
import math


def Scale(imgSrc, imgDst, scaleRow, scaleCol):
    """
    双线性插值法,来调整图片尺寸

    :param imgSrc: 原始图片
    :param imgDst: 调整后的目标图片的尺寸
    :param scaleRow: x的倍数变化,eg. 0.5; 1; 2
    :param scaleCol: y的倍数变化,eg. 0.5; 1; 2
    :return: time 执行时间
    """
    timeBegin = cv.getTickCount()  # 记录开始时间
    rowsSrc, colsSrc, channels = imgSrc.shape
    rowsDst = int(rowsSrc*scaleRow)
    colsDst = int(colsSrc*scaleCol)
    # i:纵坐标y,j:横坐标x
    # 缩放因子,scaleCol 和 scaleRow,和函数的参数不一样
    scaleCol = colsSrc / colsDst
    scaleRow = rowsSrc / rowsDst

    for i in range(rowsDst):
        for j in range(colsDst):
            srcX = float((j + 0.5) * scaleCol - 0.5)
            srcY = float((i + 0.5) * scaleRow - 0.5)

            # 向下取整,代表靠近源点的左上角的那一点的行列号
            srcXint = math.floor(srcX)
            srcYint = math.floor(srcY)

            # 取出小数部分,用于构造权值
            srcXfloat = srcX - srcXint
            srcYfloat = srcY - srcYint

            if srcXint + 1 == colsSrc or srcYint + 1 == rowsSrc:
                imgDst[i, j, :] = imgSrc[srcYint, srcXint, :]
                continue
            imgDst[i, j, :] = (1. - srcYfloat) * (1. - srcXfloat) * imgSrc[srcYint, srcXint, :] + \
                               (1. - srcYfloat) * srcXfloat * imgSrc[srcYint, srcXint + 1, :] + \
                               srcYfloat * (1. - srcXfloat) * imgSrc[srcYint + 1, srcXint, :] + \
                               srcYfloat * srcXfloat * imgSrc[srcYint + 1, srcXint + 1, :]

    timeEnd = cv.getTickCount()  # 记录结束时间
    time = (timeEnd - timeBegin) / cv.getTickFrequency()  # 计算总时间
    imgDst.shape = imgDst.shape
    imgDst = imgDst.copy()
    return time


def makeImgDst(imgSrc, scaleRow, scaleCol):
    """
    返回一个imgDst,用于Scale中的第二个参数

    :param imgSrc: 原始图片
    :param scaleRow: x的倍数变化,eg. 0.5; 1; 2
    :param scaleCol: y的倍数变化,eg. 0.5; 1; 2
    :return: imgDst 输出图像
    """
    rowsSrc, colsSrc, channels = imgSrc.shape
    rowsDst = int(rowsSrc*scaleRow)
    colsDst = int(colsSrc*scaleCol)
    imgDst = np.zeros((rowsDst, colsDst, channels), dtype='uint8')
    return imgDst


# x和y轴的缩放倍数,该实验可尝试:x = 1.44, y = 0.64
x = float(input('The scale of X: '))
y = float(input('The scale of Y: '))
# 输入图像
imgSrc = cv.imread('../images/images3_1/lab2.png')
# 输出图像
imgDst = makeImgDst(imgSrc, x, y)
# 缩放
time = Scale(imgSrc, imgDst, x, y)

nameImg = 'scale x: %.2f scale y: %.2f' % (x, y)
cv.imshow('source', imgSrc)
cv.imshow(nameImg, imgDst)
print('\nSuccessful!!!')
print('Scale time: %.4f s' % time)
cv.waitKey(0)
cv.destroyAllWindows()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值