html图像缩小失真,图像放大和缩小不失真的方法!
上一篇我們學習了圖像金字塔,圖像金字塔有兩種實現方式,一種是高斯金字塔(對圖像進行縮放)、另一種是拉普拉斯金字塔(對圖像進行放大),但是圖像金字塔對圖像進行放大放小的時候會對圖像的信息造成一定的損失,那么我們本節(jié)有另外一種更好的實現方式,這種方式對圖像放大放小時,對圖像信息造成的損失較小!那么我們正式進入本節(jié)的學習吧!
一、OpenCV中resize()函數詳解
1、函數原型
void resize(InputArray src,
OutputArray dst,
Size dsize,
double fx = 0,
double fy = 0,
int interpolation = INTER_LINEAR);
2、函數功能
將原圖像src放大(放小)到指定的尺寸,可以不用考慮目標圖像的大小和尺寸,因為目標圖像的大小和尺寸是根據resize()函數中的src,dsize,fx,fy這四個參數決定的;
調整src圖像的大小的方案
(1)調整src圖像的大小,可以預先創(chuàng)建一個目標圖像dst
例如:
//新建一張512x512尺寸的圖片
Mat dst = Mat::zeros(512, 512, CV_8UC3);
Mat src = imread("lena.png");
//顯式指定dsize=dst.size(),
//那么fx和fy會其計算出來,不用額外指定。
resize(src, dst, dst.size());
(2)調整src圖像的大小,可以不預先創(chuàng)建目標圖像dst,可以用dsize,fx,fy三個個因子來控制目標圖像的大小
例如:
Mat dst;
Mat src = imread("lena.png")
//指定fx和fy,讓函數計算出目標圖像的大小。
resize(src, dst, Size(), 0.5, 0.5);
若要縮小圖像,一般情況下最好用INTER_AREA來插值,
而若要放大圖像,一般情況下最好用INTER_CUBIC(效率不高,慢,不推薦使用)或CV_INTER_LINEAR(效率較高,速度較快,推薦使用)。
3、參數詳解
第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可;
第二個參數,OutputArray類型的dst,輸出圖像,當其非零時,有著dsize(第三個參數)的尺寸,或者由src.size()計算出來;
第三個參數,Size類型的dsize,輸出圖像的大小;如果它等于零,由下式進行計算:
dsize的計算方式
第四個參數,double類型的fx,沿水平軸的縮放系數,有默認值0,且當其等于0時,由下式進行計算:
fx的計算方式
第五個參數,double類型的fy,沿垂直軸的縮放系數,有默認值0,且當其等于0時,由下式進行計算:
fy的計算方式
第六個參數,int類型的interpolation,用于指定插值方式,默認為INTER_LINEAR(線性插值)。
常用的插值方式:
INTER_NEAREST – 最近鄰插值
INTER_LINEAR – 線性插值(默認值)
INTER_AREA – 區(qū)域插值(利用像素區(qū)域關系的重采樣插值)
INTER_CUBIC –三次樣條插值(超過4×4像素鄰域內的雙三次插值)
INTER_LANCZOS4 -Lanczos插值(超過8×8像素鄰域的Lanczos插值)
4、實例
#include
#include
using namespace cv;
int main()
{
//載入原始圖
Mat srcImage = imread("lena.png");
//臨時變量和目標圖的定義
Mat tmpImage, dstImage1, dstImage2;
//將原始圖賦給臨時變量
tmpImage = srcImage;
//顯示原始圖
imshow("【原始圖】", srcImage);
//進行尺寸調整操作
resize(tmpImage, dstImage1,
Size(tmpImage.cols / 2,
tmpImage.rows / 2),
(0, 0), (0, 0), INTER_AREA);
resize(tmpImage, dstImage2,
Size(tmpImage.cols * 2,
tmpImage.rows * 2),
(0, 0), (0, 0), INTER_LINEAR);
//顯示效果圖
imshow("【放小效果圖】", dstImage1);
imshow("【放大效果圖】", dstImage2);
waitKey(0);
return 0;
}
**實驗結果**
原圖、縮小圖、放大圖
二、對于常用的差值方式原理詳解
1、INTER_NEAREST – 最近鄰插值
最近鄰插值算法不需要計算,在待求象素的四鄰象素中,將距離待求象素最近的鄰象素灰度賦給待求象素;
原理
設i+u, j+v(i, j為正整數, u, v為大于零小于1的小數,下同)為待求象素坐標,則待求象素灰度的值 f(i+u, j+v);
如下圖所示
最近鄰插值
如果(i+u, j+v)落在A區(qū),即u<0.5, v<0.5,則將左上角象素的灰度值賦給待求象素;
落在B區(qū)則賦予右上角的象素灰度值;
落在C區(qū)則賦予左下角象素的灰度值;
落在D區(qū)則賦予右下角象素的灰度值。
最鄰近元法計算量較小,但可能會造成插值生成的圖像灰度上的不連續(xù),在灰度變化的地方可能出現明顯的鋸齒狀。
2、INTER_LINEAR – 線性插值(默認值)
線性插值是指插值函數為一次多項式的插值方式,其在插值節(jié)點上的插值誤差為零。線性插值相比其他插值方式,如拋物線插值,具有簡單、方便的特點。
原理
線性插值
首先,在X方向上進行兩次線性插值計算,然后在Y方向上進行一次插值計算;
在X方向上進行兩次線性插值計算,然后在Y方向上進行一次插值計算
在圖像處理的時候,我們先根據
srcX = dstX * (srcWidth/dstWidth)
srcY = dstY * (srcHeight/dstHeight)
來計算目標像素在源圖像中的位置,這里計算的srcX和srcY一般都是浮點數,比如f(1.2, 3.4)這個像素點是虛擬存在的,先找到與它臨近的四個實際存在的像素點
(1,3) (2,3)
(1,4) (2,4)
寫成f(i+u,j+v)的形式,則u=0.2,v=0.4, i=1, j=3
在沿著X方向差插值時,f(R1)=u(f(Q21)-f(Q11))+f(Q11)
沿著Y方向同理計算。
或者,直接整理一步計算,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) 。
好了,天的OpenCV學到這里就結束了,相信大家已經知道了如何對一幅圖像進行放大與放小,喜歡的朋友可以給我支持,點個贊哦!!!
總結
以上是生活随笔為你收集整理的html图像缩小失真,图像放大和缩小不失真的方法!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 注册表中shell文件不见了_win7系
- 下一篇: golang的图片操作:缩放图片+合成图