在进入频域变换之前, 我们还是轻松一下,再搞点平面上的变化来看看。这把选了一个双线性插值(Bilinear interpolation)来实现是源于看到了csdn上别人的问题, 权且实现一个函数,方便大家的使用吧。

双线性插值简单的说,就是扩展了之后的图像像素坐标映射回原来的坐标空间的时候, 如果出现了没有对应到整数点的情况。这时候需要做2次线性的插值计算出新的坐标的像素值,比如说:

这里可以看到这个P点落在了ABCD区间内, 如果我们本着最朴素的这个P点最靠近谁权重就越大的加权平均的思想, 我们很容易得到这样的论断:

A点对P的影响就是Sa的面积, B点的影响就是Sb, C点就Sc, d就是Sd。这样越近就是权重越大,基本上就是这样的逻辑。

这样P的像素可以简单的用 (A*Sa+B*Sb+C*Sc+D*Sd )/(Sa+Sb+Sc+Sd);来得到了。以我的雷厉风行,马上写出了如下的代码:

  1. /**
  2. ** method to remove sharp the raw image with unsharp mask
  3. * @param src input grayscale binary array
  4. * @param dst output grayscale result, the memory need to be allocated outside of the function
  5. * @param srcWidth width of the input grayscale image
  6. * @param srcHeight height of the input grayscale image
  7. * @param scalePercent, scale percentage (0-xxx)
  8. */
  9. void stretchImage (const unsigned char* src, unsigned char* dst, int srcWidth, int srcHeight, int scalePercent)
  10. {
  11. if (scalePercent < 0)
  12. return;
  13. int x, y;
  14. int ox, oy;
  15. int tmpx,tmpy;
  16. int ratio = (100 << 8)/scalePercent;
  17. int dstWidth = srcWidth * scalePercent / 100;
  18. int dstHeight = srcHeight * scalePercent / 100;
  19. unsigned char color[2][2];
  20. for (int j = 0; j < dstHeight; j ++)
  21. {
  22. for (int i = 0; i < dstWidth; i ++)
  23. {
  24. tmpx = i * ratio;
  25. tmpy = j * ratio;
  26. ox = tmpx >> 8;
  27. oy = tmpy >> 8;
  28. x = tmpx & 0xFF;
  29. y = tmpy & 0xFF;
  30. color[0][0] = src[ oy*srcWidth + ox ];
  31. color[1][0] = src[ oy*srcWidth + ox +1 ];
  32. color[0][1] = src[ (oy+1)*srcWidth + ox ];
  33. color[1][1] = src[ (oy+1)*srcWidth + ox+1 ];
  34. int final = (0x100 - x)*(0x100 - y)*color[0][0] + x*(0x100 - y)*color[1][0] + (0x100-x)*y*color[0][1] + x*y*color[1][1];
  35. final = final >> 16;
  36. if (final>255)
  37. final = 255;
  38. if (final<0)
  39. final = 0;
  40. dst [ j*dstWidth + i] = (unsigned char)final;
  41. }
  42. }
  43. }

/**
** method to remove sharp the raw image with unsharp mask
* @param src input grayscale binary array
* @param dst output grayscale result, the memory need to be allocated outside of the function
* @param srcWidth width of the input grayscale image
* @param srcHeight height of the input grayscale image
* @param scalePercent, scale percentage (0-xxx)
*/
void stretchImage (const unsigned char* src, unsigned char* dst, int srcWidth, int srcHeight, int scalePercent)
{
if (scalePercent < 0)
return;
int x, y;
int ox, oy;
int tmpx,tmpy;
int ratio = (100 << 8)/scalePercent;
int dstWidth = srcWidth * scalePercent / 100;
int dstHeight = srcHeight * scalePercent / 100;
unsigned char color[2][2];
for (int j = 0; j < dstHeight; j ++)
{
for (int i = 0; i < dstWidth; i ++)
{
tmpx = i * ratio;
tmpy = j * ratio;
ox = tmpx >> 8;
oy = tmpy >> 8;
x = tmpx & 0xFF;
y = tmpy & 0xFF;
color[0][0] = src[ oy*srcWidth + ox ];
color[1][0] = src[ oy*srcWidth + ox +1 ];
color[0][1] = src[ (oy+1)*srcWidth + ox ];
color[1][1] = src[ (oy+1)*srcWidth + ox+1 ];
int final = (0x100 - x)*(0x100 - y)*color[0][0] + x*(0x100 - y)*color[1][0] + (0x100-x)*y*color[0][1] + x*y*color[1][1];
final = final >> 16;
if (final>255)
final = 255;
if (final<0)
final = 0;
dst [ j*dstWidth + i] = (unsigned char)final;
}
}
}

