Python实现RGB等图片的图像插值算法

目录
  • 前言
  • RGB彩色图像和数组理解
  • 图片坐标对其
    • 左对齐
    • 中心对齐
  • 临近插值算法
  • 线性插值法
  • 双线性插值
  • 三种插值算法的综合使用
  • 附件

前言

问题:我们在放大图片的过程中,放大的目标图像和原图图像之间会存在不同。

放大的基本思想:

第一步:

将目标图像进行缩小到原图像的尺寸,虚拟的将二者进行对重叠在一起,这样目标图像上面的像素点就和原图像上面的像素点并不是一一对应的。

第二步:

将目标图像与原图像的像素点进行建立一个映射关系,这个像素点的映射关系不是单一的像素映射,因为我们把图片存放在三维数组里面,所以我们在得到图像的像素点时,我们是通过索引数组的高和宽,在坐标系中对应的就是x坐标、y坐标.

第三步:

怎样建立映射关系呢?

  • 最临近插值法
  • 线性插值法
  • 双线性插值法
  • 三线性插值法

本文中用到了前面三种插值算法,并且进行了代码实现,代码仅供参考,大佬随便看一下小菜鸡的就行了,还希望大佬能指出其中的错误或不足之处,跪谢。

RGB彩色图像和数组理解

对于这个图片读取到数组中形成的三维数组,我刚理解了很久,在网上找大佬的资料自己看等等,然后慢慢的才形成了自己的理解,大佬们都是纵说纷纭,自己走了很多弯路,这里吧我的理解写下来,第一,方便自以后学习查看;第二,方便和我一样的初学者理解。

先话不多说,直接上一个图:

这里我直接把彩色图片的三个通道数画成了三位图片显示出来方面自己理解。彩色图片是三通道的,分别为R、G、B,这三个通道的重叠,通过调节每个通道数灰度值的亮度,从而构成了五颜六色的彩色世界!!

红色区域为第0通道(R),以此类推,第1通道(G)、第2通道(B)。读取回来的数组是一个三维数组,这个三维数组又分为了很多二维矩阵,每个二维矩阵有三个列(三个通道)。上图中有多少个i(高h),就表示三维数组中有多少个二维数组,有多少个j(宽h),就表示二维数组有多少个行,通道数k表示通道数,彩色图像有三个通道,所以 k 是个固定值 3。

数组中的值怎么理解欸?

下面插入我这个灵魂画师的一张图示来说明吧哈哈哈哈哈哈(不禁默默的流下了眼泪)

上图中左边给出了一个图片读入到数组(假设)中的样子,不同颜色的线条表示组成的不同通道图片,然后再把这三个通道里面的图片按照上上图片一样堆叠起来,就构成了这个三维空间图了。

RGB图像的理解就说到这里吧,希望能帮助到和我一样的初学者少走弯路。

图片坐标对其

要问这公式怎么来的,第一个可以根据放大后像素点的位置成比例算出来,第二个公式暂时还没想出来咋个算出来的,要是有大佬给我指出来就好了。

在代码中有传入参数指定使用哪一种对齐方式align = left,该参数默认是居中对其center。

左对齐

src_X = dst_X*(src_Width/dst_Width)
src_Y = dst_Y*(src_Height/dst_Height)

这里的src_X 就是目标图像上的点映射到原图像上的x坐标点,同理src_Y 就是映射到原图像上的y坐标点。

dst_X表示目标图像的x坐标,dst_Y表示目标图像的y坐标。

中心对齐

src_X = (dst_X+0.5)*(src_Width/dst_Width) - 0.5
src_Y = (dst_Y+0.5)*(src_Height/dst_Height) - 0.5

这里的src_X 就是目标图像上的点映射到原图像上的x坐标点,同理src_Y 就是映射到原图像上的y坐 标点。

dst_X表示目标图像的x坐标,dst_Y表示目标图像的y坐标。

临近插值算法

最邻近插值算法是最简单的,我们算出来的坐标点:i ,j,使用round函数对其进行四舍五入,就可以得到img[i,j]这个像素点的临近值了(是一个像素值)。

