1. 程式人生 > >影象縮放之雙線性插值

影象縮放之雙線性插值

IplImage *img = cvLoadImage("C:\\Users\\Administrator\\Desktop\\3838.jpg");
int nw = img->width;
int nh = img->height;

void Ctry::OnTryTyr1()
{
	//TODO:  在此新增命令處理程式程式碼  
	double times = 0.8;          //比例因子  
	int nWidth =int( times * (img->width));
	int nHeight =int( times * (img->height));
	IplImage *dst = cvCreateImage(cvSize(nWidth, nHeight), 8, 3);

	CvScalar pixel1;
	for (int i = 0; i < dst->width; i++)
	{
		for (int j = 0; j < dst->height; j++)
		{
			if (int(i * 1 / times) < img->width && int(j * 1 / times) < img->height)
			{
				pixel1 = InterpBilinear((i * 1 / times), (j * 1 / times ));
				cvSet2D(dst, j, i, pixel1);
			}
			else
			{
				cvSet2D(dst, j, i, RGB(0, 0, 0, ));
			}
		}
	}
	cvSaveImage("C:\\Users\\Administrator\\Desktop\\InterpBilinear.jpg", dst);
	cvNamedWindow(" dst", CV_WINDOW_AUTOSIZE);
	cvShowImage(" dst", dst);
	cvNamedWindow("img", CV_WINDOW_AUTOSIZE);
	cvShowImage("img", img);
	cvWaitKey(0);

	cvReleaseImage(&img);
	cvReleaseImage(&dst);
	cvDestroyWindow(" dst");
	cvDestroyWindow("img");
}

CvScalar Ctry::InterpBilinear(double x, double y)
{
	//4個鄰近點的座標(i1,j1),(i2,j1),(i1,j2),(i2,j2)
	int x1, x2;
	int y1, y2;
	//4個最鄰近畫素值
	CvScalar f1, f2, f3, f4;
	//二個插值中間值
	CvScalar f12, f34;
	CvScalar pixel;
	double epsilon = 0.0001;
	//計算四個最鄰近畫素的座標
	x1 = int(x);
	x2 = x1 + 1;
	y1 = int(y);
	y2 = y1 + 1;

	if ((x<0) || (x>nw - 1) || (y<0) || (y>nh - 1))
	{
		//要計算的點不在原圖範圍內
		MessageBox(NULL, "超過圖片大小", "錯誤", MB_OK | MB_ICONERROR);
		return 0;
	}
	else
	{
		if (fabs(x - nw + 1 )<= epsilon)
		{
			//要計算的點在影象的右邊緣上
			if (fabs(y - nh + 1) <= epsilon)
			{
				//要計算的元素恰好是影象最右下角的那一個元素,直接返回該點的畫素值
				f1 = cvGet2D(img, y1, x1);
				return f1;
			}
			else
			{
				//在影象右邊緣且不是最後一點,直接一次插值即可
				f1 = cvGet2D(img, y1, x1);
				f3 = cvGet2D(img, y1, x2);
				pixel.val[0] = f1.val[0] + (y - y1)*(f3.val[0] - f1.val[0]);
				pixel.val[1] = f1.val[1] + (y - y1)*(f3.val[1] - f1.val[1]);
				pixel.val[2] = f1.val[2] + (y - y1)*(f3.val[2] - f1.val[2]);
				return pixel;
			}
		}
		else if (fabs(y - nh + 1) <= epsilon)
		{
			//要計算的點在影象的下邊緣上且不是最後一點,直接一次插值即可
			f1 = cvGet2D(img, y1, x1);
			f2 = cvGet2D(img, y2, x1);
			pixel.val[0] = f1.val[0] + (x - x1)*(f2.val[0] - f1.val[0]);
			pixel.val[1] = f1.val[1] + (x - x1)*(f2.val[1] - f1.val[1]);
			pixel.val[2] = f1.val[2] + (x - x1)*(f2.val[2] - f1.val[2]);
			return pixel;
		}
		else
		{
			//計算4個最鄰近畫素值
			f1 = cvGet2D(img, y1, x1);
			f2 = cvGet2D(img, y2, x1);
			f3 = cvGet2D(img, y1, x2);
			f4 = cvGet2D(img, y2, x2);
			//插值1
			f12.val[0] = f1.val[0] + (x - x1)*(f2.val[0] - f1.val[0]);
			f12.val[1] = f1.val[1] + (x - x1)*(f2.val[1] - f1.val[1]);
			f12.val[2] = f1.val[2] + (x - x1)*(f2.val[2] - f1.val[2]);
			//插值2
			f34.val[0] = f3.val[0] + (x - x1)*(f4.val[0] - f3.val[0]);
			f34.val[1] = f3.val[1] + (x - x1)*(f4.val[1] - f3.val[1]);
			f34.val[2] = f3.val[2] + (x - x1)*(f4.val[2] - f3.val[2]);
			//插值3
			pixel.val[0] = f12.val[0] + (y - y1)*(f34.val[0] - f12.val[0]);
			pixel.val[1] = f12.val[1] + (y - y1)*(f34.val[1] - f12.val[1]);
			pixel.val[2] = f12.val[2] + (y - y1)*(f34.val[2] - f12.val[2]);

			return pixel;
		}
	}
}

