Just My Life & My Work

現在使用數位相機拍照尋常可見,影像畫素不斷提高,越來越適合沖洗大張相片,然而有些人會把數位相片上傳到網路空間來分享給親朋好友,在網路空間不大以及網路傳輸速度不快的情況之下,我們就需要縮放影像,將大張影像縮小至適合螢幕大小即可省時間省空間

這裡我使用OpenCV的函式來縮放影像,核心函式為cvResize(),此程式的目標為判斷影像的長或寬是否超過1000像素,若超過則將長和寬縮小至1000像素之下。單張縮放可參考我寫的縮放影像

/**
	Theme: Resize Image (Batch)
	Compiler: Dev C++ 4.9.9.2
	Date: 100/05/29
	Author: ShengWen
	Blog: https://cg2010studio.wordpress.com/
*/
#include <cv.h>
#include <highgui.h>
#include <math.h>
#include <dirent.h>
#include<iostream>
#include<iomanip>
using namespace std;

#define MAX_SIZE 1000
int main(){
	int Height;
	int Width;
	DIR *dir;
	dirent *entry;
	IplImage *src = 0;			//來源影像指標
	IplImage *dst = 0;			//目標影像指標
	double scale = 1;			//縮放倍數為1倍
	CvSize dst_cvsize;			//目標影像尺寸

	LARGE_INTEGER startTime,endTime,fre;
	double times;
	QueryPerformanceFrequency(&fre); //取得CPU頻率
	QueryPerformanceCounter(&startTime); //取得開機到現在經過幾個CPU Cycle
	//doing something

	dir=opendir(".");//開啟目標影像所在位置資料夾
	while(entry=readdir(dir)){
		if(strstr(entry->d_name,".jpg")||
			strstr(entry->d_name,".JPG")||
			strstr(entry->d_name,".jpeg")||
			strstr(entry->d_name,".JPEG")||
			strstr(entry->d_name,".png")||
			strstr(entry->d_name,".PNG")){
			src=cvLoadImage(entry->d_name, 1);//開啟影像
			Height=src->height;//or Height=cvGetDimSize(src,0);
			Width=src->width;//or Width=cvGetDimSize(src,1);
			if(Height > MAX_SIZE || Width > MAX_SIZE){//如果長或高大於MAX_SIZE
				if(Height >= Width)
					scale=MAX_SIZE/(double)Height;
				else
					scale=MAX_SIZE/(double)Width;
			}
			else{//否則,略過,但請記得釋放影像記憶體
				cvReleaseImage(&src);	//釋放來源影像佔用的記憶體
				cvReleaseImage(&dst);	//釋放目標影像佔用的記憶體
				continue;
			}

			dst_cvsize.width = src->width * scale;		//目標影像的寬為源影像寬的scale倍
			dst_cvsize.height = src->height * scale;	//目標影像的高為源影像高的scale倍

			cout<<setw(15)<<entry->d_name
			<<setw(3)<<'H'<<setw(5)<<Height
			<<setw(3)<<'W'<<setw(5)<<Width
			<<setw(3)<<'h'<<setw(4)<<dst_cvsize.height
			<<setw(3)<<'w'<<setw(4)<<dst_cvsize.width<<endl;

			dst = cvCreateImage(dst_cvsize, src->depth, src->nChannels);	//創立目標影像
			cvResize(src, dst, CV_INTER_LINEAR);	//縮放來源影像到目標影像
			cvSaveImage(entry->d_name, dst);//儲存影像

			cvReleaseImage(&src);	//釋放來源影像佔用的記憶體
			cvReleaseImage(&dst);	//釋放目標影像佔用的記憶體
		}
	}
	//doing something
	QueryPerformanceCounter(&endTime); //取得開機到程式執行完成經過幾個CPU Cycle
	times=((double)endTime.QuadPart-(double)startTime.QuadPart)/fre.QuadPart;
	cout << fixed << setprecision(20) << times << endl;
	system("pause");
	return EXIT_SUCCESS;
}

由於是批次處理,因此記憶體的管理就顯得相當重要,記得使用cvReleaseImage()釋放影像記憶體。若沒有在執行的過程中釋放記憶體,可以在命令提示字元做測試,看著工作管理員中處理程序的記憶體使用量不斷地攀升,直至2G左右(我安裝4G記憶體)作業系統即中斷處理,並顯示訊息OpenCV Error: Insufficient memory

另外,附上計算時間,會更清楚花了多少時間在縮放影像。若編譯執行之後連結有問題,則需要動態連結libcv200.dll(C:\OpenCV2.0\bin),可以放到C:\WINDOWS\system32或用Dev C++編譯好的執行檔同一資料夾下。

特別要注意的是,縮放後的影像會遺失EXIF資訊

Comments on: "[OpenCV] 批次縮放影像 (Resize Image (Batch))" (2)

  1. Undeniably imagine that that you said. Your favourite reason appeared to be at the net the easiest factor to keep in mind of. I say to you, I definitely get annoyed at the same time as folks consider issues that they plainly don’t understand about. You managed to hit the nail upon the highest and also outlined out the whole thing without having side effect , people can take a signal. Will probably be again to get more. Thanks

隨意留個言吧:)~

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

標籤雲

%d 位部落客按了讚: