Wednesday, November 22, 2006

文章總覽

VFW:

VFW.H ( 28 Sep, 2006 )
取得視訊裝置驅動程式的資訊 ( 29 Sep, 2006 )
如何建立一個視訊擷取視窗 ( 13 Oct, 2006 )
連結視訊擷取視窗與視訊裝置 ( 13 Oct, 2006 )
取得視訊裝置驅動程式的效能 ( 15 Oct, 2006 )
設定顯示模式 ( 15 Oct, 2006 )
設定視訊畫面顯示速率 ( 15 Oct, 2006 )
調整視訊畫面大小 ( 15 Oct, 2006 )
靜態影像擷取 ( 1 Nov, 2006 )
錄影參數設定 ( 4 Nov, 2006 )

Bitmap:

RGB macro ( 12 Oct, 2006 )
位元塊傳輸 BitBlt ( 18 Nov, 2006 )

Data Tpyes & Classes:

TColor type ( 6 Oct, 2006 )
TCanvas ( 6 Oct, 2006 )
TRect type ( 21 Oct, 2006 )
tagPOINT type ( 28, May, 2006 )

Objects & Methods:

TImage ( 25 Sep, 2006 )
TPicture ( 25 Sep, 2006 )
Objects ( 26 Sep, 2006 )
TCanvas::CopyRect method ( 21 Oct, 2006 )

Basic:

開啟 BMP 影像 ( 11 Sep, 2006 )
開啟 JPEG 影像 ( 11 Sep, 2006 )
動態宣告二維陣列 ( 13 Sep, 2006 )
Visual Component Library (VCL) ( 24 Sep, 2006 )
Component Palette ( 25 Sep, 2006 )
如何讓 Label 顯示實數值 ( 13 Nov, 2006)
將布林值轉成字串 BoolToStr ( 4 Nov, 2006 )

 

Saturday, November 18, 2006

Bitmap: 位元塊傳輸 BitBlt

當我們想將圖像從視訊顯示的某個區域複製到另外一個區域時, 可以考慮使用 Windows 圖形裝置介面 (Graphics Device Interface, GDI) 所提供的位元塊傳輸 ( bit-block transfer ) 函式 BitBlt。BitBlt 讀作 bit blit, 有關 Bit Blit 這個指令的來源, 在 維基百科有相當詳細的描述; 除此, 維基百科還用小精靈為例子, 介紹關於背景圖片與 BitBlt 的使用方法, 值得一看...
The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context.

BOOL BitBlt(
 HDC hdcDest,
  // handle to destination device context
 int nXDest,
  // x-coordinate of destination rectangle's upper-left corner
 int nYDest,
  // y-coordinate of destination rectangle's upper-left corner
 int nWidth,
  // width of destination rectangle
 int nHeight,
  // height of destination rectangle
 HDC hdcSrc,
  // handle to source device context
 int nXSrc,
  // x-coordinate of source rectangle's upper-left corner
 int nYSrc,
  // y-coordinate of source rectangle's upper-left corner
 DWORD dwRop
  // raster operation code
);

Parameters
hdcDest Identifies the destination device context.

nXDest
 Specifies the logical x-coordinate of the upper-left corner of the destination rectangle.

nYDest
 Specifies the logical y-coordinate of the upper-left corner of the destination rectangle.

nWidth
 Specifies the logical width of the source and destination rectangles.

nHeight
 Specifies the logical height of the source and the destination rectangles.

hdcSrc
 Identifies the source device context.

nXSrc
 Specifies the logical x-coordinate of the upper-left corner of the source rectangle.

nYSrc
 Specifies the logical y-coordinate of the upper-left corner of the source rectangle.

dwRop
 Specifies a raster-operation code. These codes define how the color data for the source rectangle is to be combined with the color data for the destination rectangle to achieve the final color.

The following list shows some common raster operation codes:

Value Description

BLACKNESS  Fills the destination rectangle using the color associated with index 0 in the physical palette. (This color is black for the default physical palette.)

DSTINVERT  Inverts the destination rectangle.

MERGECOPY Merges the colors of the source rectangle with the specified pattern by using the Boolean AND operator.

MERGEPAINT  Merges the colors of the inverted source rectangle with the colors of the destination rectangle by using the Boolean OR operator.

