影象放大並進行BiCubic插值
BiCubic插值原理:
構造BiCubic函式:
其中,a取-0.5.
BiCubic函式具有如下形狀:
[source: R. Keys, (1981). "Cubic convolution interpolation for digital image processing".IEEE Transactions on Signal Processing, Acoustics, Speech, and Signal Processing29(6): 1153–1160.]
對待插值的畫素點(x,y)(x和y可以為浮點數),取其附近的4x4鄰域點(xi,yj), i,j = 0,1,2,3。按如下公式進行插值計算:
實現程式碼:
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> #include <cmath> #include <fstream> using namespace cv; using namespace std; #define PI 3.14159265 float BiCubicPoly(float x); void MyScaleBiCubicInter(Mat& src, Mat& dst, float TransMat[3][3]); /** * @function main */ int main( int argc, char** argv ) { // load image char* imageName = "images/Lenna_256.png"; Mat image; image = imread(imageName,1); if(!image.data) { cout << "No image data" << endl; return -1; } // show image namedWindow("image", CV_WINDOW_AUTOSIZE); imshow("image", image); Mat dst; float transMat[3][3] = { {2.0, 0, 0}, {0, 2.0, 0}, {0, 0, 1} }; MyScaleBiCubicInter(image, dst, transMat); namedWindow("out_image", CV_WINDOW_AUTOSIZE); imshow("out_image", dst); imwrite("Lenna_scale_biCubic2.jpg", dst); waitKey(0); return 0; } float BiCubicPoly(float x) { float abs_x = abs(x); float a = -0.5; if( abs_x <= 1.0 ) { return (a+2)*pow(abs_x,3) - (a+3)*pow(abs_x,2) + 1; } else if( abs_x < 2.0 ) { return a*pow(abs_x,3) - 5*a*pow(abs_x,2) + 8*a*abs_x - 4*a; } else return 0.0; } void MyScaleBiCubicInter(Mat& src, Mat& dst, float TransMat[3][3]) { CV_Assert(src.data); CV_Assert(src.depth() != sizeof(uchar)); // calculate margin point of dst image float left = 0; float right = 0; float top = 0; float down = 0; float x = src.cols * 1.0f; float y = 0.0f; float u1 = x * TransMat[0][0] + y * TransMat[0][1]; float v1 = x * TransMat[1][0] + y * TransMat[1][1]; x = src.cols * 1.0f; y = src.rows * 1.0f; float u2 = x * TransMat[0][0] + y * TransMat[0][1]; float v2 = x * TransMat[1][0] + y * TransMat[1][1]; x = 0.0f; y = src.rows * 1.0f; float u3 = x * TransMat[0][0] + y * TransMat[0][1]; float v3 = x * TransMat[1][0] + y * TransMat[1][1]; left = min( min( min(0.0f,u1), u2 ), u3); right = max( max( max(0.0f,u1), u2 ), u3); top = min( min( min(0.0f,v1), v2 ), v3); down = max( max( max(0.0f,v1), v2 ), v3); // create dst image dst.create(int(abs(right-left)), int(abs(down-top)), src.type()); CV_Assert( dst.channels() == src.channels() ); int channels = dst.channels(); int i,j; uchar* p; uchar* q0; uchar* q1; uchar* q2; uchar* q3; for( i = 0; i < dst.rows; ++i) { p = dst.ptr<uchar>(i); for ( j = 0; j < dst.cols; ++j) { // x = (j+left)/TransMat[0][0] ; y = (i+top)/TransMat[1][1] ; int x0 = int(x) - 1; int y0 = int(y) - 1; int x1 = int(x); int y1 = int(y); int x2 = int(x) + 1; int y2 = int(y) + 1; int x3 = int(x) + 2; int y3 = int(y) + 2; if( (x0 >= 0) && (x3 < src.cols) && (y0 >= 0) && (y3 < src.rows) ) { q0 = src.ptr<uchar>(y0); q1 = src.ptr<uchar>(y1); q2 = src.ptr<uchar>(y2); q3 = src.ptr<uchar>(y3); float dist_x0 = BiCubicPoly(x-x0); float dist_x1 = BiCubicPoly(x-x1); float dist_x2 = BiCubicPoly(x-x2); float dist_x3 = BiCubicPoly(x-x3); float dist_y0 = BiCubicPoly(y-y0); float dist_y1 = BiCubicPoly(y-y1); float dist_y2 = BiCubicPoly(y-y2); float dist_y3 = BiCubicPoly(y-y3); float dist_x0y0 = dist_x0 * dist_y0; float dist_x0y1 = dist_x0 * dist_y1; float dist_x0y2 = dist_x0 * dist_y2; float dist_x0y3 = dist_x0 * dist_y3; float dist_x1y0 = dist_x1 * dist_y0; float dist_x1y1 = dist_x1 * dist_y1; float dist_x1y2 = dist_x1 * dist_y2; float dist_x1y3 = dist_x1 * dist_y3; float dist_x2y0 = dist_x2 * dist_y0; float dist_x2y1 = dist_x2 * dist_y1; float dist_x2y2 = dist_x2 * dist_y2; float dist_x2y3 = dist_x2 * dist_y3; float dist_x3y0 = dist_x3 * dist_y0; float dist_x3y1 = dist_x3 * dist_y1; float dist_x3y2 = dist_x3 * dist_y2; float dist_x3y3 = dist_x3 * dist_y3; switch(channels) { case 1: { break; } case 3: { p[3*j] = (uchar)(q0[3*x0] * dist_x0y0 + q1[3*x0] * dist_x0y1 + q2[3*x0] * dist_x0y2 + q3[3*x0] * dist_x0y3 + q0[3*x1] * dist_x1y0 + q1[3*x1] * dist_x1y1 + q2[3*x1] * dist_x1y2 + q3[3*x1] * dist_x1y3 + q0[3*x2] * dist_x2y0 + q1[3*x2] * dist_x2y1 + q2[3*x2] * dist_x2y2 + q3[3*x2] * dist_x2y3 + q0[3*x3] * dist_x3y0 + q1[3*x3] * dist_x3y1 + q2[3*x3] * dist_x3y2 + q3[3*x3] * dist_x3y3 ) ; p[3*j+1] = (uchar)(q0[3*x0+1] * dist_x0y0 + q1[3*x0+1] * dist_x0y1 + q2[3*x0+1] * dist_x0y2 + q3[3*x0+1] * dist_x0y3 + q0[3*x1+1] * dist_x1y0 + q1[3*x1+1] * dist_x1y1 + q2[3*x1+1] * dist_x1y2 + q3[3*x1+1] * dist_x1y3 + q0[3*x2+1] * dist_x2y0 + q1[3*x2+1] * dist_x2y1 + q2[3*x2+1] * dist_x2y2 + q3[3*x2+1] * dist_x2y3 + q0[3*x3+1] * dist_x3y0 + q1[3*x3+1] * dist_x3y1 + q2[3*x3+1] * dist_x3y2 + q3[3*x3+1] * dist_x3y3 ) ; p[3*j+2] = (uchar)(q0[3*x0+2] * dist_x0y0 + q1[3*x0+2] * dist_x0y1 + q2[3*x0+2] * dist_x0y2 + q3[3*x0+2] * dist_x0y3 + q0[3*x1+2] * dist_x1y0 + q1[3*x1+2] * dist_x1y1 + q2[3*x1+2] * dist_x1y2 + q3[3*x1+2] * dist_x1y3 + q0[3*x2+2] * dist_x2y0 + q1[3*x2+2] * dist_x2y1 + q2[3*x2+2] * dist_x2y2 + q3[3*x2+2] * dist_x2y3 + q0[3*x3+2] * dist_x3y0 + q1[3*x3+2] * dist_x3y1 + q2[3*x3+2] * dist_x3y2 + q3[3*x3+2] * dist_x3y3 ) ; float thre = 198.0f; if( (abs(p[3*j]-q1[3*x1]) > thre) || (abs(p[3*j+1]-q1[3*x1+1]) > thre) || (abs(p[3*j+2]-q1[3*x1+2]) > thre) ) { p[3*j] = q1[3*x1]; p[3*j+1] = q1[3*x1+1]; p[3*j+2] = q1[3*x1+2]; } break; } } } } } }
相關推薦
影象放大並進行BiCubic插值
BiCubic插值原理: 構造BiCubic函式: 其中,a取-0.5. BiCubic函式具有如下形狀: [source: R. Keys, (1981). "Cubic convolution interpolation for digital image pro
影象放大並進行BiCubic插值 Matlab/C++程式碼
BiCubic插值原理: 雙三次插值又稱立方卷積插值。三次卷積插值是一種更加複雜的插值方式。該演算法利用待取樣點周圍16個點的灰度值作三次插值,不僅考慮到4 個直接相鄰點的灰度影響,而且考慮到各鄰點間灰度值變化率的影響。三次運算可以得到更接近高解析度影象的放大效果,但也導致
影象縮放--最近鄰插值
參考https://blog.csdn.net/wmn7q/article/details/52743284 自己一直以為放大影象是會放大畫素點的大小的,然後就去查了一下,發現不是這樣的,而是畫素點數量變了,而多的或者少的就依靠插值來實現 百度問答 這裡的答案我
影象縮放——雙線性插值演算法
在數學上,雙線性插值是有兩個變數的插值函式的線性插值擴充套件,其核心思想是在兩個方向分別進行一次線性插值。如果選擇一個座標系統使得 的四個已知點座標分別為 (0, 0)、(0, 1)、(1, 0) 和 (1, 1),那麼插值公式就可以化簡為: 用矩陣運算來表示的話就
雙三次插值(BiCubic插值)
雙三次插值(BiCubic插值 ) 雙三次插值又稱立方卷積插值。三次卷積插值是一種更加複雜的插值方式。該演算法利用待取樣點周圍16個點的灰度值作三次插值,不僅考慮到4 個直接相鄰點的灰度影響,而且考慮到各鄰點間灰度值變化率的影響。三
數字影象處理中常用的插值方法
在做數字影象處理時,經常會碰到小數象素座標的取值問題,這時就需要依據鄰近象素的值來對該座標進行插值。比如:做地圖投影轉換,對目標影象的一個象素進行座標變換到源影象上對應的點時,變換出來的對應的座標是一個小數,再比如做影象的幾何校正,也會碰到同樣的問題。以下是對常用的三種數字影
OpenCV---如何對影象進行雙線性插值運算(7)
附程式碼如下: import cv2 as cv import numpy as np def resize(): src = cv.imread("D:/matplotlib/0.jpg") cv.imshow("input",src) h, w = src.shape
使用Matlab進行影象的讀寫、顯示和縮放(最近臨插值和雙線性內插值法)
上次我們開始進行數字影象處理這門課程的實驗,直到現在才抽空出來寫寫文章,記錄一下知識點。介紹一下,使用Matlab對數字影象的簡單處理。 1、 讀取與顯示輸入影象: %輸入影象和顯示影象 funct
雙線性插值演算法進行影象縮放及效能效果優化
一)轉自http://handspeaker.iteye.com/blog/1545126 最近在程式設計時用到了雙線性插值演算法,對影象進行縮放。網上有很多這方面的資料,介紹的也算明白。但是,這些文章只介紹了演算法,並沒有具體說怎麼實現以及怎麼實現最好,舉個例子,你可以按照網上文章的演算法自己寫一個雙線性
影象的放大與縮小(2)——雙線性插值放大與均值縮小
概述 基於上一節“等距取樣法”實現圖片放大與縮小的缺點。要對其進行改進,對影象的縮小則可以用“區域性均值法”,對於影象的放大則可以用“雙線性插值法”。 效果如下: 2048*1536縮小為10
C/C++ BMP(24位真彩色)影象處理(3)------影象の放大縮小(雙線性插值)
影象的放大縮小其實是一回事,都是先建立一張空白目標影象(放大縮小後的影象),其大小就是想要放大縮小後所得到的影象大小。建立影象後我們並不知道這張影象裡面的各個畫素點RGB(或灰度)值是多少,這個時候就需要經過一個演算法去算目標影象的畫素點RGB(或灰度)值。基本上所
影象的放大與縮小(3)——雙立方插值演算法
-----------------------------轉載自jia20003的部落格" ----------------------------------- 一:數學原理 如果已知一個函式f(x)以及它在x=0,x=1處的導數,那麼
使用貝塞爾曲線進行插值 一種非常簡單的平滑多邊形的方法
ear loop line coin algorithm tro itl art mov 原文 Interpolation with Bezier Curves A very simple method of smoothing polygons Init
影象演算法的基礎知識(雙線性插值,協方差矩陣,矩陣的特徵值、特徵向量)
0. 前言 MATLAB或者OpenCV裡有很多封裝好的函式,我們可以使用一行程式碼直接呼叫並得到處理結果。然而當問到具體是怎麼實現的時候,卻總是一臉懵逼,答不上來。前兩天參加一個演算法工程師的筆試題,其中就考到了這幾點,感到非常汗顏!趕緊補習! 1. 雙線性插值 在影象處
雙線性插值的影象縮放問題
初次開始寫部落格,想記錄下自己在公司實習所做過的事情以及學習到的東西,雖然還是有很多東西不瞭解也還沒做出來,但是也希望這是一種體驗。 我於2018.9.3入職進行實習,到現在也快過去兩個月了,我在公司
MATLAB進行二值處理並提取畫素值
今天又重新看了一下2013年國賽的B題,碎紙片的拼接復原。瞭解了一下MATLAB處理影象的過程,不得不說MATLAB功能太強大,處理圖片只要幾行程式碼就足夠了。這道題還用到了模擬退火演算法,也是用MATLAB編寫的,寫在下一篇部落格裡。 MATLAB程式: clc; clear; fil
select 時 對欄位判斷是否為null 並進行賦值操作
今天用到這個需求,我用的是db2資料庫 ,上來就用ISNULL(欄位,賦值) ,結果不行。。。。。 經過查閱資料才發現每個資料庫還不同的,,下面總結一下: 首先使用mysql: ifnull(欄位,賦值); db2: nullif(欄位,賦值); oracl:
最近鄰插值和雙線性插值的基本原理 以及OpenCV中resize函式的用法改變影象的大小
最近鄰插值和雙線性插值的基本原理 影象的縮放很好理解,就是影象的放大和縮小。傳統的繪畫工具中,有一種叫做“放大尺”的繪畫工具,畫家常用它來放大圖畫。當然,在計算機上,我們不再需要用放大尺去放大或縮小影象了,把這個工作交給程式來完成就可以了。下面就來講講計算機怎麼來放大縮小圖象;在本文中,
最臨近 雙線性 三次卷積插值(影象放縮)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
影象處理常用插值方法總結
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!