这个图片中就能看出,A点是目标图像映射到原图像上面的位置,整个背景是原图像,图中的Q1、Q2、Q3、Q4四个点就是A点的最邻近的四个像素点。

最邻近插值算法的代码是最简单的,但是放大后的图片效果是最差的,下面看代码实现:

    def nearest_inter(self):
        """最邻近插值法"""

        new_img = np.zeros((self.goal_h, self.goal_w, self.goal_channel), dtype=np.uint8)
        for i in range(0, new_img.shape[0]):
            for j in range(0, new_img.shape[1]):
                src_i, src_j = self.convert2src_axes(i, j)
                new_img[i, j] = self.img[round(src_i), round(src_j)]
        return new_img

线性插值法

线性插值公式说白了就是,咱们数学中的直线的参数方程形式。我们知道两点可以确定一条直线,但是在确定好的这条直线中我们怎么确定直线中的某个点呢,这样我们就可以根据两条平行线之间的关系来建立该两点确定的直线方程。看下面的图(图是我在网上搬的,勿喷,侵删)

所以这样就能得该直线方程了。

这里给出线性插值算法的代码:

 def linear_inter(self):
        """线性插值算法"""
        new_img = np.zeros((self.goal_h, self.goal_w, self.goal_channel), dtype=np.uint8)
        for i in range(0, new_img.shape[0]):
            for j in range(0, new_img.shape[1]):
                src_i, src_j = self.convert2src_axes(i, j)
                if ((src_j - int(src_j)) == 0 and (src_i - int(src_i)) == 0) \
                        or ((src_i - int(src_i)) == 0) \
                        or (
                        (src_j - int(src_j)) == 0):  # 表明border_src_j是一个整数 如果是整数,直接将原图的灰度值付给目标图像即可
                    new_img[i, j] = self.img[round(src_i), round(src_j)]  # 直接将原图的灰度值赋值给目标图像即可
                else:
                    """否则进行向上和向下取整,然后进行(一维)线性插值算法"""
                    src_i, src_j = self.convert2src_axes(i, j)
                    j1 = int(src_j)  # 向下取整
                    j2 = math.ceil(src_j)  # 向上取整
                    new_img[i, j] = (j2 - src_j)*self.img[round(src_i), j1] + (src_j-j1)*self.img[round(src_i), j2]

        return new_img

双线性插值

双线性插值算法实现起来就比线性插值算法要难一些,本质上还是和线性插值算法一样,都是为了去找更目标图像映射到原图像上的点,把这个点周围尽像素尽可能多的信息传递到这个点中。线性插值使用到了周围的两个点,这里的双线性就是使用到了周围的四个点的像素值信息,所以理论上来说,采用双线线性插值算法的效果会明显优于线性插值算法(单线性插值算法)。更具体的图示我这里就不画出来了,就使用我自己手绘的简化版(因为懒),网上其他帖子讲得更加明白,这里只贴出我自己的理解,这样以后来看的时候也能一目了然。

图中的x就是图片的高h,y就是图片的宽度w,因为我们读出来的图片是彩色图片,所以这样操作的同时,图片的三个通道也会同步更新这样的操作。

下面给出双线性插值算法的python代码:

    def double_linear_inter(self):
        new_img = np.zeros((self.goal_h-2, self.goal_w-2, self.goal_channel), dtype=np.uint8)  # 这里减的目的就是为了可以进行向上向下取整
        for i in range(0, new_img.shape[0]):  # 减1的目的就是为了可以进行向上向下取整数
            for j in range(0, new_img.shape[1]):
                inner_src_i, inner_src_j = self.convert2src_axes(i, j)  # 将取得到的变量参数坐标映射到原图中,并且返回映射到原图中的坐标
                inner_i1 = int(inner_src_i)  # 对行进行向上向下取整数
                inner_i2 = math.ceil(inner_src_i)
                inner_j1 = int(inner_src_j)  # 对列进行向上向下取整数
                inner_j2 = math.ceil(inner_src_j)

                Q1 = (inner_j2 - inner_src_j) * self.img[inner_i1, inner_j1] + \
                     (inner_src_j - inner_j1) * self.img[inner_i1, inner_j2]
                Q2 = (inner_j2 - inner_src_j) * self.img[inner_i2, inner_j1] + \
                     (inner_src_j - inner_j1) * self.img[inner_i2, inner_j2]
                new_img[i, j] = (inner_i2 - inner_src_i) * Q1 + (inner_src_i - inner_i1) * Q2

        return new_img

