在进入频域变换之前, 我们还是轻松一下,再搞点平面上的变化来看看。这把选了一个双线性插值(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. 如何修改MFC的图标

    原文:如何修改MFC的图标 修改左上角的图标和任务栏里图标 在对话框构造函数中 CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/) : CDialog(CTestD ...

  2. SQLSTATE[23000]报错

    SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous 这个问题在 ...

  3. 配置Django中数据库读写分离

    django在进行数据库操作的时候,读取数据与写数据(曾.删.改)可以分别从不同的数据库进行操作 修改配置文件: DATABASES = { 'default': { 'ENGINE': 'djang ...

  4. django+uwsgi+nginx部署(非常详细)

    django+uwsgi+nginx部署 1.介绍: 在网上看了很多教程,但自己部署了很久都没有成功,这篇博文记录自己所踩过得坑. 2.环境: Ubuntu 16.04.1 LTS (GNU/Linu ...

  5. Spring Quartz 和 Spring Task使用比较

    Quartz 和 Spring Task执行时间对比: 1. Quartz同步模式:一个任务的两次执行的时间间隔是:“执行时间”和“trigger的设定间隔”的最大值 2. Task默认同步模式:一个 ...

  6. Rightmost Digit (求n^n最后一位)

    Description Given a positive integer N, you should output the most right digit of N^N.    Input The ...

  7. Vue页面骨架屏(二)

    实现思路 参考原文中在构建时使用 Vue 预渲染骨架屏一节介绍的思路,我将骨架屏也看成路由组件,在构建时使用 Vue 预渲染功能,将骨架屏组件的渲染结果 HTML 片段插入 HTML 页面模版的挂载点 ...

  8. 测试各种低价VPS

    1) dream.jp 540多的日元一个VPS,是全日本最低的VPS,但是用了以后发现最大问题是受限很多,不好用,如果你打算用作建ss或者其它***功能,对不起,请找其它VPS了 在日本dream. ...

  9. mongodb shell 无法删除问题

    1.MongoDB Shell中退格键使用的问题. 利用SecureCRT工具访问linux的时候,在使用MongoDB的交互式shell的时候,退格键(Backspace)无法使用,导致无 法修改输 ...

  10. MTK平台 GPU 相关知识

    一.什么是Render script,以及mtk平台GPU support情况 [DESCRIPTION] 1.什么是RenderScript ? 2.RenderScript 干什么? 3.MTK平 ...