|
![]() |
|
Registriert seit: 2. Feb 2009 Ort: Varel 70 Beiträge RAD-Studio 2009 Pro |
#1
Theoretisch hätte mir das wohl klar sein sollen; aber praktisch...
Ich hab zumindest über das Wocheende ein wenig weiter dran gearbeitet und komme inzwischen auch an diverse Attribute der Kamera heran. Ich kann die Kamera inzwischen auch sauber öffnen. Allerdings bekomme ich dabei den PermittedAccess Status 6 zurückgeliefert. Laut SDK Unterlagen sollen aber nur die Statuswerte 2 und 4 (und nicht deren addierte Bitsumme) valide sein. Was könnte das denn wohl bedeuten? Ich glaube, daß ich schon ein großes Stück weiter bin. Habe mir aus diversen C-Samples jetzt etwas zusammengebastelt. Das muss alles noch in einzelne Procs/Funcs ausgelagert werden, aber für eine Version zum Debuggen ist es ganz praktisch. Derzeit hängt es aber an der Struktur des pFrame (?). Ich versuche das so ähnlich zu machen wie in den C-Samples und im Quellcode, den horst0815 gepostet hat. aber hier stimt irgendwas noch nicht. Ich komme derzeit an kein Bild. Der PvCaptureQueueFrame wirft eine Exception, die ich nicht richtig verfolgt bekomme. Ich habe derzeit die Header-Datei folgendermassen übersetzt (Ausschnitte):
Delphi-Quellcode:
Auf der anderen seite steckt erst einmal alles in einem ButtonClick:
tPvImageFormat =
(ePvFmtMono8 = 0, // Monochrome, 8 bits ePvFmtMono16 = 1, // Monochrome, 16 bits, data is LSB aligned ePvFmtBayer8 = 2, // Bayer-color, 8 bits ePvFmtBayer16 = 3, // Bayer-color, 16 bits, data is LSB aligned ePvFmtRgb24 = 4, // RGB, 8 bits x 3 ePvFmtRgb48 = 5, // RGB, 16 bits x 3, data is LSB aligned ePvFmtYuv411 = 6, // YUV 411 ePvFmtYuv422 = 7, // YUV 422 ePvFmtYuv444 = 8, // YUV 444 ePvFmtBgr24 = 9, // BGR, 8 bits x 3 ePvFmtRgba32 = 10, // RGBA, 8 bits x 4 ePvFmtBgra32 = 11, // BGRA, 8 bits x 4 ePvFmtMono12Packed = 12, // Monochrome, 12 bits, ePvFmtBayer12Packed = 13, // Bayer-color, 12 bits, packed __ePvFmt_force_32 = $FFFFFFFF ); // // Bayer pattern. Applicable when a Bayer-color camera is sending raw bayer // data. // tPvBayerPattern = (ePvBayerRGGB = 0, // First line RGRG, second line GBGB... ePvBayerGBRG = 1, // First line GBGB, second line RGRG... ePvBayerGRBG = 2, // First line GRGR, second line BGBG... ePvBayerBGGR = 3, // First line BGBG, second line GRGR... __ePvBayer_force_32 = $FFFFFFFF ); tPvFrame = Packed Record //----- In ----- ImageBuffer : Pointer; // Buffer for image/pixel data. ImageBufferSize : Cardinal; // Size of ImageBuffer in bytes AncillaryBuffer : Pointer; // Camera Firmware >= 1.42 Only. // Buffer to capture ancillary chunk mode data. See ChunkModeActive attr. // This MUST be 0 if not in use. // Chunk mode format: // [Bytes 1 - 4] acquisition count. // [Bytes 5 - 8] user value. Not currently implemented. 0. // [Bytes 9 - 12] exposure value. // [Bytes 13 - 16] gain value. // [Bytes 17 - 18] sync in levels. // [Bytes 19 - 20] sync out levels. // [Bytes 21 - 40] not implemented. 0. // [Bytes 41 - 44] chunk ID. 1000. // [Bytes 45 - 48] chunk length. AncillaryBufferSize : Cardinal; // Size of your ancillary buffer in bytes. See NonImagePayloadSize attr. // Set to 0 for no buffer. Context : Array [0..3] of Pointer; // For your use. Possible application: unique ID // of tPvFrame for frame-done callback. _reserved1 : Array [0..7] of Cardinal; //----- Out ----- Status : tPvErr; // Status of this frame ImageSize : Cardinal; // Image size, in bytes AncillarySize : Cardinal; // Ancillary data size, in bytes Width : Cardinal; // Image width Height : Cardinal; // Image height RegionX : Cardinal; // Start of readout region (left) RegionY : Cardinal; // Start of readout region (top) Format : tPvImageFormat; // Image format BitDepth : Cardinal; // Number of significant bits BayerPattern : tPvBayerPattern; // Bayer pattern, if bayer format FrameCount : Cardinal; // Frame counter. Uses 16bit GigEVision BlockID. Rolls at 65535. TimestampLo : Cardinal; // Time stamp, lower 32-bits TimestampHi : Cardinal; // Time stamp, upper 32-bits _reserved2 : Array [0..31] of Cardinal; end; tPvCameraInfoExList = array of tPvCameraInfoEx; pPvCameraInfoExList = ^tPvCameraInfoExList; tConnectedCams = Cardinal; pConnectedCams = ^tConnectedCams; pPvFrame = ^tPvFrame; Const PVINFINITE = $FFFFFFFF; // Never timeout //------------------------------------------------------------------------------------- // define DLL-calls: Function PvAttrEnumSet (pCamera: tPvHandle; Name: PAnsiChar; Value: PAnsiChar): tPvErr; stdcall; external 'PvAPI.dll'; Function PvAttrUint32Get (pCamera: tPvHandle; Name: PAnsiChar; Out pValue: Cardinal) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvCameraListEx (pList: pPvCameraInfoExList; ListLength : Cardinal; Out ConnectedNum : tConnectedCams; Size : Cardinal) : Cardinal; stdcall; external 'PvAPI.dll'; Function PvCameraClose (pCamera: tPvHandle) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvCameraOpen (UniqueID: Cardinal; AccessFlag: tPvAccessFlags; Out pCamera: tPvHandle) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvCaptureStart (pCamera: tPvHandle) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvCaptureQueueFrame (pCamera: tPvHandle; pFrame: pPvFrame; FrameCallBack: Pointer ): tPvErr; stdcall; external 'PvAPI.dll'; Function PvCaptureWaitForFrameDone (pCamera: tPvHandle; pFrame: pPvFrame; Timeout: Cardinal): tPvErr; stdcall; external 'PvAPI.dll'; Function PvCommandRun (pCamera: tPvHandle; Name : PAnsiChar): tPvErr; stdcall; external 'PvAPI.dll'; Function PvInitialize : tPvErr; stdcall; external 'PvAPI.dll'; Function PvInitializeNoDiscovery : tPvErr; stdcall; external 'PvAPI.dll'; Procedure PvUnInitialize; stdcall; external 'PvAPI.dll'; Procedure PvVersion (Var Major, Minor: Cardinal); stdcall; external 'PvAPI.dll';
Delphi-Quellcode:
Soweit ich es der SDK-Doku entnehme sollte so eine Aufrufreihenfolge zum Erfolg führen. Aber momentan ist dem noch nicht so...
procedure TForm1.Button6Click(Sender: TObject);
Var aFrame : tPvFrame; aFrameBuffer : Array of Byte; aBitMap : tBitmap; aErrValue : tPvErr; Begin aErrValue := PvAttrUint32Get (CamHandle, 'TotalBytesPerFrame', aFrame.ImageBufferSize); If aErrValue = ePvErrSuccess then Begin SetLength (aFrameBuffer, aFrame.ImageBufferSize); aFrame.ImageBuffer := @aFrameBuffer[0]; end Else Begin Exit; end; aErrValue := PvCaptureStart (CamHandle); If aErrValue = ePvErrSuccess THen Begin aErrValue := PvAttrEnumSet (CamHandle, 'FrameStartTriggerMode', 'Freerun'); If aErrValue = ePvErrSuccess Then Begin aErrValue := PvCommandRun (CamHandle, 'AcquisitionStart'); If aErrValue = ePvErrSuccess Then Begin aErrValue := PvCaptureQueueFrame (CamHandle, @aFrame, 0) ; If aErrValue = ePvErrSuccess Then Begin aErrValue := PvCaptureWaitForFrameDone (CamHandle, @aFrame, PVINFINITE); If aErrValue = ePvErrSuccess Then Begin // CreateDIBitmap (@aBitmap,...?????) Beep;Beep;Beep; end; end; end; end; end; end; Jan PS: Was sind denn wohl erfahrungsgemäß gute Werte für ein TimeOut der Kamera im Debugmodus? |
![]() |
Registriert seit: 2. Feb 2009 Ort: Varel 70 Beiträge RAD-Studio 2009 Pro |
#2
Update...
ich bin inzwischen so weit, daß ich ein einzelnes Frame (theoretisch) per DLL einfangen kann. Hier scheint im Debug der Timeout ein Problem gewesen zu sein und schlechte Lötstellen von einem nicht spezifiziertes Unterwasser-Kabel. Nachdem ich diese erstmal ausgetauscht habe, habe ich auch keine 'Camera was unplugged' mehr. Das Kommando PvCaptureWaitForFrameDone liefert nun ein Success zurück. Leider hat der entsprechend zurückgelieferte Frame keine Daten und das Status sagt, daß einige Daten verloren gingen (Error Code 16). Das ist charmant untertrieben, da Image Size 0 besagt. Die anderen Werte (die mir logisch nachvollziehbar erscheinen, wie FrameCount, FrameWidth, und FrameHeight) scheinen korrekt zu sein. Mit der BitDepth von 8 bin ich mir nicht sicher; das ist doch garantiert nicht pro RGB Kanal gemeint? Auch ist mir noch nicht ganz klar, wie ich die Daten aus dem Pointer mit den anderen Infos zu einem korrekten Bitmap zusammenstelle, welches ich dann speichern und darstellen kann. Ich versuche es in der DLL Anbindung jetzt so:
Delphi-Quellcode:
Function PvAttrBooleanGet (pCamera: tPvHandle; Name: PAnsiChar; Out pValue: Boolean) : tPvErr; stdcall; external 'PvAPI.dll';
Function PvAttrBooleanSet (pCamera: tPvHandle; Name: PAnsiChar; pValue: Boolean) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvAttrEnumGet (pCamera: tPvHandle; Name: PAnsiChar; Out pBuffer : PAnsiChar; BufferSize: Cardinal; Out pSize: Cardinal): tPvErr; stdcall; external 'PvAPI.dll'; Function PvAttrEnumSet (pCamera: tPvHandle; Name: PAnsiChar; Value: PAnsiChar): tPvErr; stdcall; external 'PvAPI.dll'; //geht noch nicht:// Function PvAttrUint32Get (pCamera: tPvHandle; Name: PAnsiChar; Out pValue: Cardinal) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvCameraListEx (pList: pPvCameraInfoExList; ListLength : Cardinal; Out ConnectedNum : tConnectedCams; Size : Cardinal) : Cardinal; stdcall; external 'PvAPI.dll'; Function PvCameraClose (pCamera: tPvHandle) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvCameraCount : Cardinal; stdcall; external 'PvAPI.dll'; Function PvCameraOpen (UniqueID: Cardinal; AccessFlag: tPvAccessFlags; Out pCamera: tPvHandle) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvCaptureEnd (pCamera: tPvHandle) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvCaptureStart (pCamera: tPvHandle) : tPvErr; stdcall; external 'PvAPI.dll'; Function PvCaptureQueueFrame (pCamera: tPvHandle; pFrame: pPvFrame; FrameCallBack: Pointer ): tPvErr; stdcall; external 'PvAPI.dll'; Function PvCaptureWaitForFrameDone (pCamera: tPvHandle; pFrame: pPvFrame; Timeout: Cardinal): tPvErr; stdcall; external 'PvAPI.dll'; Function PvCommandRun (pCamera: tPvHandle; Name : PAnsiChar): tPvErr; stdcall; external 'PvAPI.dll'; Function PvInitialize : tPvErr; stdcall; external 'PvAPI.dll'; Function PvInitializeNoDiscovery : tPvErr; stdcall; external 'PvAPI.dll'; Procedure PvUnInitialize; stdcall; external 'PvAPI.dll'; Procedure PvVersion (Var Major, Minor: Cardinal); stdcall; external 'PvAPI.dll'; implementation Function PvReturnErrorString (aErrCode: tPvErr) : String; Begin Case aErrCode of ePvErrSuccess : Result := 'Code 0000: No error'; ePvErrCameraFault : Result := 'Code 0001: Unexpected camera fault'; ePvErrInternalFault : Result := 'Code 0002: Unexpected fault in PvApi or driver'; ePvErrBadHandle : Result := 'Code 0003: Camera handle is invalid'; ePvErrBadParameter : Result := 'Code 0004: Bad parameter to API call'; ePvErrBadSequence : Result := 'Code 0005: Sequence of API calls is incorrect'; ePvErrNotFound : Result := 'Code 0006: Camera or attribute not found'; ePvErrAccessDenied : Result := 'Code 0007: Camera cannot be opened in the specified mode'; ePvErrUnplugged : Result := 'Code 0008: Camera was unplugged'; ePvErrInvalidSetup : Result := 'Code 0009: Setup is invalid (an attribute is invalid)'; ePvErrResources : Result := 'Code 0010: System/network resources or memory not available'; ePvErrBandwidth : Result := 'Code 0011: 1394 bandwidth not available'; ePvErrQueueFull : Result := 'Code 0012: Too many frames on queue'; ePvErrBufferTooSmall : Result := 'Code 0013: Frame buffer is too small'; ePvErrCancelled : Result := 'Code 0014: Frame cancelled by user'; ePvErrDataLost : Result := 'Code 0015: The data for the frame was lost'; ePvErrDataMissing : Result := 'Code 0016: Some data in the frame is missing'; ePvErrTimeout : Result := 'Code 0017: Timeout during wait'; ePvErrOutOfRange : Result := 'Code 0018: Attribute value is out of the expected range'; ePvErrWrongType : Result := 'Code 0019: Attribute is not this type (wrong access function)'; ePvErrForbidden : Result := 'Code 0020: Attribute write forbidden at this time'; ePvErrUnavailable : Result := 'Code 0021: Attribute is not available at this time'; ePvErrFirewall : Result := 'Code 0022: A firewall is blocking the traffic (Windows only)'; __ePvErr_force_32 : Result := 'Code $FFFFFFFF: Codon forcing Error codes to be 32bit'; end; end; Und im eigentlichen Programm rufe ich die Funktionen wie nachfolgend auf. Es ist vorläufig eine Testversion, die auf jeden Fall dringender Überarbeitung bedarf. Wenn das ganze mal Bilder liefert denke ich, daß die komplette Unit mit Beispiel hier Veröffentlichung finden sollte. Dafür das in der FeatureMatrix des Herstellers die Delphi-Option gelistet ist, finde ich die reale Umsetzung für ein SDK doch etwas unumgänglich:
Delphi-Quellcode:
Liebe Grüße aus dem Norden
procedure TForm1.Button6Click(Sender: TObject);
Var aFrame : tPvFrame; aFrameBuffer : Array of Byte; aBitMap : tBitmap; aErrValue : tPvErr; aString : PAnsiChar; aValue : Cardinal; bmp_BMI : BITMAPINFO; bmp_Bitmap : tBitmap; Begin aErrValue := PvAttrUint32Get (CamHandle, 'TotalBytesPerFrame', aFrame.ImageBufferSize); If aErrValue = ePvErrSuccess then Begin SetLength (aFrameBuffer, aFrame.ImageBufferSize); aFrame.ImageBuffer := @aFrameBuffer[0]; end Else Begin Exit; end; aErrValue := PvCaptureStart (CamHandle); If aErrValue = ePvErrSuccess THen Begin aErrValue := PvAttrEnumSet (CamHandle, 'FrameStartTriggerMode', 'Freerun'); Memo1.Lines.Add ('Set FrameStartTriggerMode : ' + PvReturnErrorString (aErrValue)); If aErrValue = ePvErrSuccess Then Begin // SetLength (aString, 20); aErrValue := PvAttrEnumGet (CamHandle, 'FrameStartTriggerMode', aString, SizeOf (aString[0]), aValue); Memo1.Lines.Add ('Get FrameStartTriggerMode : ' + PvReturnErrorString (aErrValue)+ ' ; String:' + aString + ';(' + IntToStr (aValue) + ')'); aErrValue := PvCommandRun (CamHandle, 'AcquisitionStart'); Memo1.Lines.Add ('CommandRun AcquisitionStart : ' + PvReturnErrorString (aErrValue)); If aErrValue = ePvErrSuccess Then Begin aErrValue := PvCaptureQueueFrame (CamHandle, @aFrame, 0) ; Memo1.Lines.Add ('CaptureQueueFrame : ' + PvReturnErrorString (aErrValue)); If aErrValue = ePvErrSuccess Then Begin aErrValue := PvCaptureWaitForFrameDone (CamHandle, @aFrame, PVINFINITE); Memo1.Lines.Add ('Capture Wait For Frame Done : ' + PvReturnErrorString (aErrValue)); If aErrValue = ePvErrSuccess Then Begin Memo1.Lines.Add ('Frame count : ' + IntToStr (aFrame.FrameCount)); Memo1.Lines.Add ('Bit depth : ' + IntToStr (aFrame.BitDepth)); Memo1.Lines.Add ('Frame width : ' + IntToStr (aFrame.Width)); Memo1.Lines.Add ('Frame height : ' + IntToStr (aFrame.Height)); Memo1.Lines.Add ('Image size : ' + IntToStr (aFrame.ImageSize)); Memo1.Lines.Add ('Frame status : ' + PvReturnErrorString (aFrame.Status)); bmp_BMI.bmiHeader.biSize := SizeOf (bmp_BMI.bmiHeader); bmp_BMI.bmiHeader.biWidth := aFrame.Width; bmp_BMI.bmiHeader.biHeight := aFrame.Height; bmp_BMI.bmiHeader.biPlanes := 1; bmp_BMI.bmiHeader.biBitCount := aFrame.BitDepth; bmp_BMI.bmiHeader.biCompression := BI_RGB; bmp_BMI.bmiHeader.biSizeImage := 0; bmp_BMI.bmiHeader.biXPelsPerMeter := 0; bmp_BMI.bmiHeader.biYPelsPerMeter := 0; bmp_BMI.bmiHeader.biClrUsed := 0; bmp_BMI.bmiHeader.biClrImportant := 0; // CreateDIBitmap (@aBitmap,...?????) //createDIBSection // image1.Picture.Bitmap.Handle end; aErrValue := PvCaptureEnd (CamHandle); Memo1.Lines.Add ('Capture end : ' + PvReturnErrorString (aErrValue)); end; end; end; end; end; Jan |
![]() |
Registriert seit: 30. Jan 2004 823 Beiträge |
#3
Du solltest den Buffer mal clearen.
Delphi-Quellcode:
Den Mode kann man vorher einstellen (8bit gray, 16bitgray, rgb, etc.).
ZeroMemory(@aFrame, SizeOf(aFrame);
aErrValue := PvAttrUint32Get (CamHandle, 'TotalBytesPerFrame', totalbytes); If aErrValue = ePvErrSuccess then Begin SetLength (aFrameBuffer, totalbytes); aFrame.ImageBufferSize := totalbytes; aFrame.ImageBuffer := @aFrameBuffer[0]; end; Du musst dir dann ein Bitmap erstellen und die Pixel z.B. mit SetBitmapBits setzen. Als alternative zum Testen gehts auch erstmal mit nem Bitmap und Scanline. Geändert von brechi (17. Jul 2012 um 21:58 Uhr) |
![]() |
Registriert seit: 2. Feb 2009 Ort: Varel 70 Beiträge RAD-Studio 2009 Pro |
#4
Leider nicht...
Ich hab das Memory Blanking jetzt an der hier geposteten Selle und an einer anderen (nicht geposteten) eingebaut. Das Ergebnis ist aber immer noch dasselbe. Es kommt immer ein tPvFrame.Status = 16, 'Some data in frame missing'. Jan |
![]() |
Registriert seit: 2. Feb 2009 Ort: Varel 70 Beiträge RAD-Studio 2009 Pro |
#5
Ich habe spaßeshalber mal eine andere Kamera angeschlossen (Prosilica GE2040 monochrom) und dabei ist mir etwas aufgefallen. Wenn das Bildformat der Kamera auf Mono8 gestellt ist, dann erhalte ich plötzlich auch Daten im FrameBuffer (nach PvCaptureWaitForFrameDone), der bisher immer nur mit 0 gefüllt blieb.
Stelle ich die Farbkamera (GC2450C) mit dem Prosilica Herstellertool von Bayer8 ebenfalls auf 8bit monochrom (Mono8) um, dann bekomme ich auch hier plötzlich Daten in meinen Buffer geschrieben (zumindest unterscheiden sich nach jetzigem Erkenntnisstand die Werte von 0). Das kann es zwar auf Dauer nicht sein, ich möchte ja auch gerne die Farben, aber es ist wenigstens mal wieder ein kleiner Fortschritt. Bei beiden Varianten habe ich aber immer wieder den Fall, daß einige Frames ausfallen mit der Fehlermeldung, daß einige Daten fehlen (Error Code 16). Ich habe mir inzwischen aus dem MSDN Informationen zusammengesucht um aus einem Speicherbereich ein Bitmap zu erzeugen, welches ich erst einmal auf dem Bildschirm mit einer TImage Komponente darstellen wollte. Für Stream und Dateien gibt es ja genug Beispiele. Für diesen Fall sind die Samples aber eer schmal gestreut und erschienen nicht anwendbar/funktional. Derzeit scheinen die Bilddaten allerdings trotzdem irgenwo hängen zu bleiben. Auch ist noch nicht klar, wie die Palette des Bildes korrekt auszuformulieren ist. Ich versuche derzeit (bislang ja nur Graustufen) eine Palette manuell einzubauen. Werden bmiColors einfach ignoriert, wenn entsprechende RGB Werte vorliegen? Dies muss ja sicherlich anders im Header deklariert werden. Oder gibt es hier evtl. noch andere Faktoren die ich bislang nicht gefunden habe?
Delphi-Quellcode:
Var aFrame : tPvFrame;
aFrameBuffer : Array of Byte; aBitMap : tBitmap; aErrValue : tPvErr; aString : PAnsiChar; aValue : Cardinal; bmpInfo : ^BITMAPINFO; totalbytes : Cardinal; aChar : Char; dc : HDC; hBmp : HBITMAP; cp : PRGBQUAD; j : Cardinal; GetMem(bmpInfo, sizeof(bmpInfo.bmiHeader) + sizeof(RGBQUAD) * Trunc(Power (2, aFrame.BitDepth))); bmpInfo^.bmiHeader.biSize := SizeOf (bmpInfo.bmiHeader); bmpInfo^.bmiHeader.biWidth := aFrame.Width; bmpInfo^.bmiHeader.biHeight := aFrame.Height; bmpInfo^.bmiHeader.biPlanes := 1; bmpInfo^.bmiHeader.biBitCount := aFrame.BitDepth; bmpInfo^.bmiHeader.biCompression := BI_RGB; bmpInfo^.bmiHeader.biSizeImage := 0; bmpInfo^.bmiHeader.biXPelsPerMeter := 0; bmpInfo^.bmiHeader.biYPelsPerMeter := 0; bmpInfo^.bmiHeader.biClrUsed := 0; bmpInfo^.bmiHeader.biClrImportant := 0; for j := 0 to Trunc (Power (2, aFrame.BitDepth)) - 1 do begin bmpInfo^.bmiColors[j].rgbBlue := j; bmpInfo^.bmiColors[j].rgbGreen := j; bmpInfo^.bmiColors[j].rgbRed := j; bmpInfo^.bmiColors[j].rgbReserved := 0; end; dc := CreateDC('DISPLAY', nil, nil, nil); hBmp := CreateDIBSection(dc, bmpInfo^, DIB_RGB_COLORS, aFrame.ImageBuffer, 0, 0); // hBmp := CreateDIBitmap(dc, bmpInfo^, DIB_RGB_COLORS, aFrame.ImageBuffer, 0, 0); DeleteDC(dc); FreeMem(bmpInfo, sizeof(bmpInfo.bmiHeader) + sizeof(RGBQUAD) * Trunc(Power (2, aFrame.BitDepth))); aBitmap := TBitmap.Create; aBitmap.Handle := hBmp; Image1.Picture.Bitmap := aBitmap; Ganz herzlichen Dank an alle, die Hilfe beigesteuert haben Jan |
![]() |
Registriert seit: 2. Feb 2009 Ort: Varel 70 Beiträge RAD-Studio 2009 Pro |
#6
Ich glaub ich mach an dieser Stelle mal einen Reset. Es sind in meinen letzten Beiträgen ein wenig zu viele Punkte parallel angesprochen gewesen. Deshalb jetzt mal die Konzentration auf die derzeit kritischsten Probleme; zumindest so wie sie mir erscheinen:
1.) Der gleiche, vorher gepostete Code funktioniert derzeit für eine ältere, rein monochrome Kamera (Prosilica GE2040). Ich versuche dabei das Bild über PvCaptureWaitForFrameDone aufzunehmen. Eine Callback-Funktion habe ich derzeit noch nicht implemetiert. Für die alte Kamera klappt dies und der Datenrecord weist die korrekte Anzahl an Bytes aus. Mit der Farbkamera (Prosilica GC2450C) funktioniert dies nicht. Es kommt immer die Rückmeldung, daß Daten fehlen. Hier habe ich auch mit anderen Aufnahmemodi und Veränderungen der TimeOuts keine Erfolge erzielt. Ich vermute inzwischen fast, daß diese die Farbkamera noch andere Parameter gesetzt benötigt. Kann dies sein; und wenn ja welche? 2.) Mit der (leider geborgten und demnächst rückgabefälligen) Monochrom-Kamera (GE2040) bekomme ich ja tatsächlich ein Bild. Allerdings bin ich hier nicht in der Lage ein DIB zu erstellen. Alle Versuche führen derzeit zu einer einfarbigen Fläche. Natürlich kann ich mit:
Delphi-Quellcode:
die Daten in ein Bitmap kopieren. Allerdings ist dies relativ langsam (auch mit Scanline) und ich vermute, es hat durchaus seine Berechtigung, daß in den meisten Fällen auf HBITMAP und CreateDIB/StretchDIB verwiesen wird. Als Langzeitziel würde ich (zur Überprüfung einer Idee) gerne auf 5-6 Bilder die Sekunde kommen.
aBitmap := TBitmap.Create;
aBitmap.PixelFormat := pf8Bit; aBitmap.Height := aFrame.Height; aBitmap.Width := aFrame.Width; For y := 0 to aFrame.Height - 1 do Begin // lPixel := aBitmap.Scanline[y]; For x := 0 to aFrame.Width - 1 do Begin idx := aFrameBuffer [y*aFrame.Width + x]; aBitmap.Canvas.Pixels[x, y] := idx + idx shl 8 + idx Shl 16; end; end; Ich scheine derzeit aber aus den mir vorliegenden Informationen persönlich nicht in der Lage zu sein, eine vernünftige Bitmap hinzubekommen. Mir erscheint es so, daß die Daten nicht richtig zusammengesammelt werden. Das Ergebnis ist immer eine einfarbige Fläche. 3.) Als Fortführung: Gibt es eine allgemeine Form, wie man mit dem Hintergrundwissen (Mono8, Bayer8, Bayer16, ...; BayerPattern; Bytes pro Frame) eine universelle Routine gestaltet, die ein darstellbares/speicherfähiges Bild erzeugt? Ich habe diesbezüglich schon viel ergoogelt, allerdings persönlich noch keine Implementation geschafft, die aus einem Pointer auf ein Array of Byte eine funktionale Lösung erzeugt (wobei die Daten dann ja noch abhängig vom Pixel-Format sein können. Ich werde am Wochenende versuchen der Funktion PvCaptureQueueFrame eine Callback-Funktion zu verpassen. Laut SDK-Dokumentation würde diese Funktion dann in einem eigenen Thread ausgeführt, NACHDEM das Bild fertig aquiriert ist. Damit würde dann die bisher eingesetzte Funktion PvCaptureWaitForFrameDone obsolet werden. Vielleicht liegt hier auch ein Teil der Problematik. Bis dahin würde ich es großartig finden, wenn mir jemand ein wenig auf die Sprünge helfen könnte... Wie gesagt, ich würde die Routinen (wenn sie funktionieren) auch durchaus zur Verfügung stellen. Wenn man die Suchmaschinen bemüht stellt man schnell fest, daß es mehr Leute gibt die diese (durchaus guten) Kameras unter Delphi zum Laufen bekommen wollen... Liebe Grüße aus dem Norden Jan |
![]() |
Registriert seit: 30. Jan 2004 823 Beiträge |
#7
Zu 1.) Leider kenn ich mich mit dieser Api nicht aus, aber eventuell musst di bei einer Farbkamera mehr speicher reservieren. Hast du denn mal ausgerechnet ob die Größe die du reservierst stimmt? Also bei 8Bit waeren das Breite*Hoehe, bei 16 (YUV) Breite*Hoehe*2 bei RGB Breite*Hoehe*3.
zu 2.) Es kommt ganz darauf an was du spaeter mit den Daten machen willst. Wenn du diese dann sowieso komprimierst (z.b. JPEG) dann lohnt sich da z.B: LibJpegTurbo zu verwenden, dafür brauchst du noch nicht einmal ein Bitmap und z.B. fuer OpenCV glaub ich auch. Ansonsten ist Scanline schnell genug und auch nicht wirklich langsamer als es direkt ueber die API zu machen. Wichtig ist hier, dass du EINMAL das Bitmap erstellst und die Groesse + Pixelformat setzt und NICHT fuer jedes Bild. (Das gilt auch fuer den Speicher den du fuer das Bild reservierst). Hier Beispiel fuer 8Bit:
Delphi-Quellcode:
zu 3.
// on Create
FBmp := TBitmap.Create; FBmp.Width := 640; // Einstellungen der kamera FBmp.Height := 480; FBmp.PixelFormat := pf8Bit; // on destroy FreeAndNil(FBmp) // Pro bild var y: integer; begin pmem := // dein datenpointer for y := 0 to FBmp.Height-1 do CopyMemory(FBmp.Scanline[y], Pointer(Integer(pmem) + FBmp.width * y), Fbmp.height); Form1.Canvas.Draw(0,0,FBmp); Die UniversalAPI bietet dir z.B. Moeglichkeiten ein Bild immer in RGB auszulesen, egal welche Einstellung die Kamera hat. In den Manuals von AVT steht vieles beschrieben (z.B. Debayering etc) Geändert von brechi (19. Jul 2012 um 23:09 Uhr) |
![]() |
Registriert seit: 2. Feb 2009 Ort: Varel 70 Beiträge RAD-Studio 2009 Pro |
#8
Hallo Brechi!
Ich hab nach deinem Posting gestern Nacht dann doch noch mal beim kanadischen (?; zumindest englischsprachiger Raum) Hersteller-Support nachgefragt. Wollte mir dein Paket mal anschauen. Heut Morgen hab ich dann auch eine Kopie der UniAPI erhalten. Macht auf jeden Fall einen deutlich ausgereifteren/umfangreicheren Eindruck als die reine PvAPI. Da ich selbst nach einem Kamera-Firmwareupdate keine großen Verbesserungen hatte, wollte ich es jetzt mal damit versuchen. Hab mich nun eine Weile hingesetzt und lese mich in die Header und Beispiele ein. Ehrlich gesagt hats mich dann einen Moment geerdet. Die Headerfiles ergehen sich ja geradezu in Typdeklarationen. Hat mich einen Moment gekostet, um zu sehen, daß es in erster Linie wohl um Plattformkompatibilität geht. Die meisten Typen kann man scheinbar gut auf Standards rückführen... Kann es sein, daß die Kameras nur über ihr Handle identifiziert werden? Bislang hab ich noch keine entsprechende Kamera-Liste entdeckt, wie bei der PvAPI. Einige Funktionen hab ich schon importiert und die Typen aus den endlosen Querreferenzen auf Standards zurückgeführt. Muss jetzt nur bei dem InfoString noch mal bei.
Delphi-Quellcode:
Offensichtlich bewege ich mich schon mal in die Nähe der Kamera. Aber da geht es Morgen weiter. Den Kindern gehts grad nicht so gut; sind kurze Nächte...
Function UCC_Init: Int64; stdcall; external 'UniControl.DLL';
Function UCC_Release: Int64; stdcall; external 'UniControl.DLL'; Function UCC_GetCameras ( Var pnSize : UInt32; Out vecIds : UInt32) : Int64; stdcall; external 'UniControl.DLL'; Function UCC_OpenCamera (CamId : UInt32; lSpeedLimit : Int32) : Int64; stdcall; external 'UniControl.DLL'; Function UCC_CloseCamera (CamId : UInt32) : Int64; stdcall; external 'UniControl.DLL'; Function UCC_GetCameraInfoString (CamId : UInt32; nId : UInt32; Out pszInfoString : PAnsiChar; Var pLength : UInt32) : Int64; stdcall; external 'UniControl.DLL';
Delphi-Quellcode:
Werde dies Wochenende sicherlich noch mal auf dich zurückkommen. Ich hab schon ein paar Funktionen des UniAPI entdeckt, die sich vielversprechend anhören, aber einige Fallstricke bieten könnten.procedure TForm1.Button1Click(Sender: TObject); Var CamID : Uint32; aCount : Uint32; aVendor : PAnsiChar; aModel : PAnsiChar; aModelLength : Uint32; begin aCount := 64; aVendor := ' '; aModel := ' '; Memo1.Lines.Add ('Initialise : ' + IntToStr(UCC_Init)); Memo1.Lines.Add (''); Memo1.Lines.Add ('Get cameras : ' + IntToStr (UCC_GetCameras (aCount, CamID))); Memo1.Lines.Add ('Camera counts : ' + IntToStr (aCount)); Memo1.Lines.Add ('CamID : ' + IntToStr (CamID)); Memo1.Lines.Add (''); Memo1.Lines.Add ('Camera open : ' + IntToStr (UCC_OpenCamera (CamID, -1))); aModelLength := SizeOf (aModel); UCC_GetCameraInfoString (CamID, 0, aModel, aModelLength); Memo1.Lines.Add ('Model : ' + aModel); Memo1.Lines.Add ('Camera close : ' + IntToStr (UCC_CloseCamera (CamID))); Memo1.Lines.Add ('Uninitialise : ' + IntToStr(UCC_Release)); Memo1.Lines.Add (''); end; Jan |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |