全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:5357
推到 Plurk!
推到 Facebook!

使用Matrox Metor_II 要如何將擷取影像顯示在DISPLAY上的圖儲存起來

答題得分者是:hipig
fish730622
一般會員


發表:7
回覆:5
積分:2
註冊:2007-07-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-01-24 22:24:38 IP:210.240.xxx.xxx 訂閱
使用bcb6與Matrox Metor_II 卡 MIL8.0

我將CAMERA透過grab()來擷取單張影像顯示在Mildisplay上,
他有一個GrabContinuous()可以做連續擷取但是搞了很久沒辦法使他停止,
就改用透過timer來做連續的擷取影像 timer動作連續擷取畫面 timer停止則停止擷取
看了他的activemil help很久還是不知道要怎麼儲存影像
我將我程式碼po出來希望高手可以指導我該如何進行
或者是有更好的擷取影像的方法
能講的越詳細越好
你的講解是我進步的原動力
----------------------------------------------------
#include
#pragma hdrstop
#include "Unit1.h"
#include "mil.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "MIL_OCX"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Timer1->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Timer1->Enabled=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
MilDigitizer1->Grab();
}

hipig
高階會員


發表:31
回覆:75
積分:111
註冊:2007-01-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-01-25 10:26:52 IP:140.126.xxx.xxx 未訂閱
老實說,你的程式碼我覺得需要有的地方都沒寫出來。
不知道是否是因為資料不得流出的關係

反正這篇遲早會被我學弟上網搜尋到
就順便寫寫好了

使用Matrox 的影像卡最麻煩的地方是只能用MIL來驅動和開卡,對二次開發頗為麻煩
說得的現在這種不利於開發者的玩意(要轉移請付錢)我覺得會越來越少
首先你程式碼好像有叫OCX來做
這方面我不會
因為電腦上沒有影像卡
裝mil會出大問題...所以直接複製目錄下的library和include來用
這樣寫比較方便...至少我可以到處寫程式而不用窩在有裝卡的電腦前

我先簡單的說明啟動流程
開DCF檔設定攝影機->開影像卡->作後續工作
通常網路上面並不會特別去說明DCF檔有什麼特別,但你在使用上要注意
5.0-6.x的dcf設定是相同的,所以之間dll檔隨便你混用都沒關係,而7.x-8多了一堆東西
所以會變成你用5.0-6.x版的dll和mil.h寫出來的取像程式會無法開啟7.x-8的dcf
值得慶幸的是7.x-8版的dll和mil.h寫出來的可以向下相容

dcf檔是一個簡單的文字格式,你可以透過記事本開啟
其中我只會用到下列幾行
[INFO_FILE_REV]中第二行是影像卡類型,如果你要寫的程式可以靈活散佈在不同Matrox 的影像卡的電腦上
這就必須寫成較靈活的方式,通常網路上和泰絡(這家公司沒錢沒新範例呀)的資料大多將這部份寫死
[code cpp]
if(SLTmp->Strings[i 2]=="CORONA")
{
Image1->Picture=NULL;
Image1->Picture->Bitmap->LoadFromResourceName((int)HInstance, "CO");
CardN=1;
}
else if(SLTmp->Strings[i 2]=="GENESIS")
{
Image1->Picture=NULL;
Image1->Picture->Bitmap->LoadFromResourceName((int)HInstance, "GE");
CardN=2;
}
else if(SLTmp->Strings[i 2]=="METEOR")
{
Image1->Picture=NULL;
Image1->Picture->Bitmap->LoadFromResourceName((int)HInstance, "M1");
CardN=3;
}
else if(SLTmp->Strings[i 2]=="METEOR-II/MC")
{
Image1->Picture=NULL;
Image1->Picture->Bitmap->LoadFromResourceName((int)HInstance, "M2");
CardN=4;
}
else if(SLTmp->Strings[i 2]=="METEOR-II")
{
Image1->Picture=NULL;
Image1->Picture->Bitmap->LoadFromResourceName((int)HInstance, "M2");
VIEW->ID->Caption=4;
CardN=4;
}
else if(SLTmp->Strings[i 2]=="PULSAR")
{
Image1->Picture=NULL;
Image1->Picture->Bitmap->LoadFromResourceName((int)HInstance, "PU");
CardN=5;
}
else
{
Image1->Picture=NULL;
Image1->Picture->Bitmap->LoadFromResourceName((int)HInstance, "COM");
CardN=0;
}

[/code]
之後[GENERAL_PARAMETERS]部份是有關於這台攝影機的設定
其中VDC_IN_CH0到VDC_IN_CH_C代表纜線的顏色0x1代表true反之為false
VDT_HACTIVE和VDT_VACTIVE分別代表影像寬和高....這記住,因為之後我們開卡就直接抓這值來用,而不用手動指定

