最近在查找有关图像缩放之类的算法,因工作中需要用到诸如此类的图像处理算法就在网上了解了一下相关算法,以及其原理,并用Python实现,且亲自验证过,在次与大家分享。

  声明:本文代码示例针对的是planar格式的YUV数据,且只对Y分量做了缩放,因为平常工作中接触较多的是YUV格式的黑白图片,UV分量都是固定的0x80,所以针对UV分量没有做缩放操作。

先大概讲一下图像所方的原理,假设缩放之前的图像为src_img,分辨率为src_w*src_h,缩放之后的图像为dst_img,分辨率为dst_w*dst_h,那么我们可以利用缩放前后图像分辨率的比率来找两幅图像中像素点的对应关系,以及像素点值的对应关系。如src_im中的点S(x,y)经过缩放之后变成了dst_img中的点D(x',y'),那么点S到点D的映射存在这么一种关系:x / src_w = x' / dst_w; y / src_h = y' / dst_h。利用上述公式我们就可以得到,dst_img中所有点对应到src_img中的那个点,我们再去把这个点的像素值赋给dst_img中对应的点。这是邻近插值缩放算法最基本的思想,但是我们会发现有时候算出的坐标是个小数如(0.6,0.25)等等,那么这个点对应src_img中那个点呢?如果采取简单的四舍五入的话,那么这个点应该对应src_img中的点(1,0),这种四舍五入近似的插值算法,在图像放大后图像严重失真,容易形成严重的马赛克,那么虚拟点(0.6,0.25)像素值到底该怎么取值呢?最邻近双线性而插值算法认为,应该有点(0.6,0.25)周围四个点(0,0),(0,1),(1,0),(1,1)的像素值共同决定,那么究竟是怎么一种决定方式呢?很简单,按距离来分配权重,离得越近的点的像素值的权重自然要越大。公式如下:

f(i+u,j+v) = (1-u)*(1-v)*f(i,j) + (1-u)*v*f(i,j+1) + u*(1-v)*f(i+1,j) + u*v*f(i+1,j+1)

关于最邻近双线插值算法的原理,网上有很多详细的解释和推导,在此我也不再详细赘述了,直接上python的实现代码:

最近在工作中碰到了,自己的写的双线性缩放函数出来的结果和opencv resize函数出来的像素点的值不一样,在网上查了一下原因,是因为我选取的坐标顶点是图像的左上角(0,0)的位置,这样也能得到正确的缩放图像,但是质量不高,因为最右边和最下边几乎没有参与计算,所以opencv中选取了几何中心重合的方式去计算,具体可以再往上搜一下,先讲算法修 1 """ 2 @description:this module will use two classic way to scaling img.Read a img from a file and scale it to dst s 3

 @author:GWB

 @version:v0.0.0
"""
import os
import binascii
def get_min(a,b):
if a > b:
return b
else:
return a def get_max(a,b):
if a > b:
return a
else:
return b def read_img_from_bin_file(in_filename,list_data):
with open(in_filename,'rb') as fd: #open file
fd.seek(0,0) #relocate fd
while True: #while loop
t_byte = fd.read(1) #read one byte
if len(t_byte) == 0: #if reach the end of the file then break
break
else: #store the the t_byte into hex format
list_data.append(ord(t_byte))
fd.close() def img_scale_fuc(in_list_data,srcW,srcH,dstW,dstH,out_list_data):
rateW = (srcW*1.0 / dstW)
rateH = (srcH*1.0 / dstH)
data = 0
for i in range(0,dstH):
38     temp = rateH * (i + 0.5) -0.5
       y0 = int(temp)
       u = temp - y0
       y0 = get_max(0,get_min(y0,dstH - 2))
y1 = get_min((y0 + 1),(srcH - 1))
for j in range(0,dstW):
         temp = rateW * (j + 0.5) - 0.5
x0 = int(temp)
         v = temp - x0
         x0 = get_max(0,get_min(x0,srcW - 2))
x1 = get_min((x0 + 1),(srcW - 1))
w0 = ((1 - u)*(1 - v))
w1 = ((1 - u)*v)
w2 = (u*(1 - v))
w3 = (u*v)
p0 = in_list_data[y0*srcW + x0]
p1 = in_list_data[y1*srcW + x0]
p2 = in_list_data[y0*srcW + x1]
p3 = in_list_data[y1*srcW + x1]
#f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
data = int(w0*p0+w1*p1+w2*p2+w3*p3)
out_list_data.append('%.2X' % data) def write_data_to_text(out_filename,out_list_data):
with open(out_filename,'wb') as fd:
fd.seek(0,0)
for data in out_list_data:
fd.write(binascii.a2b_hex(data))
fd.close() list_data = []
out_list_data = [] in_filename = raw_input("Please input src file name:\n")
out_filename = raw_input("Please input dst file name:\n")
srcH = input("Please input srcH:\n")
srcW = input("Please input srcW:\n")
dstH = input("Please input dstH:\n")
dstW = input("Please input dstW:\n") read_img_from_bin_file(in_filename,list_data)
img_scale_fuc(list_data,srcW,srcH,dstW,dstH,out_list_data)
write_data_to_text(out_filename,out_list_data)

