1. 程式人生 > >影象的放大與縮小(2)——雙線性插值放大與均值縮小

影象的放大與縮小(2)——雙線性插值放大與均值縮小

概述

基於上一節“等距取樣法”實現圖片放大與縮小的缺點。要對其進行改進,對影象的縮小則可以用“區域性均值法”,對於影象的放大則可以用“雙線性插值法”。

效果如下:

      

                   2048*1536縮小為100*80時的效果               100*80放大到600*400的效果

區域性均值法縮小影象

(1)計算取樣間隔

設原圖的大小為W*H,將其放大(縮小)為(k1*W)*(K2*H),則取樣區間為

ii=1/k1;       jj=1/k2;

當k1==k2時為等比例縮小;當k1!=k2時為不等比例放大(縮小);

k1<1 && k2<1時為圖片縮小,k1>1 && k2>1時圖片放大。

(2)求出區域性子塊

設原圖為F(x,y)(i=1,2,……W; j=1,2,……H),縮小的影象為G(x,y)(x=1,2, ……M; y=1,2,……N,其中M=W*k1,N=H*k2),則有原影象區域性子塊為

f’(x,y) = f(ii*i, jj*j)        …… f(ii*i + ii-1, jj*j)

                ……                   ……

             f(ii*i, jj*j+jj-1) …… f(ii*i + ii-1, jj*j+jj-1)

(3)求出縮小的影象

G(x, y) = f’(x,y)的均值

例:


縮小後的影象

 

例如g11=(f11 +f12 + f21 + f22)/4