三种插值算法的综合使用

在进行图片处理的时候,对于图片的四个角,没有四个或者两个邻域,所以四个角就采用最邻近插值算法实现,二上下,左右这几行,没有四个邻域,所以采用线性插值算法,其余中心部分每个点都有四个邻域,所以采用双线性插值算法来实现,这样的图片效果会更好,以下是这三种算法的具体实现:

 def all_transform(self):
        # source_h, source_w, source_channel = self.img.shape  # 获得原图像的高度,宽度和通道量
        # goal_h, goal_w = round(source_h*self.h_rate), round(source_w*self.w_rate)  # 将原图像的size进行按照传入进来的rate参数等比的放大
        # goal_channel = source_channel

        """进行图像转换了"""
        new_img = np.zeros((self.goal_h-1, self.goal_w-1, self.goal_channel), dtype=np.uint8)  # 得到一个空的数组用来存放转换后的值,即为新的图片

        """边界使用线性插值算法"""
        temp_row = [0,  new_img.shape[0]-1]
        # 上下两行进行线性插值
        for i in temp_row:
            # i -> h -> x
            # j -> w -> y
            for j in range(0, new_img.shape[1]):
                """边界线(除了四个角落)采用线性插值法"""
                t_border_src_i, t_border_src_j = self.convert2src_axes(i, j)
                if ((t_border_src_j - int(t_border_src_j)) == 0 and (t_border_src_i - int(t_border_src_i)) == 0) \
                        or (t_border_src_i - int(t_border_src_i)) == 0 \
                        or (t_border_src_j - int(t_border_src_j)) == 0:  # 表明t_border_src_j是一个整数 如果是整数,直接将原图的灰度值付给目标图像即可
                    new_img[i, j] = self.img[round(t_border_src_i), round(t_border_src_j)]  # 直接将原图的灰度值赋值给目标图像即可
                else:
                    """否则进行向上和向下取整,然后进行(一维)线性插值算法"""
                    t_border_src_i, t_border_src_j = self.convert2src_axes(i, j)
                    j1 = int(t_border_src_j)  # 向下取整
                    j2 = math.ceil(t_border_src_j)  # 向上取整
                    new_img[i, j] = self.img[round(t_border_src_i), j1] + (t_border_src_j - j1) * \
                                    (self.img[round(t_border_src_i), j2] - self.img[round(t_border_src_i), j1])
        # 左右两列进行线性插值
        temp_col = [0, new_img.shape[1]-1]
        for i in temp_col:
            # i -> w -> y
            # j -> h -> x
            for j in range(0, new_img.shape[0]):
                """边界线(除了四个角落)采用线性插值法"""
                t_border_src_i, t_border_src_j = self.convert2src_axes(i, j)
                if ((t_border_src_j - int(t_border_src_j)) == 0 and (t_border_src_i - int(t_border_src_i)) == 0) \
                        or (t_border_src_i - int(t_border_src_i)) == 0 \
                        or (t_border_src_j - int(t_border_src_j)) == 0:  # 表明border_src_j是一个整数 如果是整数,直接将原图的灰度值付给目标图像即可
                    new_img[j, i] = self.img[round(t_border_src_i), round(t_border_src_j)]  # 直接将原图的灰度值赋值给目标图像即可
                else:
                    """否则进行向上和向下取整,然后进行(一维)线性插值算法"""
                    t_border_src_i, t_border_src_j = self.convert2src_axes(j, i)
                    j1 = int(t_border_src_i)  # 向下取整
                    j2 = math.ceil(t_border_src_i)  # 向上取整
                    new_img[j, i] = self.img[j1, round(t_border_src_j)] + (t_border_src_i - j1) * \
                                    (self.img[j2, round(t_border_src_j)] - self.img[j1, round(t_border_src_j)])

        """四个角落(顶点)使用最临近插值算法"""
        corner_low = [0, new_img.shape[0]-1]
        corner_height = [0, new_img.shape[1]-1]
        for i in corner_low:
            for j in corner_height:
                src_i, src_j = self.convert2src_axes(i, j)
                new_img[i, j] = self.img[round(src_i), round(src_j)]

        """中间的使用双线性插值法"""
        for i in range(1, new_img.shape[0] - 1):  # 减1的目的就是为了可以进行向上向下取整数
            for j in range(1, new_img.shape[1] - 1):
                inner_src_i, inner_src_j = self.convert2src_axes(i, j)  # 将取得到的变量参数坐标映射到原图中,并且返回映射到原图中的坐标
                inner_i1 = int(inner_src_i)  # 对行进行向上向下取整数
                inner_i2 = math.ceil(inner_src_i)

                inner_j1 = int(inner_src_j)  # 对列进行向上向下取整数
                inner_j2 = math.ceil(inner_src_j)
                Q1 = (inner_j2 - inner_src_j) * self.img[inner_i1, inner_j1] + \
                     (inner_src_j - inner_j1) * self.img[inner_i1, inner_j2]
                Q2 = (inner_j2 - inner_src_j) * self.img[inner_i2, inner_j1] + \
                     (inner_src_j - inner_j1) * self.img[inner_i2, inner_j2]
                new_img[i, j] = (inner_i2 - inner_src_i) * Q1 + (inner_src_i - inner_i1) * Q2

        return new_img