效果圖:      

相關推薦

影象線性

IplImage *img = cvLoadImage("C:\\Users\\Administrator\\Desktop\\3838.jpg"); int nw = img->width; int nh = img->height; void Ctry::OnTryTyr1() { //T

數字影象三次

基本原理:雙三次插值是一種更加複雜的插值方式,它能創造出比雙線性插值更平滑的影象邊緣。縮放後圖像中某個象素的象素值是由源影象相應畫素附近的(4 x 4)個鄰近象素值計算出來的,即通過一個基函式進行擬合得到一個目的畫素值,具體某點v(x,y) 的畫素值是使用下式計算得到:

影象三次

今天學習了第三種影象縮放的方法,雙三次插值法。由於理解能力比較差,看了好久的公式,還是雲裡霧裡,但是為了督促自己學習,還是把已知的部分記錄下來。 數學原理 假設源影象A大小為m*n,縮放後的目標影象B的大小為M*N。那麼根據比例我們可以得到B(X,Y)在

影象演算法——近鄰取樣

近鄰取樣插值原理: 對於縮放後圖片中的某點 (Dx, Dy) 對應於原圖片中的點 (Sx, Sy),它們之間存在如下的比例關係:     (Sx-0)/(SW-0)=(Dx-0)/(DW-0)     (Sy-0)/(SH-0

C/C++ BMP(24位真彩色)影象處理(3)------影象の放大縮小(線性

    影象的放大縮小其實是一回事,都是先建立一張空白目標影象(放大縮小後的影象),其大小就是想要放大縮小後所得到的影象大小。建立影象後我們並不知道這張影象裡面的各個畫素點RGB(或灰度)值是多少,這個時候就需要經過一個演算法去算目標影象的畫素點RGB(或灰度)值。基本上所

線性影象問題

       初次開始寫部落格,想記錄下自己在公司實習所做過的事情以及學習到的東西,雖然還是有很多東西不瞭解也還沒做出來,但是也希望這是一種體驗。        我於2018.9.3入職進行實習,到現在也快過去兩個月了,我在公司

影象——線性演算法

在數學上,雙線性插值是有兩個變數的插值函式的線性插值擴充套件,其核心思想是在兩個方向分別進行一次線性插值。如果選擇一個座標系統使得  的四個已知點座標分別為 (0, 0)、(0, 1)、(1, 0) 和 (1, 1),那麼插值公式就可以化簡為: 用矩陣運算來表示的話就

影象中最近鄰線性的基本原理

影象的縮放很好理解,就是影象的放大和縮小。傳統的繪畫工具中,有一種叫做“放大尺”的繪畫工具,畫家常用它來放大圖畫。當然,在計算機上,我們不再需要用放大尺去放大或縮小影象了,把這個工作交給程式來完成就可以了。下面就來講講計算機怎麼來放大縮小圖象;在本文中,我們所說的影象都是指

使用Matlab進行影象的讀寫、顯示和(最近臨線性法)

上次我們開始進行數字影象處理這門課程的實驗,直到現在才抽空出來寫寫文章,記錄一下知識點。介紹一下,使用Matlab對數字影象的簡單處理。 1、 讀取與顯示輸入影象: %輸入影象和顯示影象 funct

線性演算法進行影象及效能效果優化

一)轉自http://handspeaker.iteye.com/blog/1545126 最近在程式設計時用到了雙線性插值演算法,對影象進行縮放。網上有很多這方面的資料,介紹的也算明白。但是,這些文章只介紹了演算法,並沒有具體說怎麼實現以及怎麼實現最好,舉個例子,你可以按照網上文章的演算法自己寫一個雙線性

線性影象演算法的研究與實現

Opencv學堂 http://mp.weixin.qq.com/s?__biz=MzA4MDExMDEyMw==&mid=100000109&idx=1&sn=7540b49e869c3e27f87c84f6f3dfe9a8&chksm

線性影象示例

演算法原理簡介 雙線性插值是一階插值,常用於影象的旋轉、縮放處理。 它利用原圖中對應的四個點的畫素值來確定目標影象中的畫素值。 為了便於理解,我們來看兩張尺寸不一樣的圖片: 原圖 變換圖 假設原圖圖片的寬度為yw,高度為xh 變換圖的寬

圖像——線性算法

val 位置 單位 sso 數學 圖像 取值 利用 等待   在數學上,雙線性插值是有兩個變量的插值函數的線性插值擴展,其核心思想是在兩個方向分別進行一次線性插值。如果選擇一個坐標系統使得 的四個已知點坐標分別為 (0, 0)、(0, 1)、(1, 0) 和 (1, 1)

影象立方(三次)卷積(Android版改寫)

最近在做圖片放大之後的畫面處理,嘗試了這種卷積插值法,原文如下:https://dailc.github.io/2017/11/01/imageprocess_bicubicinterpolation.html 然後我將其工程簡單地改寫成了Android版本的程式碼(只是個Demo,用來看看效果

【短道速滑一】OpenCV中cvResize函式使用線性縮小影象到長寬大小一半時速度飛快(比最近鄰還快)異象解析和自我實現。

  今天,一個朋友想使用我的SSE優化Demo裡的雙線性插值演算法,他已經在專案裡使用了OpenCV,因此,我就建議他直接使用OpenCV,朋友的程式非常注意效率和實時性(因為是處理視訊),因此希望我能測試下我的速度和OpenCV相比到底那一個更有速度優勢,恰好前一段時間也有朋友有這方面的需求,因此我就隨意編

影象演算法的基礎知識(線性,協方差矩陣,矩陣的特徵值、特徵向量)

0. 前言 MATLAB或者OpenCV裡有很多封裝好的函式,我們可以使用一行程式碼直接呼叫並得到處理結果。然而當問到具體是怎麼實現的時候,卻總是一臉懵逼,答不上來。前兩天參加一個演算法工程師的筆試題,其中就考到了這幾點,感到非常汗顏!趕緊補習! 1. 雙線性插值 在影象處

最近鄰線性的基本原理 以及OpenCV中resize函式的用法改變影象的大小

最近鄰插值和雙線性插值的基本原理 影象的縮放很好理解,就是影象的放大和縮小。傳統的繪畫工具中,有一種叫做“放大尺”的繪畫工具,畫家常用它來放大圖畫。當然,在計算機上,我們不再需要用放大尺去放大或縮小影象了,把這個工作交給程式來完成就可以了。下面就來講講計算機怎麼來放大縮小圖象;在本文中,

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

影象演算法-最近鄰 線性

影象插值演算法包括向上插值和向下插值,向上插值就是對影象進行放大,向下插值就是對影象進行縮小,插值演算法在影象預處理過程中經常被使用,通過插值演算法,可以將影象尺寸變換為任意尺寸,下面以舉例子的方式來說明兩種常見的插值演算法: 假設影象原始尺寸為wi,hi,縮

影象演算法(一):最近鄰線性,三次

最近在複習影象演算法,對於一些簡單的影象演算法進行一個程式碼實現,由於找工作比較忙,具體原理後期補上,先上程式碼。今天先給出最近鄰插值,雙線性插值,三次插值。 1.最近鄰插值 原始圖中影響點數為1 (1)程式碼 # include<iostream>