1. 程式人生 > >【數字影象處理之四】影象的放大縮小旋轉

【數字影象處理之四】影象的放大縮小旋轉

縮放放大:


修改紅框裡面的引數,2.0表示放大兩倍,0.5表示縮小兩倍。

旋轉:


修改紅框裡面的引數,表示旋轉多少度。逆時針。

旋轉編寫程式碼的時候可能會出現這樣的情況:


因為旋轉的時候,座標的對映無法使座標連續,所以中間會出現背景色的花紋。此時處理的方法使用均值濾波。

均值濾波的運算元如下:


要用均值濾波處理,首先得把旋轉後的影象放進一個數組裡面:


所以新陣列是(wImage*sinΘ+hImage*cosΘ) x (wImage*cosΘ + hImage*sinΘ)

然後新陣列中要忽略四個直角三角形,只讀取影象部分,才能使用均值濾波。這裡需要用到向量。


只要四個向量的夾角之和為360°,就說明d點在影象內。

判斷d點在影象在影象內,並且該色塊的值等於背景色的時候,使用均值濾波

,將背景色除去。

判斷點是否在某矩形上的程式碼。

#include<iostream>
#include<math.h>
using namespace std;

/**
 * 座標點類,儲存一個座標
 */
class Position{
public:
	int x;// H
	int y;// W
	Position(int x,int y){
		this->x = x;
		this->y = y;
	}
};

class Vector{
public:
	int x;
	int y;
	Vector(int x,int y){
		this->x=x;
		this->y=y;
	}
	Vector(Position a,Position b){//根據兩個點來求向量的座標
		this->x=a.x-b.x;
		this->y=a.y-b.y;
	}
	double getabs(){//求向量的長度
		return sqrt(x*x+y*y);
	}
};

double get(Vector a,Vector b){
//	cout<<'('<<a.x<<','<<a.y<<')'<<"&&"<<'('<<b.x<<','<<b.y<<')'<<endl;
//	cout<<((double)(a.x)*(double)(b.x)+(double)(a.y)*(double)(b.y))/(double)(a.getabs()*b.getabs())<<endl;
	double _a=a.getabs(),_b=b.getabs();
	if(_a==0.0 ||_b==0.0){
		return -0.707107;//返回該值可以判斷該點是否剛好為矩形的頂點。
	}
	return ((double)(a.x)*(double)(b.x)+(double)(a.y)*(double)(b.y))/(double)(_a*_b);
}

bool isImage(Position *p,int x, int y){
	Position d(x,y);
	Vector v[4]={Vector(p[0],d),Vector(p[1],d),Vector(p[2],d),Vector(p[3],d)};//建立四個向量
	cout<<acos(get(v[0],v[1]))+acos(get(v[0],v[3]))+acos(get(v[2],v[1]))+acos(get(v[2],v[3]))<<endl;
	//判斷四個向量的夾角之和是否為2π
	if(fabs(acos(get(v[0],v[1])) + acos(get(v[0],v[3])) + acos(get(v[2],v[1])) + acos(get(v[2],v[3]))-6.28319)<0.0001){
		return true;
	}
	else return false;
	
}

int main(){
	Position p[4]={Position(0,0),Position(2,0),Position(2,2),Position(0,2)};//矩形的四個頂點的座標
	int i=2,j=2;//判斷點(i,j)是不是在矩形內
	Position d(i,j);//生成點d(i,j)
	if(isImage(p,i,j)){//判斷d(i,i)是不是在矩形內,是返回true,否返回false。p是四個矩形的頂點。
		cout<<'('<<i<<','<<j<<')'<<' '<<1<<endl;
	}
	else{
		cout<<'('<<i<<','<<j<<')'<<' '<<0<<endl;
	}
	return 0;
}
均值濾波程式碼:
/**
 * Time:201505261947
 * 1 1 1
 * 1 0 1 /8 均值濾波,用於填充旋轉圖片時候空出來的座標(即花紋)
 * 1 1 1
 */
void Processing(RGB_INT **n,int H,int W,int xPos,int yPos,Position *p){
	int mask[9]={
		1,1,1,
		1,0,1,
		1,1,1
	};
	int Coff,i,j,m,g,k,temp,MaskWH=3,MaskCoff=8;
	 k=(MaskWH-1)/2;
  	 for(i=k;i<H-k;i++){
	 	 for(j=k;j<W-k;j++){
			 if(isImage(p,i,j) && n[i][j].R==256){
				 Coff=0;
				for(m=-k;m<=k;m++){
					for(g=-k;g<=k;g++){
						Coff+=(BYTE)n[i+m][j+g].R * mask[(m+k)*MaskWH+(g+k)];
					}//for
				}//for
				if(Coff<0)n[i][j].R=n[i][j].G=n[i][j].B=0;
				else{
					temp=(BYTE)(Coff/MaskCoff);
					n[i][j].R=n[i][j].G=n[i][j].B=(BYTE)( Coff%MaskCoff==0 ? temp:temp+1 );
				}
			 }//if
		}//for
	}//for
	ShowImage(n,H,W,xPos,yPos,p);
}

逆時針旋轉120度



逆時針旋轉60度



逆時針旋轉300度


放大兩倍


縮小兩倍:


數字影象處理程式彙總VC6.0原始碼:http://download.csdn.net/detail/u013580497/8877185