淘宝网站建设的目标是什么,广告设计软件下载,品牌营销,企业宽带可以做网站吗一、概括
面试的时候问到了一个图#xff0c;就是如何将一个算子放缩#xff1f;#xff1f;我第一反应是resize#xff08;#xff09;,但是后来我转念一想#xff0c;人家问的是插值方式#xff0c;今天来总结一下
最邻近插值法原理分析及c实现_最临近插值法-CSDN博…一、概括
面试的时候问到了一个图就是如何将一个算子放缩我第一反应是resize,但是后来我转念一想人家问的是插值方式今天来总结一下
最邻近插值法原理分析及c实现_最临近插值法-CSDN博客
我们总常用的插值方式临近插值 、双线性插值、三次样条插值、拉格朗日插值、多项式、区域插值等
下面我们就一步一步的将其概括出来
二、临近插值
最邻近插值法 : 其核心思想是选取离目标点最近的点作为待插入的新值点
如图其他的Q12 Q22 Q11 Q21都是已知的像素点要求插入一个点P 从上图可以看出P到 Q12 最近那么我就直接将PQ12
计算两份方向上的缩放后的图像 int dst_cols round(src.cols * sx); // 列 xint dst_rows round(src.rows * sy); // 行y
有3*3 --》5*5 ,那么我们可以计算P3,3 sx5/3
那么 new_i3/sxround(9/5)2; new_j3/syround(9/5)2
P(3,3)src(2,2)83 void NearestInterpolation(cv::Mat src, cv::Mat dst, float sx, float sy)
{//放大的因子 x,y 方向可能会不一样的// 放缩之后的图像的大小int dst_cols round(src.cols * sx); // 列 xint dst_rows round(src.rows * sy); // 行ydst cv::Mat(dst_rows, dst_cols, src.type());//灰度图像处理if (src.channels() 1){for (int i 0; i dst.rows; i){for (int j 0; j dst.cols; j){//插值计算取最近值插入到新的图像中int i_new round(i / sy);int j_new round(j / sx);if (i_new src.rows - 1){i_new src.rows - 1;}if (j_new src.cols - 1){j_new src.cols - 1;}dst.atuchar(i, j) src.atuchar(i_new, j_new);}}}//彩色图像处理else {for (int i 0; i dst.rows; i){for (int j 0; j dst.cols; j){int i_new round(i / sy);int j_new round(j / sx);if (i_new src.rows - 1){i_new src.rows - 1;}if (j_new src.cols - 1){j_new src.cols - 1;}//Bdst.atcv::Vec3b(i, j)[0] src.atcv::Vec3b(i_new, j_new)[0];//Gdst.atcv::Vec3b(i, j)[1] src.atcv::Vec3b(i_new, j_new)[1];//Rdst.atcv::Vec3b(i, j)[2] src.atcv::Vec3b(i_new, j_new)[2];}}}
}
优点简单、计算量小。 缺点效果不好图像放大后失真现象严重。 三、线性插值
resize() 函数默认的就是双线性插值
我们先看线性插值
线性插值 然后我们将上面的做个变性就写成了如下 双线性插值原理
顾名思义就是做两次线性插值但是其实是3次
c opencv图像双线性插值的应用方法 - 知乎 案例: 算法流程
1、先通过每个方向的缩放因子计算出我们缩放后的图像的大小
2、计算通过新图像的row_new 和col_new 推算出原图像中的四个点 的位置并获得四个点的灰度值
3、通过上面拿到的公式来计算新插入的值
4、计算边界的特殊值 /// summary
/// 双线性插值处理
/// /summary
/// param namesrc/param
/// param namescale_x/param
/// param namescale_y/param
/// param namedst/param
void DoubleLineInterpolate(Mat src, double scale_x,double scale_y, Mat dst)
{int result_H static_castint(src.rows * scale_y);int result_W static_castint(src.cols * scale_x);dst Mat::zeros(cv::Size(result_W, result_H), src.type());for (int i 0; i dst.rows; i){for (int j 0; j dst.cols; j){// 非常重要的一步就是用新的图像来推算出原来图像的四个像素的位置和灰度值double before_x double(j 0.5) / scale_x - 0.5f;double before_y double(i 0.5) / scale_y - 0.5;int top_y static_castint(before_y);int bottom_y top_y 1;int left_x static_castint(before_x);int right_x left_x 1;//计算变换前坐标的小数部分double u before_x - left_x;double v before_y - top_y;// 如果计算的原始图像的像素大于真实原始图像尺寸if ((top_y src.rows - 1) (left_x src.cols - 1)){//右下角dst.atuchar(i, j) (1. - u) * (1. - v) * src.atuchar(top_y, left_x);}else if (top_y src.rows - 1){//最后一行dst.atuchar(i, j) (1. - u) * (1. - v) * src.atuchar(top_y, left_x) (1. - v) * u * src.atuchar(top_y, right_x);}else if (left_x src.cols - 1){dst.atuchar(i, j) (1. - u) * (1. - v) * src.atuchar(top_y, left_x) (v) * (1. - u) * src.atuchar(bottom_y, left_x);}else{dst.atuchar(i, j) (1. - u) * (1. - v) * src.atuchar(top_y, left_x) (1. - v) * (u)*src.atuchar(top_y, right_x) (v) * (1. - u) * src.atuchar(bottom_y, left_x) (u) * (v)*src.atuchar(bottom_y, right_x);}}}
}