附件

下面附上我这个插值算法所有的代码

import numpy as np
import cv2
import math
import logging

class Image_inter_lines(object):
    """设置传入参数"""

    def __init__(self, img, modify_size=(3, 3), *, align='center'):
        self.img = img
        self.h_rate = modify_size[0]  # 高度的缩放率
        self.w_rate = modify_size[1]  # 宽度的缩放率
        self.align = align  # 设置居中模式,进而进行判断其对齐方式

        self.source_h = img.shape[0]  # 对应 i 列  -> x
        self.source_w = img.shape[1]  # 对饮 j 列  -> y
        self.goal_channel = img.shape[2]  # 通道数

        self.goal_h = round(self.source_h * self.h_rate)  # 将原图像的size进行按照传入进来的rate参数等比的放大
        self.goal_w = round(self.source_w * self.w_rate)

        if self.align not in ['center', 'left']:
            logging.exception(f'{self.align} is not a valid align parameter')
            self.align = 'center'  # 如果传入的参数不是居中或者居左,则强制将其置为居中
            pass

    def set_rate(self, new_modify_size=(None, None)):
        self.h_rate = new_modify_size[0]
        self.w_rate = new_modify_size[1]

    def convert2src_axes(self, des_x, des_y):
        if self.align == 'left':  # 左对齐
            src_x = float(des_x * (self.source_w / self.goal_w))
            src_y = float(des_y * (self.source_h / self.goal_h))

            src_x = min((self.source_h - 1), src_x)
            src_y = min((self.source_w - 1), src_y)
        else:  # 几何中心对齐
            src_x = float(des_x * (self.source_w / self.goal_w) + 0.5 * (self.source_w / self.goal_w))
            src_y = float(des_y * (self.source_h / self.goal_h) + 0.5 * (self.source_h / self.goal_h))

            src_x = min((self.source_h - 1), src_x)
            src_y = min((self.source_w - 1), src_y)

        return src_x, src_y  # 这里返回的数值可以是小数,也可能是整数例如:23.00,但是这个数仍然是小数

    def nearest_inter(self):
        """最邻近插值法"""

        new_img = np.zeros((self.goal_h, self.goal_w, self.goal_channel), dtype=np.uint8)
        for i in range(0, new_img.shape[0]):
            for j in range(0, new_img.shape[1]):
                src_i, src_j = self.convert2src_axes(i, j)
                new_img[i, j] = self.img[round(src_i), round(src_j)]
        return new_img

    def linear_inter(self):
        """线性插值算法"""
        new_img = np.zeros((self.goal_h, self.goal_w, self.goal_channel), dtype=np.uint8)
        for i in range(0, new_img.shape[0]):
            for j in range(0, new_img.shape[1]):
                src_i, src_j = self.convert2src_axes(i, j)
                if ((src_j - int(src_j)) == 0 and (src_i - int(src_i)) == 0) \
                        or ((src_i - int(src_i)) == 0) \
                        or (
                        (src_j - int(src_j)) == 0):  # 表明t_border_src_j是一个整数 如果是整数,直接将原图的灰度值付给目标图像即可
                    new_img[i, j] = self.img[round(src_i), round(src_j)]  # 直接将原图的灰度值赋值给目标图像即可
                else:
                    """否则进行向上和向下取整,然后进行(一维)线性插值算法"""
                    src_i, src_j = self.convert2src_axes(i, j)
                    j1 = int(src_j)  # 向下取整
                    j2 = math.ceil(src_j)  # 向上取整
                    new_img[i, j] = (j2 - src_j)*self.img[round(src_i), j1] + (src_j-j1)*self.img[round(src_i), j2]

        return new_img

    def double_linear_inter(self):
        new_img = np.zeros((self.goal_h-2, self.goal_w-2, self.goal_channel), dtype=np.uint8)  # 这里减的目的就是为了可以进行向上向下取整
        for i in range(0, new_img.shape[0]):  # 减1的目的就是为了可以进行向上向下取整数
            for j in range(0, new_img.shape[1]):
                inner_src_i, inner_src_j = self.convert2src_axes(i, j)  # 将取得到的变量参数坐标映射到原图中,并且返回映射到原图中的坐标
                inner_i1 = int(inner_src_i)  # 对行进行向上向下取整数
                inner_i2 = math.ceil(inner_src_i)
                inner_j1 = int(inner_src_j)  # 对列进行向上向下取整数
                inner_j2 = math.ceil(inner_src_j)

                Q1 = (inner_j2 - inner_src_j) * self.img[inner_i1, inner_j1] + \
                     (inner_src_j - inner_j1) * self.img[inner_i1, inner_j2]
                Q2 = (inner_j2 - inner_src_j) * self.img[inner_i2, inner_j1] + \
                     (inner_src_j - inner_j1) * self.img[inner_i2, inner_j2]
                new_img[i, j] = (inner_i2 - inner_src_i) * Q1 + (inner_src_i - inner_i1) * Q2

        return new_img

    def all_transform(self):
        # source_h, source_w, source_channel = self.img.shape  # 获得原图像的高度,宽度和通道量
        # goal_h, goal_w = round(source_h*self.h_rate), round(source_w*self.w_rate)  # 将原图像的size进行按照传入进来的rate参数等比的放大
        # goal_channel = source_channel

        """进行图像转换了"""
        new_img = np.zeros((self.goal_h-1, self.goal_w-1, self.goal_channel), dtype=np.uint8)  # 得到一个空的数组用来存放转换后的值,即为新的图片

        """边界使用线性插值算法"""
        temp_row = [0,  new_img.shape[0]-1]
        # 上下两行进行线性插值
        for i in temp_row:
            # i -> h -> x
            # j -> w -> y
            for j in range(0, new_img.shape[1]):
                """边界线(除了四个角落)采用线性插值法"""
                t_border_src_i, t_border_src_j = self.convert2src_axes(i, j)
                if ((t_border_src_j - int(t_border_src_j)) == 0 and (t_border_src_i - int(t_border_src_i)) == 0) \
                        or (t_border_src_i - int(t_border_src_i)) == 0 \
                        or (t_border_src_j - int(t_border_src_j)) == 0:  # 表明t_border_src_j是一个整数 如果是整数,直接将原图的灰度值付给目标图像即可
                    new_img[i, j] = self.img[round(t_border_src_i), round(t_border_src_j)]  # 直接将原图的灰度值赋值给目标图像即可
                else:
                    """否则进行向上和向下取整,然后进行(一维)线性插值算法"""
                    t_border_src_i, t_border_src_j = self.convert2src_axes(i, j)
                    j1 = int(t_border_src_j)  # 向下取整
                    j2 = math.ceil(t_border_src_j)  # 向上取整
                    new_img[i, j] = self.img[round(t_border_src_i), j1] + (t_border_src_j - j1) * \
                                    (self.img[round(t_border_src_i), j2] - self.img[round(t_border_src_i), j1])
        # 左右两列进行线性插值
        temp_col = [0, new_img.shape[1]-1]
        for i in temp_col:
            # i -> w -> y
            # j -> h -> x
            for j in range(0, new_img.shape[0]):
                """边界线(除了四个角落)采用线性插值法"""
                t_border_src_i, t_border_src_j = self.convert2src_axes(i, j)
                if ((t_border_src_j - int(t_border_src_j)) == 0 and (t_border_src_i - int(t_border_src_i)) == 0) \
                        or (t_border_src_i - int(t_border_src_i)) == 0 \
                        or (t_border_src_j - int(t_border_src_j)) == 0:  # 表明border_src_j是一个整数 如果是整数,直接将原图的灰度值付给目标图像即可
                    new_img[j, i] = self.img[round(t_border_src_i), round(t_border_src_j)]  # 直接将原图的灰度值赋值给目标图像即可
                else:
                    """否则进行向上和向下取整,然后进行(一维)线性插值算法"""
                    t_border_src_i, t_border_src_j = self.convert2src_axes(j, i)
                    j1 = int(t_border_src_i)  # 向下取整
                    j2 = math.ceil(t_border_src_i)  # 向上取整
                    new_img[j, i] = self.img[j1, round(t_border_src_j)] + (t_border_src_i - j1) * \
                                    (self.img[j2, round(t_border_src_j)] - self.img[j1, round(t_border_src_j)])

        """四个角落(顶点)使用最临近插值算法"""
        corner_low = [0, new_img.shape[0]-1]
        corner_height = [0, new_img.shape[1]-1]
        for i in corner_low:
            for j in corner_height:
                src_i, src_j = self.convert2src_axes(i, j)
                new_img[i, j] = self.img[round(src_i), round(src_j)]

        """中间的使用双线性插值法"""
        for i in range(1, new_img.shape[0] - 1):  # 减1的目的就是为了可以进行向上向下取整数
            for j in range(1, new_img.shape[1] - 1):
                inner_src_i, inner_src_j = self.convert2src_axes(i, j)  # 将取得到的变量参数坐标映射到原图中,并且返回映射到原图中的坐标
                inner_i1 = int(inner_src_i)  # 对行进行向上向下取整数
                inner_i2 = math.ceil(inner_src_i)

                inner_j1 = int(inner_src_j)  # 对列进行向上向下取整数
                inner_j2 = math.ceil(inner_src_j)
                Q1 = (inner_j2 - inner_src_j) * self.img[inner_i1, inner_j1] + \
                     (inner_src_j - inner_j1) * self.img[inner_i1, inner_j2]
                Q2 = (inner_j2 - inner_src_j) * self.img[inner_i2, inner_j1] + \
                     (inner_src_j - inner_j1) * self.img[inner_i2, inner_j2]
                new_img[i, j] = (inner_i2 - inner_src_i) * Q1 + (inner_src_i - inner_i1) * Q2

        return new_img

