Kamera Auslesen, Fragen zu DIB
-
Ich habe eine Kamera die ich mit C++ auslesen möchte. Leider habe ich als Beispielcode für die DLL nur Delphi Code und stehe vor dem Rätsel wie man das nun in MFC unsemtzen könnte.
Da steht folgendes (delpi code, gekürzt):
pBuf : pointer; DibPixels : pchar; FrameBuf : TRgbPixArray; FrameP : PChar; Status := CxGetSnapshot(H, 1, True, True, True, FrameP, RAME_WIDTH*FRAME_HEIGHT, RetLen); pBuf := FrameP; DibPixels:=pBuf; SetDIBitsToDevice(DC, dx, dy, ScW, ScH, 0, 0, 0, ScH, DibPixels, TBitMapInfo((@FDib)^), DIB_RGB_COLORS);SetDIBitsToDevice gibts ja auch in Win32
aber wie setzte ich das ganze nun in MFC um?Konkret:
- wie muss ich ein Array anlegen so dass die Daten als DIB darin gespeichert werden können?
- gibt es eine andere/einfacherer Methode als SetDIBitsToDevice um dieses Array darzustellen?
- was sollte ich sonst noch beachten?Matthias
-
Mal anders gefragt, hast du überhaupt schon ein Bild der Cam in einem IVideoWindow oder überhaupt etc., den so wie ich das sehe, sind wohl gesonderte Delphidateien dazu zuständig und solang du die Cam noch nicht in einem FilterGraph mit SampleGrabber hast, oder eine CaptureCallback für VfW, bringt dir das da reichlich wenig.
-
orr lol schrieb:
Mal anders gefragt, hast du überhaupt schon ein Bild der Cam in einem IVideoWindow oder überhaupt etc., den so wie ich das sehe, sind wohl gesonderte Delphidateien dazu zuständig und solang du die Cam noch nicht in einem FilterGraph mit SampleGrabber hast, oder eine CaptureCallback für VfW, bringt dir das da reichlich wenig.
Ich verstehe nicht wirklich was du meinst.
Für die (Film)Kamera gibt es ein Programm mit dem ich die Bilder anschauen, die Einstellungen verändern und ein Video abspeichern kann.Um das ganze auch selber machen zu können gibt es eine dll mit einer Wrapperklasse die die DLL lädt und die Funktionen zur Verfügung stellt (Alles C++). CxGetSnapshot ist eine solche Funktion.
In Delphi6 und VB5 gibt es Beispielprojekte die diese DLL nutzen. Mein Problem ist nur eine äquivalente C++ Ansteuerung zu schreiben, und dabei genauer die Daten auf den Bildschirm zu bringen.
Matthias
-
das mit dem IVideoWindow kannst ignoriern
er redet von directshow und das benutzt du hier garnich und brauchst du auch nichnun zu deinem problem
prinzipiell gibt es imho nur eine SetDIBitsToDevice funktion, d.h. delphi ruft
die c funktion aufdu musst also eigentich nur den delphi code in c++ umschreiben
SetDIBitsToDevice funktioniert an sich so, dass du einen HDC von deinem fenster
brauchst auf das du zeichnen willst, dann gibst gibst du noch den bereich an
den du zeichnen willst. an der adresse von lpvBits müssen sich die bilddaten
befinden und dann musst du auch noch einen Bitmapinfoheader übergeben der das
format der bilddaten enthält.is an sich nich so schwer aber beim ersten mal n bissi hakelig.
-
Ich habe jetzt folgendes probiert und wüsste gerne ob das vom Ansatz her richtig ist. Inbesondere ist mir unklar ob BYTE die richtige Initialisierung für ein Array von DIB Daten ist.
BYTE* m_CameraFrameArray; CDlgCamera::CDlgCamera(CWnd* pParent /*=NULL*/) : CDialog(CDlgCamera::IDD, pParent) { m_camera.Initialize(); //loads Camera dll and does initialisation m_HandleCamera = m_camera.CxOpenDevice(0); // open camera and save device m_camera.CxGetScreenParams(m_HandleCamera, &m_CameraParameters); m_CameraSize.x=m_CameraParameters.Width; m_CameraSize.y=m_CameraParameters.Height; m_CameraFrameArray = new BYTE[m_CameraSize.x * m_CameraSize.y]; }int BufSize = m_CameraSize.x*m_CameraSize.y; int iTimeOut=1; bool boolTriggerEnabled = false; bool boolTriggerPosEnabled = false; DWORD *retlength; int result = m_camera.CxGetSnapshot(m_HandleCamera, iTimeOut, boolTriggerEnabled, boolTriggerPosEnabled, true, m_CameraFrameArray, BufSize, retlength); m_WndGraphCamera.SetDIB(m_CameraFrameArray);void CGraphCtrl::SetDIB(BYTE* DIBArray) { if ((PixelNumber.x>0) && (PixelNumber.y > 0)) { DIBDataEnabled = true; pDIBData = new BYTE[PixelNumber.x*PixelNumber.y]; memcpy(pDIBData, DIBArray, PixelNumber.x*PixelNumber.y*sizeof(BYTE)); } }void CGraphCtrl::OnPaint() { CPaintDC dc(this); // device context for painting if (PixelNumber.x == 0) return; if (DIBDataEnabled) { //First step: Create BITMAP Header info: BITMAPINFOHEADER bitmapInfo; ::ZeroMemory(&bitmapInfo,sizeof(BITMAPINFOHEADER)); bitmapInfo.biSize = sizeof(BITMAPINFOHEADER); bitmapInfo.biWidth = PixelNumber.x;/*enter Width*/ bitmapInfo.biHeight = PixelNumber.y;/*enter Height*/ bitmapInfo.biPlanes = 1; bitmapInfo.biBitCount = 32/*bit per pixel 24,32 */ ; //<-------LOOK HERE!!! bitmapInfo.biCompression = 0; //RGB bitmapInfo.biSizeImage = bitmapInfo.biWidth*bitmapInfo.biHeight*bitmapInfo.biBitCount/8; SetDIBitsToDevice(dc, 0, 0, bitmapInfo.biWidth, bitmapInfo.biHeight, 0, 0, 0, bitmapInfo.biHeight, pDIBData, (LPBITMAPINFO)&bitmapInfo, DIB_RGB_COLORS); DIBDataEnabled=false; return; } }In der jetzigen Form stürzt das Programm jedoch bei "CxGetSnapshot" ab.
Matthias
-
welches bildformat hat die kamera, was sagt die kamera doku?
in deinem code nimmst du ein graubild mit einem hpitch von einem byte und einem vpitch von m_CameraParameters.Width byte an.bist sicher, dass des stimmt?
BYTE is als datentyp ok denk ich... kannst aber auch gleich unsigned char* nehmen
was bedeuten die parameter von CxGetSnapshot?
-
Sovok schrieb:
welches bildformat hat die kamera, was sagt die kamera doku?
Das bekomme ich mit
m_camera.CxGetScreenParams(m_HandleCamera, &m_CameraParameters); m_CameraSize.x=m_CameraParameters.Width; m_CameraSize.y=m_CameraParameters.Height;Kann ich aber auch einstellen mit
m_camera.CxSetScreenParams(m_HandleCamera, &m_CameraParameters);Sovok schrieb:
in deinem code nimmst du ein graubild mit einem hpitch von einem byte und einem vpitch von m_CameraParameters.Width byte an.
Diese Daten sagen mir jetzt nichts. Ein Graybild ist es aber auf jeden Fall.
Sovok schrieb:
BYTE is als datentyp ok denk ich... kannst aber auch gleich unsigned char* nehmen
Ich hatte an 8 Bit gedacht. Dann vermute ich das unsigned char* auch 8 Bit breit ist.
Sovok schrieb:
was bedeuten die parameter von CxGetSnapshot?
Aus der Doku:
CxGetSnapshot
Grabs the hardware snapshot into the memory buffer.
Parameters:
DeviceHandle 32-bit integer value previously returned by CxOpenDevice function
Timeout 32-bit integer value, wait timeout period, sec
ExtTrgEnabled boolean, TRUE if wait external event
ExtTrgPositive boolean, TRUE if wait positive level else negative
SnapshotMode boolean, reserved, always True
pBuf pointer to the frame buffer that receives the data
BufSize 32-bit integer value specifying the buffer size, in bytes
pRetLen pointer to 32-bit unsigned integer receiving the return snapshot sizeReturn Value:
Nonzero if successfulRemarks:
This function requires to turn the video stream OFF.Matthias
-
es geht im prinzip darum, dass manche kameras z.b. ein 640x480 bild haben
aber z.b. 800x600 byte speicher für die bildaufnahme brauchenhpitch = horizontaler abstand zweier pixel im bild in bytes
vpitch = vertikaler abstand zweier zeilen im bild in bytesder absturz deutet drauf hin, dass über den speicherbereich rausgelaufen wird
kannst du noch posten welche exception auftritt?müsstest du im debugmodus im ausgabefenster sehn
ich tipp auf access violation