需要说明的事情是, 浮点数需要引入效率上一定的损失, 当然我们这里就用大数来和谐。但是只是随便写写的代码, 我们没有加入超出int范围的检查或者说明,暂时也只能这样了:)。用了这个函数的效果还是不错的, 我们来看看在75%,125%和250%时候的效果:

原图:

%75效果图:

125%效果图:

250%效果图:

其实从效果图多少可以看出一些的问题就是, 随着图像的拉伸, 图像的锐度其实降低了, 这个比较容易想象的,因为我们这个拉伸的办法本身就是线性的,无疑来扩大的时候把锐利的边缘模糊化了,所以自然在图像扩大很多倍的时候效果不是很好了。

http://blog.csdn.net/hhygcy/article/details/4434870#comments

图像处理之基础---图像缩放中的双线性插值c实现的更多相关文章

  1. opencv学习笔记——图像缩放函数resize

    opencv提供了一种图像缩放函数 功能:实现对输入图像缩放到指定大小 函数原型: void cv::resize ( InputArray src, OutputArray dst, Size ds ...

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

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

  3. 邻近双线性插值图像缩放的Python实现

    最近在查找有关图像缩放之类的算法,因工作中需要用到诸如此类的图像处理算法就在网上了解了一下相关算法,以及其原理,并用Python实现,且亲自验证过,在次与大家分享. 声明:本文代码示例针对的是plan ...

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

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

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

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

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

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

  7. 图像缩放_OpenCv

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

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

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

  9. OpenCV探索之路(二):图像处理的基础知识点串烧

    opencv图像初始化操作 #include<opencv2\opencv.hpp> #include<opencv2\highgui\highgui.hpp> using n ...

随机推荐

  1. Filter简介

    Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 htm ...

  2. Spring boot 配置tomcat后 控制台不打印SQL日志

    在pom.xml中配置tomcat启动处加上: <dependency> <groupId>org.springframework.boot</groupId> & ...

  3. vue中axios发送post请求,后端(@RequestParam)接不到参数

    遇到的问题描述 :axios post 请求,后端接收不到参数. 我们的接口是java,用@RequestParam来接收前端的参数 解决方案:使用qs:axios中已经包含有qs,所以无需重新安装, ...

  4. python字符串,常用编码

    Python的字符串和编码 1.常用编码 与python有关的编码主要有:ASCII.Unicode.UTF-8 其中ASCII如今可以视作UTF-8的子集 内存中统一使用Unicode编码(如记事本 ...

  5. Centos下PHP7.1打开Oracle扩展

    背景 最近因为项目研究了一下PHP集成Oracle,虽然这个组合很奇葩,但万一用到请勿采坑~ 环境 CentOS Linux release 7.3.1611 (Core) PHP7.1.1 安装or ...

  6. mysql查询排名

    student_work表 student_info表 sql语句:按grade从高到低排名 结果:

  7. Spider-Python爬虫之使用Selenium模拟浏览器行为

    分析 他的代码比较简单,主要有以下的步骤:使用BeautifulSoup库,打开百度贴吧的首页地址,再解析得到id为new_list标签底下的img标签,最后将img标签的图片保存下来. header ...

  8. <mongoose>……find与findOne的区别……//

    mongoose中的 find 和 findOne 都是用来查找指定表的数据的 find指的是查找指定表的所有数据,返回的是数组 User.find().then((result)=>{ con ...

  9. Eclipse Myeclipse 设定文件的默认打开方式

    Eclipse Myeclipse 设定文件的默认打开方式   菜单:Window -> Preferences -> General -> Editors -> File A ...

  10. Linux读取网卡流量脚本

    #!/bin/bash #eval `date "+day=%d; month=%m; year=%Y; hour=%H; minute=%M second=%S"` #INSTF ...