NOTSRCCOPY Copies the inverted source rectangle to the destination.

NOTSRCERASE 
Combines the colors of the source and destination rectangles by using the Boolean OR operator and then inverts the resultant color.

PATCOPY
 Copies the specified pattern into the destination bitmap.

PATINVERT
 Combines the colors of the specified pattern with the colors of the destination rectangle by using the Boolean XOR operator.

PATPAINT
 Combines the colors of the pattern with the colors of the inverted source rectangle by using the Boolean OR operator. The result of this operation is combined with the colors of the destination rectangle by using the Boolean OR operator.

SRCAND
 Combines the colors of the source and destination rectangles by using the Boolean AND operator.

SRCCOPY  Copies the source rectangle directly to the destination rectangle.

SRCERASE  Combines the inverted colors of the destination rectangle with the colors of the source rectangle by using the Boolean AND operator.

SRCINVERT  Combines the colors of the source and destination rectangles by using the Boolean XOR operator.

SRCPAINT  Combines the colors of the source and destination rectangles by using the Boolean OR operator.

WHITENESS Fills the destination rectangle using the color associated with index 1 in the physical palette. (This color is white for the default physical palette.)

Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks
If a rotation or shear transformation is in effect in the source device context, BitBlt returns an error. If other transformations exist in the source device context (and a matching transformation is not in effect in the destination device context), the rectangle in the destination device context is stretched, compressed, or rotated as necessary.

If the color formats of the source and destination device contexts do not match, the BitBlt function converts the source color format to match the destination format.

When an enhanced metafile is being recorded, an error occurs if the source device context identifies an enhanced-metafile device context.

Not all devices support the BitBlt function. For more information, see the RC_BITBLT raster capability entry in GetDeviceCaps.

BitBlt returns an error if the source and destination device contexts represent different devices.

針對 BitBlt 這個指令, 我做了一項有趣的實驗, 利用 WebCam 攝影機拍攝了連續兩張影像, 這兩張影像人眼看起來雖然相同, 但是, 由於光影的影響, 還是存在一些像素的色彩值有些許的差異。



我使用 BitBlt 這個指令, 並設定運算模式為 SRCINVERT, 將一張影像從 Device Context (DC), 傳送到另外一張影像的 DC 中, 得到下列這張影像...



很有趣的實驗, 你知道為什麼這張影像會出現紅、綠、藍這些顏色嗎?
 

Monday, November 13, 2006

如何讓 Label 顯示實數值

在程式中, 我們常會遭遇到要顯示實數(real number)的問題, 早期我會直接寫一個小程式把實數中每一個 digit 都算出來, 然後轉換成 AnsiString, 再把字串接起來, 再顯示到 Label 上。

後來, 我的作法就簡單多了, 直接用 sprintf 的方式, 將實數輸出到某一個字串中, 然後再顯示到某個 Label 上。例如:

//宣告部份
char Message[10];

//程式部份
RMS = sqrt(SquareErrorSum/(MH*MW*3));
sprintf(Message,"%6.3f",RMS);
lblRMS->Caption = "RMS="+AnsiString(Message);
 

Saturday, November 04, 2006

VFW: 取得與設定錄影參數

攝影機錄影期間, 必須針對需求設定相關攝影參數, 這些參數在 vfw.h 之中, 宣告一個資料型態來儲存這些參數。
typedef struct tagCaptureParms {
 DWORD dwRequestMicroSecPerFrame;
           // Requested capture rate
 BOOL fMakeUserHitOKToCapture; // Show "Hit OK to cap" dlg?
 UINT wPercentDropForError; // Give error msg if > (10%)
 BOOL fYield; // Capture via background task?
 DWORD dwIndexSize; // Max index size in frames (32K)
 UINT wChunkGranularity; // Junk chunk granularity (2K)
 BOOL fUsingDOSMemory; // Use DOS buffers?
 UINT wNumVideoRequested; // # video buffers, If 0, autocalc
 BOOL fCaptureAudio; // Capture audio?
 UINT wNumAudioRequested; // # audio buffers, If 0, autocalc
 UINT vKeyAbort; // Virtual key causing abort
 BOOL fAbortLeftMouse; // Abort on left mouse?
 BOOL fAbortRightMouse; // Abort on right mouse?
 BOOL fLimitEnabled; // Use wTimeLimit?
 UINT wTimeLimit; // Seconds to capture
 BOOL fMCIControl; // Use MCI video source?
 BOOL fStepMCIDevice; // Step MCI device?
 DWORD dwMCIStartTime; // Time to start in MS
 DWORD dwMCIStopTime; // Time to stop in MS
 BOOL fStepCaptureAt2x; // Perform spatial averaging 2x
 UINT wStepCaptureAverageFrames;
          // Temporal average n Frames
 DWORD dwAudioBufferSize; // Size of audio bufs (0 = default)
 BOOL fDisableWriteCache; // Attempt to disable write cache
 UINT AVStreamMaster; // Which stream controls length?
} CAPTUREPARMS, *PCAPTUREPARMS, FAR *LPCAPTUREPARMS;

