前面一篇已經(jīng)簡(jiǎn)單的介紹了如何利用gcc編譯c源代碼,這篇說(shuō)一下gcc的具體編譯過(guò)程
- 預(yù)處理
預(yù)處理的工作主要是處理#include語(yǔ)句等,然后生成*.i文件。如果不加參數(shù)“-o *.i”,則會(huì)將預(yù)處理的結(jié)果輸出到標(biāo)準(zhǔn)輸出。
gcc -E *.c -o *.i #使用gcc的E參數(shù)進(jìn)行預(yù)處理
cpp *c - o *.i #使用cpp命令進(jìn)行預(yù)處理
這兩條命令預(yù)處理的結(jié)果一樣,因?yàn)間cc使用-E參數(shù)實(shí)際上也是調(diào)用了cpp指令。
2.生成匯編代碼
gcc -S *c -o *.s #將C代碼匯編為匯編語(yǔ)言代碼
gcc -S *.i -o *.s #將i文件匯編為匯編語(yǔ)言代碼
3.編譯
gcc -c *.c -o *.o
gcc -c *.s -o *o
as *.s -o *.o
cc -c *.c -o *.o
4.鏈接
gcc *.o -o *out
GCC高級(jí)技巧
1.指定頭文件位置
一是在源碼中指定頭文件的絕對(duì)路徑,簡(jiǎn)單直觀但缺乏靈活性,二是在編譯時(shí)使用“-I”參數(shù)來(lái)指定頭文件的路徑,實(shí)際工作中,一般選擇第二種。
使用第二種方法將resolv.c編譯為resolv.out的命令如下:
gcc resolv.c -I /home/myname/code/header -o resolv.out 如果找不到會(huì)按照代碼所在目錄或系統(tǒng)目錄尋找頭文件
gcc resolv.c -I /home/myname/code/header -I /home/myname/code/header2 -o resolv.out 多個(gè)路徑
2.定義符號(hào)常量
在代碼中會(huì)使用一些常量來(lái)控制程序的行為,如#define WIRELESS 211 等等一系列,怎么來(lái)檢驗(yàn)定義了符號(hào)常量與為定義符號(hào)常量的區(qū)別,一般在編譯時(shí)使用-D參數(shù)來(lái)指定符號(hào)常量,命令如下:gcc -D WIRELESS -I /home/myname/code/header resolv.c -o resolv.out
3.定義警告級(jí)別
最常用的警告選項(xiàng)是-Wall選項(xiàng)。其意思是warning all。使用如下命令顯示特定警告信息來(lái)編譯test.c,命令如下:
gcc -Wall test.c -o test
4.其他GCC選項(xiàng)
gcc [option] [filename]
- -c:只將源代碼編譯為以.o為后綴的目標(biāo)文件,而不是直接將這些文件連接可執(zhí)行文件。通常用于不包含主程序(man函數(shù))的子程序代碼。
- -o:filename: 指定輸出文件名。如果不用這個(gè)選項(xiàng),gcc會(huì)將文件輸出到a.out,而不管輸出文件的類(lèi)型
- -g:產(chǎn)生調(diào)試信息。如果要使用gdb進(jìn)行調(diào)式,則必須使用該選項(xiàng)。但是該選項(xiàng)所產(chǎn)生的調(diào)式符號(hào),并不能被其他調(diào)式器識(shí)別。
- -O:在程序編譯、連接過(guò)程中對(duì)代碼進(jìn)行優(yōu)化。
- -O2:比-O更好的優(yōu)化編譯、連接。
- -L dir:在程序連接時(shí),會(huì)首先在dir目錄尋找類(lèi)庫(kù)文件,然后在系統(tǒng)預(yù)設(shè)路徑中尋找類(lèi)庫(kù)。也可以使用多個(gè)-L參數(shù)指定多個(gè)類(lèi)庫(kù)存放的目錄。
- -lname:在程序連接時(shí)加載名為libname.a的函數(shù)庫(kù)。如-lmath 表示連接名為libmath.a的數(shù)學(xué)函數(shù)庫(kù)。
- --sysboot=dir:讓目錄dir作為頭文件和庫(kù)文件的根目錄
- -B dir:將目錄dir添加到編譯器的搜索路徑中。
- -b:指定gcc編譯的目標(biāo)機(jī)器架構(gòu),如ARM、DEC、GNU/Linux、IA64、MIPS等,這也可以看出gcc的超級(jí)跨平臺(tái)性。
- -V n1.n2:使用n1.n2指定版本的gcc進(jìn)行編譯
- -E:僅作預(yù)處理,不能進(jìn)行編譯等工作,生成i文件
- -S:將源碼編譯為匯編語(yǔ)言代碼
- -x lang:將源代碼依照特定語(yǔ)言進(jìn)行編譯,可以取得值包括但不限于C、C++、Objective-C、Objective-C++、Assembler、Ada、java等。在一系列的編譯中,該選項(xiàng)會(huì)一直保持,知道另一個(gè)-x lang出現(xiàn),指定另一種編譯語(yǔ)言。如果是none,意味著讓gcc一句文件的后綴來(lái)自動(dòng)判斷語(yǔ)言種類(lèi)。
在Linux 下面,如果要編譯一個(gè)C 語(yǔ)言源程序,我們要使用GNU 的gcc 編譯器。下面
我們以一個(gè)實(shí)例來(lái)說(shuō)明如何使用gcc 編譯器。假設(shè)我們有下面一個(gè)非常簡(jiǎn)單的源程序
(hello.c):
int main(int argc,char **argv)
{
printf("Hello Linux\n");
}
要編譯這個(gè)程序,我們只要在命令行下執(zhí)行:
gcc -o hello hello.c
下面就詳細(xì)說(shuō)一下gcc的編譯過(guò)程
gcc由C語(yǔ)言源代碼文件生成可執(zhí)行文件的過(guò)程,一般來(lái)說(shuō)分為四個(gè)階段:預(yù)處理(也稱(chēng)預(yù)編譯Preprocessing)、編譯(compilation)、匯編(Assembly)和鏈接(linking)。這四個(gè)階段分別由gcc調(diào)用不同的程序來(lái)實(shí)現(xiàn)。
- 預(yù)處理是調(diào)用cpp程序來(lái)實(shí)現(xiàn)的,預(yù)處理主要是對(duì)包含語(yǔ)句、宏定義等進(jìn)行處理。
- 編譯是調(diào)用cc來(lái)實(shí)現(xiàn)的,它是源文件變?yōu)楹缶Y為.o的目標(biāo)文件的過(guò)程。
- 匯編過(guò)程是對(duì)匯編語(yǔ)言的操作,通過(guò)調(diào)用as來(lái)實(shí)現(xiàn),匯編同樣也生成目標(biāo)文件。
- 鏈接是通過(guò)用ld來(lái)實(shí)現(xiàn)的。這是最為關(guān)鍵的步驟,在該階段,ld會(huì)將各程序的執(zhí)行代碼放置在程序的適合位置,同時(shí),程序調(diào)用的庫(kù)函數(shù)也會(huì)以適當(dāng)?shù)姆椒ㄔO(shè)置調(diào)用接口。
gcc編譯時(shí),如果在命令行沒(méi)有指定其他參數(shù),則gcc會(huì)完成編譯、鏈接的過(guò)程,然后在當(dāng)前目錄中生成一個(gè)名為a.out的可執(zhí)行文件。一般來(lái)說(shuō),linux并不依賴(lài)文件的后綴來(lái)識(shí)別文件是否為可執(zhí)行程序,其判斷文件是否可執(zhí)行依據(jù)的是文件的屬性。如果對(duì)于當(dāng)前用戶而言,文件有運(yùn)行權(quán)限,則該文件為一個(gè)可執(zhí)行程序。
對(duì)于gcc而言,判斷文件的類(lèi)型主要是依據(jù)文件的后綴名。所以,要使用gcc編譯代碼,正確使用文件后綴是保證編譯正確的前提。如果寫(xiě)了一個(gè)C++代碼,卻使用了.c為后綴,gcc在編譯該文件時(shí)會(huì)將該文件按照C語(yǔ)言代碼來(lái)處理,一般會(huì)出錯(cuò)。
一些gcc常用的文件后綴名:
- c: C語(yǔ)言源代碼文件
- a:由目標(biāo)文件構(gòu)成的檔案庫(kù)文件
- .C、.cc 或.cxx:c++源代碼文件
- h:頭文件
- i:經(jīng)過(guò)預(yù)處理的C源代碼文件
- ii:經(jīng)過(guò)預(yù)處理的C++源代碼文件
- m:Objective-C源代碼文件
- o:編譯后的目標(biāo)文件
- s:匯編語(yǔ)言源代碼文件
- S:經(jīng)過(guò)預(yù)編譯的匯編語(yǔ)言源代碼文件
gcc hello.c編譯通過(guò)后,就可以簡(jiǎn)單的使用a.out調(diào)用該程序,使用命令如下:./a.out - 注意:這里不能直接使用a.out來(lái)調(diào)用該程序,因?yàn)閟hell在尋找可執(zhí)行程序時(shí),并不在當(dāng)前目錄中尋找,所以必須用“./”來(lái)顯示指定該文件的路徑是當(dāng)前目錄
1.關(guān)于創(chuàng)建Direct3D設(shè)備對(duì)象
創(chuàng)建Direct3D設(shè)備對(duì)象時(shí),需要先創(chuàng)建Direct3D對(duì)象,然后再調(diào)用Direct3D對(duì)象的接口函數(shù)IDirect3D9::CreateDevice創(chuàng)建Direct3D設(shè)備對(duì)象。通過(guò)同一個(gè)Direct3D對(duì)象創(chuàng)建的所有Direct3D設(shè)備對(duì)象共享相同的物理資源(顯卡)。因?yàn)楣蚕硗挥布匀绻ㄟ^(guò)一個(gè)Direct3D對(duì)象創(chuàng)建多個(gè)Direct3D渲染設(shè)備對(duì)象會(huì)明顯降低系統(tǒng)性能。
在創(chuàng)建Direct3D設(shè)備對(duì)象之前,還需要先初始化D3DPRESENT_PARAMENTERS結(jié)構(gòu),該結(jié)構(gòu)用于創(chuàng)建Direct3D設(shè)備對(duì)象。此結(jié)構(gòu)將會(huì)影響Direct3D設(shè)備的顯示方法。
D3DPRESENT_PARAMETERS
Describes the presentation parameters.
typedef struct D3DPRESENT_PARAMETERS {
UINT BackBufferWidth, BackBufferHeight;
D3DFORMAT BackBufferFormat;
UINT BackBufferCount;
D3DMULTISAMPLE_TYPE MultiSampleType;
DWORD MultiSampleQuality;
D3DSWAPEFFECT SwapEffect;
HWND hDeviceWindow;
BOOL Windowed;
BOOL EnableAutoDepthStencil;
D3DFORMAT AutoDepthStencilFormat;
DWORD Flags;
UINT FullScreen_RefreshRateInHz;
UINT PresentationInterval;
} D3DPRESENT_PARAMETERS, *LPD3DPRESENT_PARAMETERS;
Members
- BackBufferWidth, BackBufferHeight
- Width and height of the new swap chain's back buffers, in pixels. If Windowed is FALSE (the presentation is full-screen), these values must equal the width and height of one of the enumerated display modes found through IDirect3D9::EnumAdapterModes. If Windowed is TRUE and either of these values is zero, the corresponding dimension of the client area of the hDeviceWindow (or the focus window, if hDeviceWindow is NULL) is taken.
- BackBufferFormat
- The back buffer format. For more information about formats, see D3DFORMAT. This value must be one of the render-target formats as validated by IDirect3D9::CheckDeviceType. You can use IDirect3DDevice9::GetDisplayMode to obtain the current format.
In fact, D3DFMT_UNKNOWN can be specified for the BackBufferFormat while in windowed mode. This tells the runtime to use the current display-mode format and eliminates the need to call IDirect3DDevice9::GetDisplayMode.
For windowed applications, the back buffer format no longer needs to match the display-mode format because color conversion can now be done by the hardware (if the hardware supports color conversion). The set of possible back buffer formats is constrained, but the runtime will allow any valid back buffer format to be presented to any desktop format. (There is the additional requirement that the device be operable in the desktop mode; devices typically do not operate in 8 bits per pixel modes.)
Full-screen applications cannot do color conversion.
- BackBufferCount
- This value can be between 0 and D3DPRESENT_BACK_BUFFERS_MAX (or D3DPRESENT_BACK_BUFFERS_MAX_EX when using Direct3D 9Ex). Values of 0 are treated as 1. If the number of back buffers cannot be created, the runtime will fail the method call and fill this value with the number of back buffers that could be created. As a result, an application can call the method twice with the same D3DPRESENT_PARAMETERS structure and expect it to work the second time.
The method fails if one back buffer cannot be created. The value of BackBufferCount influences what set of swap effects are allowed. Specifically, any D3DSWAPEFFECT_COPY swap effect requires that there be exactly one back buffer.
- MultiSampleType
- Member of the D3DMULTISAMPLE_TYPE enumerated type. The value must be D3DMULTISAMPLE_NONE unless SwapEffect has been set to D3DSWAPEFFECT_DISCARD. Multisampling is supported only if the swap effect is D3DSWAPEFFECT_DISCARD.
- MultiSampleQuality
- Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by IDirect3D9::CheckDeviceMultiSampleType. Passing a larger value returns the error D3DERR_INVALIDCALL. Paired values of render targets or of depth stencil surfaces and D3DMULTISAMPLE_TYPE must match.
- SwapEffect
- Member of the D3DSWAPEFFECT enumerated type. The runtime will guarantee the implied semantics concerning buffer swap behavior; therefore, if Windowed is TRUE and SwapEffect is set to D3DSWAPEFFECT_FLIP, the runtime will create one extra back buffer and copy whichever becomes the front buffer at presentation time.
D3DSWAPEFFECT_COPY requires that BackBufferCount be set to 1.
D3DSWAPEFFECT_DISCARD will be enforced in the debug runtime by filling any buffer with noise after it is presented.
Differences between Direct3D9 and Direct3D9Ex
In Direct3D9Ex, D3DSWAPEFFECT_FLIPEX is added to designate when an application is adopting flip mode. That is, whan an application's frame is passed in window's mode (instead of copied) to the Desktop Window Manager(DWM) for composition. Flip mode provides more efficient memory bandwidth and enables an application to take advantage of full-screen-present statistics. It does not change full screen behavior. Flip mode behavior is available beginning with Windows 7. |
- hDeviceWindow
- The device window determines the location and size of the back buffer on screen. This is used by Direct3D when the back buffer contents are copied to the front buffer during IDirect3DDevice9::Present.
-
For a full-screen application, this is a handle to the top window (which is the focus window).
For applications that use multiple full-screen devices (such as a multimonitor system), exactly one device can use the focus window as the device window. All other devices must have unique device windows.
- For a windowed-mode application, this handle will be the default target window for IDirect3DDevice9::Present. If this handle is NULL, the focus window will be taken.
Note that no attempt is made by the runtime to reflect user changes in window size. The back buffer is not implicitly reset when this window is reset. However, the IDirect3DDevice9::Present method does automatically track window position changes.
- Windowed
- TRUE if the application runs windowed; FALSE if the application runs full-screen.
- EnableAutoDepthStencil
- If this value is TRUE, Direct3D will manage depth buffers for the application. The device will create a depth-stencil buffer when it is created. The depth-stencil buffer will be automatically set as the render target of the device. When the device is reset, the depth-stencil buffer will be automatically destroyed and recreated in the new size.
If EnableAutoDepthStencil is TRUE, then AutoDepthStencilFormat must be a valid depth-stencil format.
- AutoDepthStencilFormat
- Member of the D3DFORMAT enumerated type. The format of the automatic depth-stencil surface that the device will create. This member is ignored unless EnableAutoDepthStencil is TRUE.
- Flags
- One of the D3DPRESENTFLAG constants.
- FullScreen_RefreshRateInHz
- The rate at which the display adapter refreshes the screen. The value depends on the mode in which the application is running:
- For windowed mode, the refresh rate must be 0.
- For full-screen mode, the refresh rate is one of the refresh rates returned by IDirect3D9::EnumAdapterModes.
- PresentationInterval
- The maximum rate at which the swap chain's back buffers can be presented to the front buffer. For a detailed explanation of the modes and the intervals that are supported, see D3DPRESENT.
Requirements
Header: Declared in D3D9Types.h.
幾個(gè)重要的參數(shù)加以解釋說(shuō)明一下,其中BackBufferWidth和BackBufferHeight指定后臺(tái)緩存區(qū)的寬高(以像素為單位)。如果圖形以窗口方式顯示并且該成員變量被設(shè)置為0,則系統(tǒng)自動(dòng)使用顯示窗口客戶區(qū)的寬高作為后臺(tái)緩沖區(qū)的寬高。BackBufferCount指定后臺(tái)緩沖區(qū)的數(shù)量。該值可以為0、1、2、3,其中0和1時(shí)都表示創(chuàng)建一個(gè)后臺(tái)緩沖區(qū)。通常使用一個(gè)后臺(tái)緩沖區(qū)和一個(gè)主緩存,主緩存將其顯示在屏幕上。
這兩天考慮把DirectX 版本升級(jí),同時(shí)把相關(guān)的功能也升級(jí),比如畫(huà)圖,之前用的是DirectDraw比較老,現(xiàn)在想改用Direct2D。
Direct2D是DirectX11中的新特性,可以說(shuō)是DirectDraw的升級(jí)版。DirectX最新版本
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=6812,當(dāng)然要想使用DirectX11需要系統(tǒng)支持,win7中就已帶DirectX11,而vista中使用就需要Update,以下來(lái)自MSDN文檔
Direct3D 11 Runtime
To obtain the Direct3D 11 runtime, please install the release version of Windows 7 or Windows Server 2008 R2. Windows Vista users can follow the procedure described in
KB 971644 (or
KB 971512 for corporate network users).
http://support.microsoft.com/kb/971644具體如何去實(shí)現(xiàn)一個(gè)DirectX2D Application 參見(jiàn)DirectX 2010.6 版本中SDK文檔——Windows DirectX Graphics Documention——Direct2D
Direct2D入門(mén):
http://blog.pfan.cn/lym51/52200.html使用Direct2D繪圖
http://msdn.microsoft.com/zh-cn/magazine/ee413543.aspx
1、為什么要進(jìn)行傅里葉變換,其物理意義是什么?
傅立葉變換是數(shù)字信號(hào)處理領(lǐng)域一種很重要的算法。要知道傅立葉變換算法的意義,首先要了解傅立葉原理的意義。傅立葉原理表明:任何連續(xù)測(cè)量的時(shí)序或信號(hào),都可以表示為不同頻率的正弦波信號(hào)的無(wú)限疊加。而根據(jù)該原理創(chuàng)立的傅立葉變換算法利用直接測(cè)量到的原始信號(hào),以累加方式來(lái)計(jì)算該信號(hào)中不同正弦波信號(hào)的頻率、振幅和相位。
和傅立葉變換算法對(duì)應(yīng)的是反傅立葉變換算法。該反變換從本質(zhì)上說(shuō)也是一種累加處理,這樣就可以將單獨(dú)改變的正弦波信號(hào)轉(zhuǎn)換成一個(gè)信號(hào)。
因此,可以說(shuō),傅立葉變換將原來(lái)難以處理的時(shí)域信號(hào)轉(zhuǎn)換成了易于分析的頻域信號(hào)(信號(hào)的頻譜),可以利用一些工具對(duì)這些頻域信號(hào)進(jìn)行處理、加工。最后還可以利用傅立葉反變換將這些頻域信號(hào)換成時(shí)域信號(hào)。
從現(xiàn)代數(shù)學(xué)的眼光來(lái)看,傅里葉變換是一種特殊的積分變換。它能將滿足一定條件的某個(gè)函數(shù)表示成正弦基函數(shù)的線性組合或者積分。在不同的研究領(lǐng)域,傅里葉變換具有多種不同的變體形式,如連續(xù)傅里葉變換和離散傅里葉變換。
在數(shù)學(xué)領(lǐng)域,盡管最初傅立葉分析是作為熱過(guò)程的解析分析的工具,但是其思想方法仍然具有典型的還原論和分析主義的特征。"任意"的函數(shù)通過(guò)一定的分解,都能夠表示為正弦函數(shù)的線性組合的形式,而正弦函數(shù)在物理上是被充分研究而相對(duì)簡(jiǎn)單的函數(shù)類(lèi):1. 傅立葉變換是線性算子,若賦予適當(dāng)?shù)姆稊?shù),它還是酉算子;2. 傅立葉變換的逆變換容易求出,而且形式與正變換非常類(lèi)似;3. 正弦基函數(shù)是微分運(yùn)算的本征函數(shù),從而使得線性微分方程的求解可以轉(zhuǎn)化為常系數(shù)的代數(shù)方程的求解.在線性時(shí)不變雜的卷積運(yùn)算為簡(jiǎn)單的乘積運(yùn)算,從而提供了計(jì)算卷積的一種簡(jiǎn)單手段;5. 離散形式的傅立葉的物理系統(tǒng)內(nèi),頻率是個(gè)不變的性質(zhì),從而系統(tǒng)對(duì)于復(fù)雜激勵(lì)的響應(yīng)可以通過(guò)組合其對(duì)不同頻率正弦信號(hào)的響應(yīng)來(lái)獲取;4. 著名的卷積定理指出:傅立葉變換可以化復(fù)變換可以利用數(shù)字計(jì)算機(jī)快速的算出(其算法稱(chēng)為快速傅立葉變換算法(FFT))。
正是由于上述的良好性質(zhì),傅里葉變換在物理學(xué)、數(shù)論、組合數(shù)學(xué)、信號(hào)處理、概率、統(tǒng)計(jì)、密碼學(xué)、聲學(xué)、光學(xué)等領(lǐng)域都有著廣泛的應(yīng)用。
2、圖像傅立葉變換的物理意義
圖像的頻率是表征圖像中灰度變化劇烈程度的指標(biāo),是灰度在平面空間上的梯度。如:大面積的沙漠在圖像中是一片灰度變化緩慢的區(qū)域,對(duì)應(yīng)的頻率值很低;而對(duì)于地表屬性變換劇烈的邊緣區(qū)域在圖像中是一片灰度變化劇烈的區(qū)域,對(duì)應(yīng)的頻率值較高。傅立葉變換在實(shí)際中有非常明顯的物理意義,設(shè)f是一個(gè)能量有限的模擬信號(hào),則其傅立葉變換就表示f的譜。從純粹的數(shù)學(xué)意義上看,傅立葉變換是將一個(gè)函數(shù)轉(zhuǎn)換為一系列周期函數(shù)來(lái)處理的。從物理效果看,傅立葉變換是將圖像從空間域轉(zhuǎn)換到頻率域,其逆變換是將圖像從頻率域轉(zhuǎn)換到空間域。換句話說(shuō),傅立葉變換的物理意義是將圖像的灰度分布函數(shù)變換為圖像的頻率分布函數(shù),傅立葉逆變換是將圖像的頻率分布函數(shù)變換為灰度分布函數(shù)
傅立葉變換以前,圖像(未壓縮的位圖)是由對(duì)在連續(xù)空間(現(xiàn)實(shí)空間)上的采樣得到一系列點(diǎn)的集合,我們習(xí)慣用一個(gè)二維矩陣表示空間上各點(diǎn),則圖像可由z=f(x,y)來(lái)表示。由于空間是三維的,圖像是二維的,因此空間中物體在另一個(gè)維度上的關(guān)系就由梯度來(lái)表示,這樣我們可以通過(guò)觀察圖像得知物體在三維空間中的對(duì)應(yīng)關(guān)系。
為什么要提梯度?因?yàn)閷?shí)際上對(duì)圖像進(jìn)行二維傅立葉變換得到頻譜圖,就是圖像梯度的分布圖,當(dāng)然頻譜圖上的各點(diǎn)與圖像上各點(diǎn)并不存在一一對(duì)應(yīng)的關(guān)系,即使在不移頻的情況下也是沒(méi)有。傅立葉頻譜圖上我們看到的明暗不一的亮點(diǎn),實(shí)際上圖像上某一點(diǎn)與鄰域點(diǎn)差異的強(qiáng)弱,即梯度的大小,也即該點(diǎn)的頻率的大小(可以這么理解,圖像中的低頻部分指低梯度的點(diǎn),高頻部分相反)。一般來(lái)講,梯度大則該點(diǎn)的亮度強(qiáng),否則該點(diǎn)亮度弱。這樣通過(guò)觀察傅立葉變換后的頻譜圖,也叫功率圖,我們首先就可以看出,圖像的能量分布,如果頻譜圖中暗的點(diǎn)數(shù)更多,那么實(shí)際圖像是比較柔和的(因?yàn)楦鼽c(diǎn)與鄰域差異都不大,梯度相對(duì)較小),反之,如果頻譜圖中亮的點(diǎn)數(shù)多,那么實(shí)際圖像一定是尖銳的,邊界分明且邊界兩邊像素差異較大的。對(duì)頻譜移頻到原點(diǎn)以后,可以看出圖像的頻率分布是以原點(diǎn)為圓心,對(duì)稱(chēng)分布的。將頻譜移頻到圓心除了可以清晰地看出圖像頻率分布以外,還有一個(gè)好處,它可以分離出有周期性規(guī)律的干擾信號(hào),比如正弦干擾,一副帶有正弦干擾,移頻到原點(diǎn)的頻譜圖上可以看出除了中心以外還存在以某一點(diǎn)為中心,對(duì)稱(chēng)分布的亮點(diǎn)集合,這個(gè)集合就是干擾噪音產(chǎn)生的,這時(shí)可以很直觀的通過(guò)在該位置放置帶阻濾波器消除干擾
另外我還想說(shuō)明以下幾點(diǎn):
1、圖像經(jīng)過(guò)二維傅立葉變換后,其變換系數(shù)矩陣表明:
若變換矩陣Fn原點(diǎn)設(shè)在中心,其頻譜能量集中分布在變換系數(shù)短陣的中心附近(圖中陰影區(qū))。若所用的二維傅立葉變換矩陣Fn的原點(diǎn)設(shè)在左上角,那么圖像信號(hào)能量將集中在系數(shù)矩陣的四個(gè)角上。這是由二維傅立葉變換本身性質(zhì)決定的。同時(shí)也表明一股圖像能量集中低頻區(qū)域。
2 、變換之后的圖像在原點(diǎn)平移之前四角是低頻,最亮,平移之后中間部分是低頻,最亮,亮度大說(shuō)明低頻的能量大(幅角比較大)
BOOL CD3DCameraViewWnd::GetImageInfo(DWORD* pPixelBuffer, int& width,int& height)
{
BOOL result = FALSE;
IDirect3DSurface9 *_surfaceback = NULL;
if (FAILED(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &_surfaceback)))
{
result = FALSE;
}
D3DSURFACE_DESC surfaceDesc;
if (!FAILED(_surfaceback->GetDesc(&surfaceDesc)))
{
width = surfaceDesc.Width;
height = surfaceDesc.Height;
}
D3DLOCKED_RECT lockedRect;
HRESULT hr = _surfaceback->LockRect( &lockedRect,0, 0); /* pointer to receive locked data指向申請(qǐng)到的內(nèi)存區(qū)域*/ /* lock entire surface*/// no lock flags specified
if (!FAILED(hr))
{
pPixelBuffer = (DWORD*)lockedRect.pBits;
result = TRUE;
}
_surfaceback->UnlockRect();
_surfaceback->Release();
return result;
}
但是這樣存在著性能的問(wèn)題,經(jīng)測(cè)試獲取一幀需要200ms左右,為什么會(huì)存在這樣的問(wèn)題?因?yàn)檫@邊有資源鎖定操作。
現(xiàn)在關(guān)鍵的問(wèn)題就在于,資源鎖定的操作速度總是非常之慢.當(dāng)然,你會(huì)跟我提, OpenGL似乎能夠快捷地完成這項(xiàng)任務(wù).但是,在Direct3D中,資源鎖定操作確實(shí)是很慢的.這里面一個(gè)主要的原因是,API,驅(qū)動(dòng),以及硬件要處理一些不可回避的后臺(tái)操作.那就是GPU與CPU是并行運(yùn)行的,若不加任何措施,將引起類(lèi)似多線程程序同步時(shí)的競(jìng)態(tài)條件的問(wèn)題.
如果你試圖去修改的資源正同時(shí)被一個(gè)位于GPU處理序列中的指令使用,那么整個(gè)渲染流程就會(huì)因?yàn)槟愕馁Y源鎖定而停頓或強(qiáng)制刷新(stalls and flushes).停頓(stall)會(huì)一直持續(xù)到你完成了對(duì)資源的修改并調(diào)用Unlock().而強(qiáng)制刷新(flush)則會(huì)要求GPU在你得到這個(gè)資源的訪問(wèn)權(quán)之前完成目前所有的任務(wù).
如何去解決這個(gè)問(wèn)題?下面的參考資料中有一些解決方案,我沒(méi)有經(jīng)過(guò)認(rèn)真測(cè)試,我試了其中一個(gè)GetRenderTargetData 這樣的一種方法 ,感覺(jué)不太好用,why請(qǐng)看Reference3
下面給出我的解決方案
BOOL CD3DCameraViewWnd::GetImageInfo(DWORD* pPixelBuffer, int& width,int& height)
{
BOOL result = FALSE;
IDirect3DSurface9 *_surfaceback = NULL;
if (FAILED(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &_surfaceback)))
{
result = FALSE;
}
D3DSURFACE_DESC surfaceDesc;
if (!FAILED(_surfaceback->GetDesc(&surfaceDesc)))
{
width = surfaceDesc.Width;
height = surfaceDesc.Height;
}
LPDIREC3DSURFACE9 surf;
if(FAILED(m_pDevice->CreateOffscreenPlainSurface(width, height,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM, &surf,NULL)))
{
result = FALSE;
}
D3DXLoadSurfaceFromSurface(surf, NULL,NULL,_surfaceback,NULL,NULL,D3DX_FILTER_NONE,0);
D3DLOCKED_RECT lockedRect;
HRESULT hr = surf->LockRect( &lockedRect,0, 0); /* pointer to receive locked data指向申請(qǐng)到的內(nèi)存區(qū)域*/ /* lock entire surface*/// no lock flags specified
if (!FAILED(hr))
{
pPixelBuffer = (DWORD*)lockedRect.pBits;
result = TRUE;
}
surf->UnlockRect();
surf->Release();
_surfaceback->Release();
return result;
}
參考資料:Reference1.http://www.cnblogs.com/mixiyou/archive/2010/02/25/1673060.html
Reference 2.http://www.cnblogs.com/mixiyou/archive/2010/02/25/1673425.html
Reference 3.http://blog.csdn.net/Nightmare/article/details/1707362
Reference 4.http://www.cnblogs.com/lancidie/archive/2011/3/14.html
摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->////////////////////////////////////////////////////////////////////////////////// CppSQLite3&nbs...
閱讀全文