if __name__ == '__main__':
    pic1 = cv2.imread(r'C:\Users\heshijie\Desktop\Py_study\image processing\Carmen.jpg')
    pic2 = cv2.imread(r'C:\Users\heshijie\Desktop\Py_study\image processing\girl.jpg')
    pic3 = cv2.imread(r'C:\Users\heshijie\Desktop\Py_study\image processing\architecture.jpg')
    Obj_pic1 = Image_inter_lines(pic1, modify_size=(2, 2), align='center')
    new_pic1 = Obj_pic1.nearest_inter()
    cv2.imshow('origin', pic1)
    cv2.imshow('nearest_inter', new_pic1)
    new_pic2 = Obj_pic1.linear_inter()
    cv2.imshow('liner_inter', new_pic2)
    new_pic3 = Obj_pic1.all_transform()
    cv2.imshow('double_liner_inter', new_pic3)

    cv2.waitKey()
 

到此这篇关于Python实现RGB等图片的图像插值算法的文章就介绍到这了,更多相关Python 图像插值算法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python-opencv 双线性插值实例

    我就废话不多说了,直接上代码吧! #coding=utf-8 import cv2 import numpy as np '''双线性插值''' img = cv2.imread('timg.jpeg', cv2.CV_LOAD_IMAGE_GRAYSCALE) # load the gray image cv2.imwrite('img.jpg', img) h, w = img.shape[:2] # shrink to half of the original a1 = np.array(

  • Python实现线性插值和三次样条插值的示例代码

    (1).函数 y = sin(x) (2).数据准备 #数据准备 X=np.arange(-np.pi,np.pi,1) #定义样本点X,从-pi到pi每次间隔1 Y= np.sin(X)#定义样本点Y,形成sin函数 new_x=np.arange(-np.pi,np.pi,0.1) #定义差值点 (3).样条插值 #进行样条差值 import scipy.interpolate as spi #进行一阶样条插值 ipo1=spi.splrep(X,Y,k=1) #样本点导入,生成参数 iy1

  • python 图像插值 最近邻、双线性、双三次实例

    最近邻: import cv2 import numpy as np def function(img): height,width,channels =img.shape emptyImage=np.zeros((2048,2048,channels),np.uint8) sh=2048/height sw=2048/width for i in range(2048): for j in range(2048): x=int(i/sh) y=int(j/sw) emptyImage[i,j]

  • python线性插值解析

    在缺失值填补上如果用前后的均值填补中间的均值,比如,0,空,1,我们希望中间填充0.5:或者0,空,空,1,我们希望中间填充0.33,0.67这样. 可以用pandas的函数进行填充,因为这个就是线性插值法 df..interpolate() dd=pd.DataFrame(data=[0,np.nan,np.nan,1]) dd.interpolate() 补充知识:线性插值公式简单推导 以上这篇python线性插值解析就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我

  • Python实现RGB等图片的图像插值算法

    目录 前言 RGB彩色图像和数组理解 图片坐标对其 左对齐 中心对齐 临近插值算法 线性插值法 双线性插值 三种插值算法的综合使用 附件 前言 问题:我们在放大图片的过程中,放大的目标图像和原图图像之间会存在不同. 放大的基本思想: 第一步: 将目标图像进行缩小到原图像的尺寸,虚拟的将二者进行对重叠在一起,这样目标图像上面的像素点就和原图像上面的像素点并不是一一对应的. 第二步: 将目标图像与原图像的像素点进行建立一个映射关系,这个像素点的映射关系不是单一的像素映射,因为我们把图片存放在三维数组

  • Python 将RGB图像转换为Pytho灰度图像的实例

    问题: 我正尝试使用matplotlib读取RGB图像并将其转换为灰度. 在matlab中,我使用这个: img = rgb2gray(imread('image.png')); 在matplotlib tutorial中他们没有覆盖它.他们只是在图像中阅读 import matplotlib.image as mpimg img = mpimg.imread('image.png') 然后他们切片数组,但是这不是从我所了解的将RGB转换为灰度. lum_img = img[:,:,0] 编辑:

  • Python实现RGB与HSI颜色空间的互换方式

    概要 这是这学期数字图像处理课的第一份作业好久没懂python手都快生了,调了好久才搞出来. HSI颜色模型是一个满足计算机数字化颜色管理需要的高度抽象模拟的数学模型.HIS模型是从人的视觉系统出发,直接使用颜色三要素–色调(Hue).饱和度(Saturation)和亮度(Intensity,有时也翻译作密度或灰度)来描述颜色. RGB向HSI模型的转换是由一个基于笛卡尔直角坐标系的单位立方体向基于圆柱极坐标的双锥体的转换.基本要求是将RGB中的亮度因素分离,通常将色调和饱和度统称为色度,用来表

  • Python OpenCV中的numpy与图像类型转换操作

    Python OpenCV存储图像使用的是Numpy存储,所以可以将Numpy当做图像类型操作,操作之前还需进行类型转换,转换到int8类型 import cv2 import numpy as np # 使用numpy方式创建一个二维数组 img = np.ones((100,100)) # 转换成int8类型 img = np.int8(img) # 颜色空间转换,单通道转换成多通道, 可选可不选 img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) cv2

  • 详解Python+opencv裁剪/截取图片的几种方式

    前言 在计算机视觉任务中,如图像分类,图像数据集必不可少.自己采集的图片往往存在很多噪声或无用信息会影响模型训练.因此,需要对图片进行裁剪处理,以防止图片边缘无用信息对模型造成影响.本文介绍几种图片裁剪的方式,供大家参考. 一.手动单张裁剪/截取 selectROI:选择感兴趣区域,边界框框选x,y,w,h selectROI(windowName, img, showCrosshair=None, fromCenter=None): . 参数windowName:选择的区域被显示在的窗口的名字

  • Python列表删除重复元素与图像相似度判断及删除实例代码

    发现问题 项目需要,需要删除文件夹中的冗余图片.涉及图像文件名的操作,图像文件名存储在list中 python list删除元素有remove()和pop(),remove()对元素进行操作,pop()对索引进行操作,并会返回pop掉的值.一个只会从列表移除一个数 一.如果已经有了一个列表l,令h=l,对l操作时同时会影响h,貌似原因是内存共享的,正确的方法是h=l.copy() 二.测试时,发现一个问题,如下面代码和结果: item=2时,并没有把2全部删掉,后面重复的3也没有删去. **查阅

  • Python对接PicGo实现图片自动加水印并上传操作示例

    目录 1. 天下苦搬运党久矣 2. 目前的图床管理工具 3. 方案的设想 4. 代码完整解析 4.1 定义热键并监听键盘 第一步:先定义好你的热键 第二步:监听所有的键盘动作 4.2 从内存中读取图像 4.3 添加水印生成新图像 4.4 将新图像重新放入剪切板 4.5 模拟触发 PicGo 4.6 通知 Mac 通知台 5. 其他设置工作 5.1 设置程序权限 5.2 设置开机自启 6. 运行效果 7. 写在最后 1. 天下苦搬运党久矣 对于我这样经常需要写点文章的技术自媒体来说,很经常早上我才

  • python实现RGB与YCBCR颜色空间转换

    目录 前言: 1.灰度值和亮度的关系 2.RGB颜色空间与颜色控制 3.YCbCr颜色空间及与RGB的变换关系 前言: 人类如何感知或者理解颜色是个非常复杂的问题,本文不讨论如何从生物学或者心理学角度来分析颜色,而是分析“数值大小如何影响颜色”.文中主要介绍了RGB与YCbCr颜色空间概念的与变换关系. 1.灰度值和亮度的关系 人类能够从灰度图像中获取理解场景需要的大部分信息,所以看黑白电视机并不会严重影响人对视频中场景的理解.图像的亮度和像素值成正比,如果需要增加图像的亮度,比如从黑色逐渐过渡

  • Python比较两个图片相似度的方法

    本文实例讲述了Python比较两个图片相似度的方法.分享给大家供大家参考.具体分析如下: 这段代码实用pil模块比较两个图片的相似度,根据实际实用,代码虽短但效果不错,还是非常靠谱的,前提是图片要大一些,太小的图片不好比较.附件提供完整测试代码和对比用的图片. 复制代码 代码如下: #!/usr/bin/python # Filename: histsimilar.py # -*- coding: utf-8 -*- import Image def make_regalur_image(img

  • 用Python将动态GIF图片倒放播放的方法

    这次让我们一个用 Python 做一个小工具:将动态 GIF 图片倒序播放! GIF(Graphics Interchange Format) 是一种可以用来呈现动画效果的图片格式,原理就是保存很多帧(Frame)静态图像,然后连续呈现.很多简短的视频也会被转换成动态 GIF 呈现,压缩画质和去除声音之后可以有效地减小文件大小.网络上不计其数的搞笑动图,几乎承载了网友大半的欢乐,但是也有人发现,将正常的动画倒序播放往往可以获得更搞笑的效果,Reddit 上甚至有一个专门的节点:/r/revers

随机推荐