接著開啟影像卡顯示影像
我弄個新form來作這件事
先宣告資源...看你的需求要啥就宣告啥,這部份不用說明應該都要知道吧
[code cpp]
//Hao.Y W.
//---------------------------------------------------------------------------
#include
#include
#include
#include <math.h><br />#include
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
#include "Unit3.h"
#include "Unit4.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#pragma resource "millogo.res"
TVIEW *VIEW;
MIL_ID MilApplication,
MilSystem,
MilDisplay,
MilDigitizer,
MilImage,
MilImage1; //用來SAVE影像;

int IMAGE_WIDTH, IMAGE_HEIGHT,SNumbers=0;
int aSfilen,savesum=0; //檔名編號用

void Free_MIL(void)
{
MdigHalt(MilDigitizer);
MdigGrabWait(MilDigitizer, M_GRAB_END);

MbufFree(MilImage);
MbufFree(MilImage1);
MdispFree(MilDisplay);
MdigFree(MilDigitizer);
MsysFree(MilSystem);

MappFree(MilApplication);
};

[/code]
開卡開影像...一樣我的需求是這樣所以我才這樣寫
要是照學生習慣直接複製是死路一條
[code cpp]
switch(StrToInt(ID->Caption)) //CardN == ID->Caption
{
case 0:
{
Label1->Caption=0; //宣告啟用Mil系統,啟用通用模式
MappAlloc(M_DEFAULT, &MilApplication);
MsysAlloc(M_SYSTEM_METEOR_II, M_DEFAULT, M_DEFAULT, &MilSystem);
MdigAlloc(MilSystem, M_DEFAULT, "M_RS170", M_DEFAULT, &MilDigitizer);
MdispAlloc(MilSystem, M_DEFAULT, "M_RS170", M_DEFAULT, &MilDisplay);
MdigChannel(MilDigitizer,M_CH1);
MbufAlloc2d(MilSystem, 640, 480,8L M_UNSIGNED, M_IMAGE M_GRAB M_PROC M_DISP, &MilImage);
break;
}
case 1:
{
Label1->Caption=1;
MappAlloc(M_SETUP, &MilApplication);
MsysAlloc(M_SYSTEM_CORONA, M_DEFAULT, M_DEFAULT, &MilSystem);
MdispAlloc(MilSystem, M_DEFAULT, "M_DEFAULT", M_DEFAULT, &MilDisplay);
MdigAlloc(MilSystem, M_DEFAULT, (DirF->Caption).c_str(), M_DEFAULT, &MilDigitizer);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 M_UNSIGNED, M_IMAGE M_DISP M_GRAB M_PROC, &MilImage);
break;
}
case 2:
{
Label1->Caption=2;
MappAlloc(M_SETUP, &MilApplication);
// MsysAlloc(M_SYSTEM_GENESIS, M_DEFAULT, M_DEFAULT, &MilSystem);(實驗室函式庫不支援)
MdispAlloc(MilSystem, M_DEFAULT, "M_DEFAULT", M_DEFAULT, &MilDisplay);
MdigAlloc(MilSystem, M_DEFAULT, (DirF->Caption).c_str(), M_DEFAULT, &MilDigitizer);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 M_UNSIGNED, M_IMAGE M_DISP M_GRAB M_PROC, &MilImage);
break;
}
case 3:
{
Label1->Caption=3;
MappAlloc(M_SETUP, &MilApplication);
// MsysAlloc(M_SYSTEM_METEOR, M_DEFAULT, M_DEFAULT, &MilSystem);(實驗室函式庫不支援)
MdispAlloc(MilSystem, M_DEFAULT, "M_DEFAULT", M_DEFAULT, &MilDisplay);
MdigAlloc(MilSystem, M_DEFAULT, (DirF->Caption).c_str(), M_DEFAULT, &MilDigitizer);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 M_UNSIGNED, M_IMAGE M_DISP M_GRAB M_PROC, &MilImage);
break;
}
case 4:
{
Label1->Caption=4;
MappAlloc(M_SETUP, &MilApplication);
MsysAlloc(M_SYSTEM_METEOR_II, M_DEFAULT, M_DEFAULT, &MilSystem);
MdispAlloc(MilSystem, M_DEFAULT, "M_DEFAULT", M_DEFAULT, &MilDisplay);
MdigAlloc(MilSystem, M_DEFAULT, (DirF->Caption).c_str(), M_DEFAULT, &MilDigitizer);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 M_UNSIGNED, M_IMAGE M_DISP M_GRAB M_PROC, &MilImage);
break;
}
case 5:
{
Label1->Caption=5;
MappAlloc(M_SETUP, &MilApplication);
// MsysAlloc(M_SYSTEM_PULSAR, M_DEFAULT, M_DEFAULT, &MilSystem);
MdispAlloc(MilSystem, M_DEFAULT, "M_DEFAULT", M_DEFAULT, &MilDisplay);
MdigAlloc(MilSystem, M_DEFAULT, (DirF->Caption).c_str(), M_DEFAULT, &MilDigitizer);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 M_UNSIGNED, M_IMAGE M_DISP M_GRAB M_PROC, &MilImage);
break;
}
case 6:
{
Label1->Caption=6;
break;
}
}
MdispSelectWindow(MilDisplay, MilImage, ScrollBox1->Handle); //顯示影像於元件上
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 M_UNSIGNED, M_IMAGE M_PROC, &MilImage1);
MbufClear(MilImage1 , 0L);
MdigGrabContinuous(MilDigitizer, MilImage); //來源為擷取卡則連續輸出