邻近双线性插值图像缩放的Python实现的更多相关文章

  1. opencv3 图像处理(一)图像缩放( python与c++ 实现)

    opencv3 图像处理 之 图像缩放( python与c++实现 ) 一. 主要函数介绍 1) 图像大小变换 Resize () 原型: void Resize(const CvArr* src,C ...

  2. OpenCV - opencv3 图像处理 之 图像缩放( python与c++实现 )

    转自:https://www.cnblogs.com/dyufei/p/8205121.html 一. 主要函数介绍 1) 图像大小变换 cvResize () 原型: voidcvResize(co ...

  3. c#数字图像处理(十)图像缩放

    图像几何变换(缩放.旋转)中的常用的插值算法 在图像几何变换的过程中,常用的插值方法有最邻近插值(近邻取样法).双线性内插值和三次卷积法. 最邻近插值: 这是一种最为简单的插值方法,在图像中最小的单位 ...

  4. OpenCV计算机视觉学习(11)——图像空间几何变换(图像缩放,图像旋转,图像翻转,图像平移,仿射变换,镜像变换)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 图像 ...

  5. 实现基于最近邻内插和双线性内插的图像缩放C++实现

    平时我们写图像处理的代码时,如果需要缩放图片,我们都是直接调用图像库的resize函数来完成图像的缩放.作为一个机器视觉或者图像处理算法的工作者,图像缩放代码的实现应该是必须掌握的.在众多图像缩放算法 ...

  6. 图像缩放_OpenCv

    图像缩放是一种比较简单的图像处理操作,这里给出opencv中的代码, opencv的版本C语言接口 int resize_c() { const char *pstrImageName = " ...

  7. opencv2 矩阵方式 resize图像缩放代码(转载)

    http://blog.sina.com.cn/s/blog_74a459380101r0yx.html opencv2 矩阵方式 resize图像缩放代码(转载) (2014-05-16 09:55 ...

  8. 【美工设计 - Adobe Illustrator】基本设置 (图像显示 | 图像缩放 | 置入导出 | 标尺 | 网格 | 参考线 | 画板)

    作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50232767 一. 基础操作 1. 设置图像显示效果 (1) ...

  9. 图像旋转与图像缩放及Matlab代码实现

    本周的作业是自己通过公式编写图像旋转与缩放的代码.今天先通过调用函数的方法来实现. 图像的旋转: A=imread('2.jpg'); J=imrotate(A, 30); subplot(1,2,1 ...

随机推荐

  1. PHP 经典有趣的算法

    原文:https://blog.csdn.net/a519395243/article/details/77942913 1.一群猴子排成一圈,按1,2,…,n依次编号.然后从第1只开始数,数到第m只 ...

  2. HNUSTOJ-1253 Babelfish(字典树)

    1253: Problem C: Babelfish 时间限制: 1 Sec  内存限制: 128 MB提交: 14  解决: 3[提交][状态][讨论版] 题目描述 Problem C: Babel ...

  3. 二、JVM — 垃圾回收

    JVM 垃圾回收 写在前面 本节常见面试题 本文导火索 1 揭开 JVM 内存分配与回收的神秘面纱 1.1 对象优先在 eden 区分配 1.2 大对象直接进入老年代 1.3 长期存活的对象将进入老年 ...

  4. 剑指offer-链表中环的入口结点-链表-python ***

    题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 思路 第一步,用两个快慢指针找环中相汇点.分别用slow, fast指向链表头部,slow每次走一步,fast每次 ...

  5. 14-jquery元素节点操作

    **创建节点** ```var Div = $('<div>');var Div2 = $('<div>这是一个div元素</div>');``` **插入节点** ...

  6. R语言模型选择之精度准则与最大值法问题

    在模型选择中我们一般用caret包train函数建立模型,并对模型进行评判 方法1: ) tr_control<-trainControl(method = ) # 创建随机森林模型 model ...

  7. linux MySQL 初始化数据库

    #创建数据目录并且初始化 /bin/mysql_install_db –user=mysql

  8. Zabbix--01 介绍及安装

    目录 一. 监控知识基本概述 1.为什么要使用监控 2.如何进行监控,比如我们需要监控磁盘的使用率 3.流行的监控工具 4.如果去到一家新公司,如何入手监控 二. 单机时代如何监控 三. zabbix ...

  9. 牛客练习赛49 E 筱玛爱游戏 (线性基+博弈)

    链接:https://ac.nowcoder.com/acm/contest/946/E 来源:牛客网 筱玛爱游戏 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  10. JavaScript设计模式 样例三 —— 装饰模式

    装饰模式(Decorator Pattern): 定义:在不改变原对象的情况下,动态的给对象添加一些额外的职责.就功能而言,装饰模式相比生成子类更为灵活. 目的:把类的核心职责和装饰功能区分开.可以去 ...