因此, 我們在程式中可以如下宣告一個變數 s,
tagCaptureParms s;
然後, 我們就可以透過 &s 當作為呼叫 VFW SDK 相關函數的參數, 了解目前視訊系統的攝影參數設定為何? 一般來說, 一些我們比較常用到的攝影參數為:
  • 指定視訊畫面的擷取速率
  • 指定分派影像緩衝區數目
  • 選擇是否'擷取聲音
  • 指定視訊串流擷取時間長短
  • 指定擷取時間是否使用 MCI 裝置
  • 指定鍵盤或滑鼠控制來終止擷取
在 VFW SDK 中, 透過 capCaptureGetSetup 可以知道目前的錄影參數的設定為何?
The capCaptureGetSetup macro retrieves the current settings of the streaming capture parameters.

BOOL capCaptureGetSetup(
 hwnd,
 s,
 wSize
 );

Parameters
hwnd Handle of a capture window.
s Address of a CAPTUREPARMS structure.
wSize Size, in bytes, of the structure referenced by s.

Return Values
Returns TRUE if successful or FALSE otherwise.

Remarks
For information about the parameters used to control streaming capture, see the CAPTUREPARMS structure.
知道了錄影參數的設定情形後, 我們也可以透過 capCaptureSetSetup 來改變錄影參數的設定:
The capCaptureSetSetup macro sets the configuration parameters used with streaming capture.

BOOL capCaptureSetSetup(
 hwnd,
 s,
 wSize
 );

Parameters
hwnd Handle of a capture window.
s Address of a CAPTUREPARMS structure.
wSize Size, in bytes, of the structure referenced by s.

Return Values
Returns TRUE if successful or FALSE otherwise.

Remarks
For information about the parameters used to control streaming capture, see the CAPTUREPARMS structure.
延伸閱讀: C++ Builder's Help 中的 CAPTUREPARMS structure

將布林值轉成字串 BoolToStr

運用在邏輯運算的 Boolean 型態值有 true or false 兩個。因此, 這兩個字在 C++ 屬於 specific keywords。換句話說, 你不可以用這兩個字當變數名稱, 它們是有特定意義的。

我們再深入一點探討, 電腦是怎麼儲存這個形態的變數呢? 我們看看 BCB 中的 Help 是怎麼說的:
bool, true, false

Category

C++-Specific Keywords

Syntax
bool ;

Description
Use bool and the literals false and true to perform Boolean logic tests.

The bool keyword represents a type that can take only the value false or true. The keywords false and true are Boolean literals with predefined values. false is numericallly zero and true is numerically one. These Boolean literals are rvalues; you cannot make an assignment to them.

You can convert an rvalue that is of type bool to an rvalue that is int type. The numerical conversion sets false to zero and true becomes one.

You can convert arithmetic, enumeration, pointer, or pointer to member rvalue types to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false. Any other value is converted to true.

很顯然地, 這些 Boolean 值在電腦中, 也是用電腦基本的 0, 1 數值來儲存。"The keywords false and true are Boolean literals with predefined values. false is numericallly zero and true is numerically one." 此外, 我們也可以把一些其他型態的值轉換成布林值, 像 0, null pointer value, null member pointer value 會被轉換成 false, 其餘則是通通轉換成 true

在 BCB 中, 還提供了一個 BoolToStr 將布林值轉換成字串。
BoolToStr(bool B, bool UseBoolStrs)
Converts a Boolean value to an AnsiString.