[/code]
使用MdigGrabContinuous是讓攝影機連續輸出顯示,同樣的這邊也作清空MilImage1以利之後胡搞瞎搞
正常來說這時你已經做到可以在一個元件上顯示影像了
再來是存檔部份

不管你影像動的再慢,存檔時最好要先暫停一下,這問題我也很納悶
因為有些卡你可以無視畫面是否動態,一樣可以存檔,但有的卡卻會存成一張黑
保險起見都暫停吧
[code cpp]
SaveDialog1->FileName="image (" IntToStr(SNumbers) ")";
if (SaveDialog1->Execute())
{
int SaveImageSize = IMAGE_WIDTH*IMAGE_HEIGHT;
if(CheckBox2->Checked)
{
// 這部份牽涉實驗室一些東西,所以不能寫 XD
//不過也不重要 跟存檔無關 只是處理一些影像罷了
}
else
{
MbufClear(MilImage , 0L);
MdigHalt(MilDigitizer);
MbufCopy(MilImage, MilImage1);
}
SNumbers ;
switch(SaveDialog1->FilterIndex)
{
case 1://TIF
{
MbufExport(((SaveDialog1->FileName) ".tif").c_str(),M_TIFF,MilImage1);
break;
}
case 2://MIM
{
MbufExport(((SaveDialog1->FileName) ".mim").c_str(),M_MIL,MilImage1);
break;
}
case 3://BMP
{
MbufExport(((SaveDialog1->FileName) ".bmp").c_str(),M_BMP,MilImage1);
break;
}
case 4://RAW
{
MbufExport(((SaveDialog1->FileName) ".raw").c_str(),M_RAW,MilImage1);
break;
}
}
MdigGrabContinuous(MilDigitizer, MilImage);
MbufClear(MilImage1 , 0L);
}

[/code]
清除一次MilImage確保取得最新的圖片後暫停MilDigitizer這樣就有一張新圖
然後複製到MilImage1再吧MilImage1存起來
存檔類型說明書有寫...我用的版本不新,在當時存成連續高品質JPEG還需要外加擴充電路卡
存完後記得恢復暫停....

好了
既然單張都沒問題了
連續應該可以自己搞吧....
編輯記錄
hipig 重新編輯於 2008-01-25 10:31:43, 註解 無‧
hipig 重新編輯於 2008-01-25 10:35:20, 註解 無‧
hipig 重新編輯於 2008-01-25 10:41:55, 註解 無‧
hipig 重新編輯於 2008-01-25 10:44:21, 註解 無‧
hipig 重新編輯於 2008-01-25 10:45:57, 註解 無‧
hipig 重新編輯於 2008-01-25 10:49:19, 註解 無‧
kyoti
一般會員


發表:3
回覆:7
積分:2
註冊:2008-03-02

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-05-14 11:17:24 IP:122.116.xxx.xxx 訂閱
一般bcb+mil的方式來控制matrox的卡,
那我想請問一下,可以用一般的Camera來取相,再使用mil來做各種的處理嗎!?
fish730622
一般會員


發表:7
回覆:5
積分:2
註冊:2007-07-05

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-05-14 13:12:32 IP:210.240.xxx.xxx 訂閱
可以!他有一些影像處理的函式!不過你要自己去測試功能是幹麻的
t7511307
一般會員


發表:1
回覆:1
積分:0
註冊:2009-02-27

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-03-15 17:18:29 IP:140.122.xxx.xxx 訂閱
各位高手:
小弟目前也是用BCB6.0搭配Mil來做取像,最近也是因為取像問題所苦,
所以想請教各方好手,幫忙一下~
我先敘述一下我的規格!
1.影像擷取卡(Matrox):
Solios 6M-CL
2.攝影機(Pulnix Dual TAP):
TM-6740CL /解析度:640*480 /frame rate 200fps
3.程式:
MIL-LITE 8.0
4.目前需求:直接在Form上面開兩個取像畫面(因為有兩台camera),
分別拉出"開始取像","停止取像"的Button.

我研究過站上這篇文章:
如何利用MATROX與BCB做結合擷取影像,
但不知為何沒有影像?我想是不是他們都是用MIL 7.5以下的版本的原因,
我現在是用廠商附的MIL 8.0版,
剛好看到Hi大有這一方面的專業見解,只是不知道,有哪個地方要修改的?
新手入門,所以請多包含~
以上是我想請教的相關問題,謝謝各位!

------
海闊天空~
系統時間:2024-11-25 16:45:08
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!