#include<opencv2\opencv.hpp>
#include<iostream> using namespace cv;
using namespace std; bool enlargedImage(Mat &src, float k1, float k2);//k1,k2表示放大的倍数 void main()
{
Mat srcImage = imread("flower.png");
float k1 = 1.2, k2 = 2.5;
enlargedImage(srcImage, k1, k2);
} bool enlargedImage(Mat &src, float k1, float k2)
{
int height, width, theight, twidth;
int ia, ja;//新的坐标
height = src.rows;//图像的高
width = src.cols;//图像的宽
theight = round(height*k1);//扩大后图像的高
cout << theight << endl;
twidth = round(width*k2);//扩大后图像的宽
cout << twidth << endl;
Mat dstImage(theight, twidth, src.type(), Scalar(0));
//对得到的新图片进行填充 for (int i = 0; i < height; i++)
{
for (int j = 0; j < width - 1; j++)
{ ia = round(i*k1);
ja = round(j*k2);
//如果位于四个顶角
if (ia == 0 && ja == 0)//左顶角
{
dstImage.at<Vec3b>(ia, ja)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(ia, ja)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(ia, ja)[2] = src.at<Vec3b>(i, j)[2];
}
else if (ia == theight - 1 && ja == twidth - 1)//左下角
{
dstImage.at<Vec3b>(ia, ja)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(ia, ja)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(ia, ja)[2] = src.at<Vec3b>(i, j)[2];
}
else if (ia == 0 && ja == twidth - 1)//右顶角
{
dstImage.at<Vec3b>(ia, ja)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(ia, ja)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(ia, ja)[2] = src.at<Vec3b>(i, j)[2];
}
else if (ia == theight - 1 && ja == twidth - 1)//右下角
{
dstImage.at<Vec3b>(ia, ja)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(ia, ja)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(ia, ja)[2] = src.at<Vec3b>(i, j)[2];
}
else if (ja == twidth - 1)//第三种情况,最右边
{
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, ja)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, ja)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, ja)[2] = src.at<Vec3b>(i, j)[2];
}
else if (ia == 0)//第一种情况,最上面
{
dstImage.at<Vec3b>(ia, round((j - 1)*k2) + 1)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(ia, round((j - 1)*k2) + 1)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(ia, round((j - 1)*k2) + 1)[2] = src.at<Vec3b>(i, j)[2];
}
else if (ja == 0)//第二种情况,最左边
{
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, ja)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, ja)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, ja)[2] = src.at<Vec3b>(i, j)[2];
} else if (ia == theight - 1)//第四种情况,最下面
{
dstImage.at<Vec3b>(ia, round((j - 1)*k2) + 1)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(ia, round((j - 1)*k2) + 1)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(ia, round((j - 1)*k2) + 1)[2] = src.at<Vec3b>(i, j)[2];
}
//最后一种情况,位于中间的,将值赋给左上角的值
else
{
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, round((j - 1)*k2) + 1)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, round((j - 1)*k2) + 1)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, round((j - 1)*k2) + 1)[2] = src.at<Vec3b>(i, j)[2];
}
}
}
for (int i = 0; i < height; i++)
{
//单独考虑最右边
int j = width - 1;
ia = round(i*k1);
ja = round(j*k2);
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, ja + 1)[0] = src.at<Vec3b>(i, j)[0];
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, ja + 1)[1] = src.at<Vec3b>(i, j)[1];
dstImage.at<Vec3b>(round((i - 1)*k1) + 1, ja + 1)[2] = src.at<Vec3b>(i, j)[2]; } int a1, a2, b1, b2;//用来表示单线性插值中的上下左右中不为0的坐标
//利用单线性进行了行插值
for (int i = 0; i < theight; i++)
{
for (int j = 0; j < twidth; j++)
{
//首先考虑的满足单线性插值的 if (dstImage.at<Vec3b>(i, 0)[0] == 0 && dstImage.at<Vec3b>(i, 0)[1] == 0 && dstImage.at<Vec3b>(i, 0)[2] == 0)
{
continue;
} if (dstImage.at<Vec3b>(i, j)[0] == 0 && dstImage.at<Vec3b>(i, j)[1] == 0 && dstImage.at<Vec3b>(i, j)[2] == 0&& j>0 && j < twidth)
{
b1 = j - 1;
b2 = j + 1; while (dstImage.at<Vec3b>(i, b1)[0] == 0 && dstImage.at<Vec3b>(i, b1)[1] == 0 && dstImage.at<Vec3b>(i, b1)[2] == 0 && b1 >= 0)
{
b1--;
} while (dstImage.at<Vec3b>(i, b2)[0] == 0 && dstImage.at<Vec3b>(i, b2)[1] == 0 && dstImage.at<Vec3b>(i, b2)[2] == 0 && b2 <twidth)
{
b2++;
}
int sfrg0 = floor(((j - b1)*1.0 / (b2 - b1))*dstImage.at<Vec3b>(i, b2)[0] + ((b2 - j)*1.0 / (b2 - b1))*dstImage.at<Vec3b>(i, b1)[0]);
int sfrg1 = floor(((j - b1)*1.0 / (b2 - b1))*dstImage.at<Vec3b>(i, b2)[1] + ((b2 - j)*1.0 / (b2 - b1))*dstImage.at<Vec3b>(i, b1)[1]);
int sfrg2 = floor(((j - b1)*1.0 / (b2 - b1))*dstImage.at<Vec3b>(i, b2)[2] + ((b2 - j)*1.0 / (b2 - b1))*dstImage.at<Vec3b>(i, b1)[2]);
dstImage.at<Vec3b>(i, j)[0] = saturate_cast<uchar>(sfrg0);
dstImage.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(sfrg1);
dstImage.at<Vec3b>(i, j)[2] = saturate_cast<uchar>(sfrg2); }
}
}
//利用单线性对列进行插值 for (int j = 0; j < twidth; j++)
{
for (int i = 0; i < theight; i++)
{ if (dstImage.at<Vec3b>(i, j)[0] == 0 && dstImage.at<Vec3b>(i, j)[1] == 0 && dstImage.at<Vec3b>(i, j)[2] == 0 && i>0 && i < theight)
{
a1 = i - 1;
a2 = i + 1; while (dstImage.at<Vec3b>(a1, j)[0] == 0 && dstImage.at<Vec3b>(a1, j)[1] == 0 && dstImage.at<Vec3b>(a1, j)[2] == 0 && a1 >= 0)
{
a1--;
} while (dstImage.at<Vec3b>(a2, j)[0] == 0 && dstImage.at<Vec3b>(a2, j)[1] == 0 && dstImage.at<Vec3b>(a2, j)[2] == 0 && a2 < twidth)
{
a2++;
}
int s0 = floor(((i - a1)*1.0 / (a2 - a1))*dstImage.at<Vec3b>(a2, j)[0] + ((a2 - i)*1.0 / (a2 - a1))*dstImage.at<Vec3b>(a1, j)[0]);
int s1 = floor(((i - a1)*1.0 / (a2 - a1))*dstImage.at<Vec3b>(a2, j)[1] + ((a2 - i)*1.0 / (a2 - a1))*dstImage.at<Vec3b>(a1, j)[1]);
int s2 = floor(((i - a1)*1.0 / (a2 - a1))*dstImage.at<Vec3b>(a2, j)[2] + ((a2 - i)*1.0 / (a2 - a1))*dstImage.at<Vec3b>(a1, j)[2]);
dstImage.at<Vec3b>(i, j)[0] = saturate_cast<uchar>(s0);
dstImage.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(s1);
dstImage.at<Vec3b>(i, j)[2] = saturate_cast<uchar>(s2); }
}
} imshow("原图", src);
//namedWindow("扩大后的图像", CV_WINDOW_NORMAL);
imshow("扩大后的图像", dstImage); waitKey(0);
return true;
}

  效果图:

