图像处理之几何变换(python实现)


通过几何变换不仅可以产生某种特殊的效果,而且可以简化图像处理过程和分析程序。图像的几何变换最重要的特征是仅改变像素的位置,而不改变图像的像素值。图像的几何变换按变换性质可分为五项的位置变换(平移、镜像、旋转)、图像的形状变换(放大、缩小、错切)等基本变换,以及图像的复合变换。

1.图像比例放缩

图像比例放缩是指将给定的图像在x、y轴方向按比例分别缩放 f x f_x fx倍和 f y f_y fy倍,从而获得一幅新的图像。如果 f x f_x fx= f y f_y fy,即在x轴和y轴方向缩放的比率相同,该比例缩放称为图像的全比例放缩。如果 f x ≠ f y f_x \neq f_y fx=fy,图像的比例放缩为改变原始图像的像素间的相对位置,产生几何畸变。比例放缩后图像中的像素在原图像中可能找不到对应的像素点,则此时需要进行插值处理,常见的插值处理方法为最邻近插值法和双线性插值法。
比例放缩前后 P 0 ( x , y ) 和 P ( x , y ) P_0(x,y)和P(x,y) P0(x,y)P(x,y)之间的关系用矩阵形式可表示为
[ x y 1 ] = [ f x 0 0 0 f y 0 0 0 1 ] ⋅ [ x 0 y 0 1 ] \left[ \begin{matrix} x\\ y\\ 1 \end{matrix} \right] = \left[ \begin{matrix} f_x&0&0\\ 0&f_y&0\\ 0&0&1 \end{matrix} \right]· \left[ \begin{matrix} x_0\\ y_0\\ 1 \end{matrix} \right] xy1=fx000fy0001x0y01
在Opencv中,使用函数cv2.resize() 实现对图像的缩放,该函数的具体形式为:
d s t = c v 2. r e s i z e ( s r c , d s i z e , f x , f y , i n t e r p o l a t i o n ) dst=cv2.resize(src,dsize,fx,fy,interpolation) dst=cv2.resize(src,dsize,fx,fy,interpolation)

  • dst代表输出图像
  • src代表输入图像
  • dsize代表输出图像大小
  • fx代表水平方向的缩放比例
  • fy代表垂直方向的缩放比例
  • interpolation代表插值方式,常见插值方式有cv2.INTER_NEAREST(最近邻域插值 )、cv2.INTER_LINEAR(双线性插值)、cv2.INTER_CUBIC(三次样条插值)
示例代码
cv.resize(img,None,fx=2,fy=2,interpolation=cv.INTER_LINEAR)

1.1最邻近插值法

将变换后图像中的原像素点的最邻近像素的灰度值赋给原图像的方法。当图像按全比例放大两倍,放大后图像中的(0,0)像素,对应于原图像的(0,0)像素;放大后图像中的(0,1)像素,对应于原图像的(0,0.5)像素,但该像素不存在,则近似为原图像(0,0)的像素;放大后图像中的(0,2)像素,对应于原图像的(0,1)像素;放大后图像中的(0,3)像素,对应于原图像的(0,1.5)像素,但该像素不存在,则近似为原图像(0,1)的像素,以此类推。

1.1.1自定义函数
    #p代表垂直放缩比例
    #q代表水平放缩比例
    def Inter_Neareast(self,img,q,p):
        h,w=img.shape[:2]
        print(h,w)
        new_img=[]
        # q=int(new_h/h)
        # p=int(new_w/w)
        for i in range(h*q):
            for j in range(w*p):
                new_img.append(
                    int(img[int(i/q),int(j/p)])
                )
        new_img=np.array(new_img).reshape(h*q,w*p)
        print(new_img.shape[:2])
        return new_img
1.1.2实现结果图

使用自定义最邻近插值函数和Opencv最邻近插值实现图像的比例放缩:
最邻近插值法

1.2双线性插值法

当求出的分数地址与像素点不一致时,求出其与周围4个像素点的距离比,根据该比率,由4个邻域的像素灰度值进行双线性插值。简化后的插值点(x,y)处的灰度值可由下式计算:
g ( x , y ) = ( 1 − q ) × [ ( 1 − p ) × f ( [ x ] , [ y ] ) + p × f ( [ x ] + 1 , [ y ] ) ] + q × [ ( 1 − p ) × f ( [ x ] , [ y ] + 1 ) + p × f ( [ x ] + 1 , [ y ] + 1 ) ] g(x,y)=(1-q) \times \left[(1-p)\times f([x],[y])+p\times f([x]+1,[y])\right]+q \times \left[(1-p)\times f([x],[y]+1)+p\times f([x]+1,[y]+1)\right] g(x,y)=(1q)×[(1p)×f([x],[y])+p×f([x]+1,[y])]+q×[(1p)×f([x],[y]+1)+p×f([x]+1,[y]+1)]
其中[x]、[y]分别代表不大于x、y的整数,f(x,y)为像素点(x,y)插值前的灰度值,g(x,y)代表像素点(x,y)插值后的灰度值,p代表x-[x],q代表y-[y]。

1.2.1自定义函数
    #p代表垂直放缩比例
    #q代表水平放缩比例
    def Inter_Linear(self,img,p,q):
        h,w=img.shape[:2]
        # q=int(new_h/h)
        # p=int(new_w/w)
        new_img=[]
        for i in range(w*p):
            for j in range(h*q):
                dstx=i/p-int(i/p)
                dsty=j/q-int(j/q)
                new_img.append(
                    int((1-dsty)*((1-dstx)*img[int(i/p),int(j/q)]+dstx*img[min(int(i/p)+1,h-1),int(j/q)])+
                    dsty*((1-dstx)*img[int(i/p),min(int(j/q)+1,w-1)]+dstx*img[min(int(i/p)+1,h-1),min(int(j/q)+1,w-1)]))
                )#列表会溢出,溢出时选择最大序号
        new_img=np.array(new_img).reshape(h*q,w*p)
        return new_img

注意:f([x]+1,[y])、f([x]+1,[y]+1)、f([x],[y]+1)会出现溢出,当溢出时,我们默认选择f(x,y)的 x m a x x_{max} xmax或者 y m a x y_{max} ymax,即图像高度和图像宽度。

1.2.2实现结果图

使用自定义双线性插值函数和Opencv双线性插值实现图像的比例放缩:
双线性插值

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿宇阿星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值