Unit
SysUtils

Category
type conversion routines

extern PACKAGE AnsiString __fastcall BoolToStr(bool B, bool UseBoolStrs = false);

Description
BoolToStr converts the given Boolean value to a string as follows:

B UseBoolStrs  Returned string
true  false    "-1"
true  true    The first string in TrueBoolStrs (default, "TRUE");
false  false    "0"
false  true    The first string in FalseBoolStrs (default, "FALSE");

 

Wednesday, November 01, 2006

VFW: 靜態影像擷取

VFW SDK 所提供的擷取靜態影像方式是先抓取單一視訊畫面 ( frame ), 將其存入記憶體緩衝區中, 接下來你可以選擇要將存到剪貼簿中, 或是直接存成一張點陣圖檔 ( .BMP )。

抓取單一視訊畫面時, 依照不同需求, 可以使用 capGrabFrame 選擇讓原先動態的視訊畫面靜止, 或是用 capGrabFrameNoStop 不讓畫面靜止。靜止的影像可以讓我們清楚地看清抓取的視訊畫面為何, 如果要讓原先的擷取視窗恢復動態顯示, 則是必須重新 設定顯示模式 才行。

The capGrabFrame macro retrieves and displays a single frame from the capture driver. After capture, overlay and preview are disabled.

BOOL capGrabFrame(
 hwnd
 );

Parameters
hwnd Handle of a capture window.

Return Values
Returns TRUE if successful or FALSE otherwise.

Remarks
For information about installing callback functions, see the capSetCallbackOnError and capSetCallbackOnFrame macros.
因為必須告知要抓取哪一個視訊視窗, 所以函數的傳入值 ( parameter ) 就是該視窗的代碼 ( handle)。而傳回值 ( return value ) 就是告知我們是否成功捉取畫面。至於抓取畫面後的後續動作, 還可以使用回呼函數 ( callback function ) 來執行。
The capGrabFrameNoStop macro fills the frame buffer with a single uncompressed frame from the capture device and displays it. Unlike with the capGrabFrame macro, the state of overlay or preview is not altered by this message.

BOOL capGrabFrameNoStop(
 hwnd
 );

Parameters
hwnd Handle of a capture window.

Return Values
Returns TRUE if successful or FALSE otherwise.

Remarks
For information about installing callback functions, see the capSetCallbackOnError and capSetCallbackOnFrame macros.
以點陣圖格式 ( device independent bitmap, DIB ) 放入緩衝區的視訊畫面, 可以透過放到剪貼簿的方式 (capEditCopy) 讓別的應用程式使用。
The capEditCopy macro copies the contents of the video frame buffer and associated palette to the clipboard.

BOOL capEditCopy(
 hwnd
 );

Parameters
hwnd Handle of a capture window.

Return Values
Returns TRUE if successful or FALSE otherwise.
我們也可以使用 capFileSaveDIB 直接將緩衝區中畫面存成點陣圖檔 ( .BMP )。
The capFileSaveDIB macro copies the current frame to a DIB file.

BOOL capFileSaveDIB(
 hwnd,
 szName
);

Parameters
hwnd Handle of a capture window.
szName Address of the null-terminated string that contains the name of the destination DIB file.

Return Values
Returns TRUE if successful or FALSE otherwise. If an error occurs and an error callback function is set using the capSetCallbackOnError macro, the error callback function is called.

Remarks
If the capture driver supplies frames in a compressed format, this call attempts to decompress the frame before writing the file.
注意: 輸入參數 szName 變數名稱前置的 sz 告訴我們這是一個 null-terminated string。而要傳入的正是該 string 的記憶體位址 ( address )。因此, 若是我們在 BCB 中, 要用一個 TSavePictureDialog 類別的物件要讓使用者輸入檔名, 我們在程式中則是要將該物件的檔名屬性 ( TSavePictureDialog::FileName ) 中的檔名位址指定給 capFileSaveDIB 函數。假設該物件的名稱為 SavePictureDialog1, 而檔名的位址為: &SavePictureDialog1->FileName[1]。

範例程式:
 if ( SavePictureDialog1->Execute() )
  {
  capFileSaveDIB(hwndVideo,&(SavePictureDialog1->FileName[1]));
  }