演算法原始碼(Java

  1. /** 
  2.      * 區域性均值的影象縮小 
  3.      * @param img 要縮小的影象物件 
  4.      * @param m 縮小後圖像的寬 
  5.      * @param n 縮小後圖像的高 
  6.      * @return 返回處理後的影象物件 
  7.      */
  8.     publicstatic BufferedImage shrink(BufferedImage img, 
    int m, int n) {  
  9.         float k1 = (float)m/img.getWidth();  
  10.         float k2 = (float)n/img.getHeight();          
  11.         return shrink(img, k1, k2);  
  12.     }  
  13.     /** 
  14.       * 區域性均值的影象縮小 
  15.      * @param img 要縮小的影象物件 
  16.      * @param k1 要縮小的列比列 
  17.      * @param k2 要縮小的行比列 
  18.      * @return 返回處理後的影象物件 
  19.      */
  20.     publicstatic BufferedImage shrink(BufferedImage img, float k1, float k2) {  
  21.         if(k1 >1 || k2>1) {//如果k1 >1 || k2>1則是圖片放大,不是縮小
  22.             System.err.println("this is shrink image funcation, please set k1<=1 and k2<=1!");  
  23.             returnnull;  
  24.         }   
  25.         float ii = 1/k1;    //取樣的行間距
  26.         float jj = 1/k2; //取樣的列間距       
  27.         int dd = (int)(ii*jj);   
  28.         //int m=0 , n=0;                
  29.         int imgType = img.getType();  
  30.         int w = img.getWidth();  
  31.         int h = img.getHeight();  
  32.         int m = (int) (k1*w);  
  33.         int n = (int) (k2*h);  
  34.         int[] pix = newint[w*h];  
  35.         pix = img.getRGB(00, w, h, pix, 0, w);  
  36.         System.out.println(w + " * " + h);  
  37.         System.out.println(m + " * " + n);  
  38.         int[] newpix = newint[m*n];  
  39.         for(int j=0; j<n; j++) {  
  40.             for(int i=0; i<m; i++) {  
  41.                 int r = 0, g=0, b=0;  
  42.                 ColorModel cm = ColorModel.getRGBdefault();               
  43.                 for(int k=0; k<(int)jj; k++) {  
  44.                     for(int l=0; l<(int)ii; l++) {  
  45.                         r = r + cm.getRed(pix[(int)(jj*j+k)*w + (int)(ii*i+l)]);  
  46.                         g = g + cm.getGreen(pix[(int)(jj*j+k)*w + (int)(ii*i+l)]);  
  47.                         b = b + cm.getBlue(pix[(int)(jj*j+k)*w + (int)(ii*i+l)]);  
  48.                     }  
  49.                 }  
  50.                 r = r/dd;  
  51.                 g = g/dd;  
  52.                 b = b/dd;  
  53.                 newpix[j*m + i] = 255<<24 | r<<16 | g<<8 | b;  
  54.                 //255<<24 | r<<16 | g<<8 | b  這個公式解釋一下,顏色的RGB在記憶體中是
  55.                 //以二進位制的形式儲存的,從右到左1-8位表示blue,9-16表示green,17-24表示red
  56.                 //所以"<<24" "<<16" "<<8"分別表示左移24,16,8位
  57.                 //newpix[j*m + i] = new Color(r,g,b).getRGB();
  58.             }  
  59.         }  
  60.         BufferedImage imgOut = new BufferedImage( m, n, imgType);  
  61.         imgOut.setRGB(00, m, n, newpix, 0, m);              
  62.         return imgOut;  
  63.     }  

  1. /** 
  2.      * 區域性均值的影象縮小 
  3.      * @param img 要縮小的影象物件 
  4.      * @param m 縮小後圖像的寬 
  5.      * @param n 縮小後圖像的高 
  6.      * @return 返回處理後的影象物件 
  7.      */
  8.     publicstatic BufferedImage shrink(BufferedImage img, int m, int n) {  
  9.         float k1 = (float)m/img.getWidth();  
  10.         float k2 = (float)n/img.getHeight();          
  11.         return shrink(img, k1, k2);  
  12.     }  
  13.     /** 
  14.       * 區域性均值的影象縮小 
  15.      * @param img 要縮小的影象物件 
  16.      * @param k1 要縮小的列比列 
  17.      * @param k2 要縮小的行比列 
  18.      * @return 返回處理後的影象物件 
  19.      */
  20.     publicstatic

    相關推薦

    影象放大縮小(2)——線性放大均值縮小

    概述 基於上一節“等距取樣法”實現圖片放大與縮小的缺點。要對其進行改進,對影象的縮小則可以用“區域性均值法”,對於影象的放大則可以用“雙線性插值法”。 效果如下:                           2048*1536縮小為10

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

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

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

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

    影象放大縮小(3)——立方演算法

    -----------------------------轉載自jia20003的部落格" ----------------------------------- 一:數學原理 如果已知一個函式f(x)以及它在x=0,x=1處的導數,那麼

    影象-線性三次

    在現實生活中,我們經常會遇到把影象進行放大、幾何空間變換的情況等等,這些操作都需要在源影象和目標影象之間建立一個對映規則,使得兩影象畫素座標之間建立起一種對應關係,從而為目標影象的每一個畫素賦值。 從源影象到目標影象的對映叫前向對映,但是這種對映方法可能會出現這樣的兩個問題

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

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

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

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

    線性影象縮放問題

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

    最近鄰線性的基本原理 以及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>

    影象縮放——線性演算法

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

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

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

    OpenCL應用線性

    void func(BYTE*src, int width, int height, int pitchSrc, BYTE *dst, int t_width, int t_height, int pitchDes) { float fw = float(width)/ (t_width);

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

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

    影象縮放之線性

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

    線性-影象旋轉

    首先,什麼是雙線性插值?具體的說明大家可參照各種百科,我在這裡從影象角度來簡單講下,大體相似。 看下面這個圖 影象旋轉後,畫素點的整數座標必然會得到小數,顯然在影象的畫素點裡面是沒有小數座標的,那計算這些點的顏色值怎麼辦呢,為了保持準確性,我們把旋轉後的影象再旋轉

    線性法,最鄰近法 處理圖片的旋轉,放大

    對於一張圖片旋轉某個角度,其實就是把每個畫素計算好它的位置,再對對應的位置設定畫素值即可,以順時針為例,如下圖,由P點旋轉到P', x=rcos(a) y=rsin(a) x'=rcos(a+b)=rcos(a)cos(b)-rsin(a)sin(b) y'=rsi

    最近鄰內線性

    前一陣想改進個影象處理的演算法,發現基礎太差了,還是要從基礎開始,畢竟一口出不成胖子 於是自己學習一下影象處理的基本知識。看到兩個最簡單的演算法 一個是最近鄰內插值和雙線性插值,決定自己實現以下,順便也能瞭解一下數字影象內部的儲存結構。 以下為簡單整理 by the way