Opencv(C++)实现二阶线性插值的更多相关文章

  1. opencv边缘检测的入门剖析(第七天)

    ---边缘检测概念理解--- 边缘检测的理解可以结合前面的内核,说到内核在图像中的应用还真是多,到现在为止学的对图像的操作都是核的操作,下面还有更神奇的! 想把边缘检测出来,从图像像素的角度去想,那就 ...

  2. opencv算法学习

    1.改变图像的亮度和对比度: 算法介绍:对每一点像素值的r,g,b,值进行乘法和加法的运算. 代码使用: ; y < image.rows; y++ ) { ; x < image.col ...

  3. opencv的学习笔记5

    总结原博文中的一些边缘检测算子和滤波器.(Canny算子,  Sobel算子,  Laplace算子以及Scharr滤波器) 首先,一般的边缘检测包括三个步骤: 1)滤波:边缘检测的算法主要是基于图像 ...

  4. OpenCV 之 边缘检测

    上一篇 <OpenCV 之 图像平滑> 中,提到的图像平滑,从信号处理的角度来看,实际上是一种“低通滤波器”. 本篇中,数字图像的边缘,因为通常都是像素值变化剧烈的区域 (“高频”),故可 ...

  5. opencv 简单模糊和高斯模糊 cvSmooth

    cv::Mat 是C++版OpenCV的新结构. cvSmooth() 是老版 C API. 没有把C接口与C + + 结合. 建议你们也可以花一些时间看一下介绍. 同样,你如果查看opencv/mo ...

  6. 【OpenCV】边缘检测:Sobel、拉普拉斯算子

    推荐博文,博客.写得很好,给个赞. Reference Link : http://blog.csdn.net/xiaowei_cqu/article/details/7829481 一阶导数法:梯度 ...

  7. OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放

    这篇已经写得很好,真心给作者点个赞.题目都是直接转过来的,直接去看吧. Reference Link : http://blog.csdn.net/poem_qianmo/article/detail ...

  8. 学习OpenCV——Surf(特征点篇)&flann

    Surf(Speed Up Robust Feature) Surf算法的原理                                                             ...

  9. [OpenCV] Feature Extraction

    特征检测 特征描述 特征匹配 特征跟踪 “不读白不读,读了还想读” 的一本基础书 低层次特征提取 阈值方法 1. 边缘检测 一阶检测算子 二阶检测算子 相位一致性(频域) 2. 角点检测(局部特征提取 ...

随机推荐

  1. java 如何使的float保留2位或者多位小数 (转载)

    转载自 http://blog.csdn.net/com_stu_zhang/article/details/7214565 方法1: float   f   =  34.232323;    Big ...

  2. BuautifulSoup4库详解

    1.BeautifulSoup4库简介 What is beautifulsoup ? 答:一个可以用来从HTML 和 XML中提取数据的网页解析库,支持多种解析器(代替正则的复杂用法) 2.安装 p ...

  3. TensorFlow实践笔记(一):数据读取

    本文整理了TensorFlow中的数据读取方法,在TensorFlow中主要有三种方法读取数据: Feeding:由Python提供数据. Preloaded data:预加载数据. Reading ...

  4. Aptana下Django1.6以后的项目模板结构改造

    Django1.6以后的manage.py放在项目包目录的根目录下,这种情况下在create app的app也在这个目录下面,由此可能导致app的名称有可能会和广大的内建包或者第三方包发生命名冲突,解 ...

  5. XYC2016上半年工作笔记整理

    只要团队在,做那个方向都可能 这个产品的用户群人均价值高 第一次产品介绍会议就介绍了产品的初期全部目标功能 传统互联网人的产品思路比较偏媒体内容服务特性. 产品转化率高说明了其发展势头 任何一个形式变 ...

  6. uedit,检测粘贴事件,替换粘贴内容

    vue.editor.addListener("beforepaste",function(type, arg1, arg2){arg1.html="ddddddd&qu ...

  7. 使用Myeclipse2015构建SpringMVC项目

    1.新建web project 2.右键项目,给项目添加spring框架如图,不需要勾选任何一个选项. 3.在WebRoot/WEB-INF目录下添加web.xml内容如下: <?xml ver ...

  8. HiJson(Json格式化工具)64位中文版下载 v2.1.2

    链接:https://pan.baidu.com/s/15gMvig15iUjpqSX7nUZ-5Q 密码:8086

  9. spring 整合 shiro框架

    shiro是用来干嘛的?从它的官网上(http://shiro.apache.org/)基本可以了解到,她主要提供以下功能: (1)Authentication(认证) (2)Authorizatio ...

  10. 3d轮播图——类似酷狗的轮播

    说到轮播图,其实只要是跟web开发相关的无论是前端后端应该都不陌生,各种各样的轮播图,从以前的单纯的平面山水画遮盖滑动或滚动,到Jquery的animate甚至是h5+css3,各种炫酷的轮播图更是层 ...