AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DLL Funktion(en) von openCV einbinden

Offene Frage von "alf.stefan"
Ein Thema von alf.stefan · begonnen am 17. Feb 2010 · letzter Beitrag vom 18. Feb 2010
Antwort Antwort
Seite 2 von 2     12   
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#11

Re: DLL Funktion(en) von openCV einbinden

  Alt 17. Feb 2010, 11:45
Hallo,

stimmt
Single ist ja 32 Bit.

Hast du den @line[] ersetzt ?

Ausserdem kannst du ja mal ein c++-Bsp. mit dem Fit posten,
vor allem die Vorbereitung.

Habe keine Lust, hier was zu installieren.


Heiko
Heiko
  Mit Zitat antworten Zitat
alf.stefan

Registriert seit: 11. Apr 2003
88 Beiträge
 
Delphi 7 Professional
 
#12

Re: DLL Funktion(en) von openCV einbinden

  Alt 17. Feb 2010, 15:08
here we are again!

war ein bisschen gegoogel bis ich ein c beispiel fand! allerdings mit einigermaßen unleserlichen komentaren (zumindest für den dem japanisch nicht mächtigen)

Delphi-Quellcode:
#include <cv.h>
#include <stdio.h>
#include <math.h>
float myLinearity(CvSeq *);
int main(void)
{
int i;
double fx[] = {0.0, 0.301, 0.477, 0.602, 0.699, 0.778, 0.845, 0.903, 0.954, 1.0}
;
double fy[] = {3.874, 3.202, 2.781, 2.49, 2.274, 2.156, 1.934, 1.74, 1.653, 1.662};
float *line = new float[4];
float linearity=0.0f;
//入れ物の確保
CvMemStorage* storage = cvCreateMemStorage(0);
//3次元の場合はCV_32FC2がCV_32FC3に、CvPoint2D32fがCvPoint3D32fになる
CvSeq* point_seq = cvCreateSeq( CV_32FC2, sizeof(CvSeq), sizeof(CvPoint2D32f), storage );
for (i=0; i<10; i++){
//値の追加はcvSeqPush
cvSeqPush(point_seq, &cvPoint2D32f(fx,fy));
}

linearity = myLinearity(point_seq);
cvFitLine(point_seq,CV_DIST_L2,0,0.01,0.01,line);
fprintf(stdout,"v=(%f,%f),vy/vx=%f,(x,y)=(%f,%f), Linearity=%f\n",line[0],line[1],line[1]/line[0],line[2],line[3],linearity);
cvClearSeq(point_seq);
cvReleaseMemStorage(&storage);
return 0;
}
//大津の直線度
float myLinearity(CvSeq *seq)
{
int i;
CvPoint2D32f *p;
float *x = new float[seq->total];
float *y = new float[seq->total];
float x_bar=0.0, y_bar=0.0;
float u11=0.0, u20=0.0, u02=0.0;
float linearity=0.0;
//吸い出し cvGetSeqElemでポインタを得るのでキャストして取得
for (i=0; i < seq->total; i++){
p=(CvPoint2D32f*)cvGetSeqElem(seq,i);
x=p->x;
y=p->y;
}

//x_bar, y_bar
for (i=0; i < seq->total; i++){
x_bar+=x;
y_bar+=y;
}

x_bar/=seq->total;
y_bar/=seq->total;
//セントラルモーメント
for (i=0; i < seq->total; i++){
u11+=((x-x_bar)*(y-y_bar));
u20+=pow(x-x_bar,2.0f);
u02+=pow(y-y_bar,2.0f);
}

u11/=seq->total;
u20/=seq->total;
u02/=seq->total;
//直線度の算出
linearity = sqrt(4*pow(u11,2.0f)+pow(u20-u02,2.0f))/(u20+u02);
return linearity;
}
Was mir aufgefallen ist
1. cvCreateSeq wird mit CV_32FC2 als 1.parameter aufgerufen! das ergibt bei mir aber einen Fehler!
aber das was mit der pSeq gemacht wird mache ich genau gleich und das funktioniert! (ist natürlich keine Garantie)
2. cvFitLine wird als Dist 2.Par CV_DIST_L2 mitgegeben, hat aber auch keine Besserung gebracht.

Im Anhang habe ich mal noch den Source Code von cvFitLine reingepackt, dort wird untersucht ob der Pointer auf das line Array Nil ist! Wie ich mein Line Array definiere ist dann also (noch) nicht für den Fehler verantwortlich, (wenn überhaupt).

Gruß

Stefan
Angehängte Dateien
Dateityp: cpp cvfitline_157.cpp (2,9 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Jaynder
Jaynder

Registriert seit: 2. Dez 2004
Ort: Süderelbe
134 Beiträge
 
Delphi 10.4 Sydney
 
#13

Re: DLL Funktion(en) von openCV einbinden

  Alt 17. Feb 2010, 16:36
Wenn ich nochmal auf die Fehlermeldung
Zitat:
"Unsupported format or combination of formats (Input sequence must consist of 2d
points or 3d points) in function cvFitLine, .\cvlinefit.cpp(665)"
bei verwendung von cv110.dll bzw. cxcore110.dll.
hinweisen darf: cvFitLine bekommt offensichlich schrottige Daten.

cvFitLine bekommt points : pcvArr

Delphi-Quellcode:
procedure cvFitLine(points : pcvArr; dist_Type : longInt; param : double; reps: double; aeps: double; line: pSingle);cdecl;
// ist in C
//void cvFitLine( const CvArr* points, int dist_type, double param, double reps, double aeps, float* line );
du übergibst aber ein pCvSeq

Delphi-Quellcode:
  seq : pCvSeq;

begin
   ...
    seq := cvCreateSeq(0, sizeOf(CvSeq), sizeOf(CvPoint2D32f), store);
    ...
    cvFitLine(seq, 0, 0, 0.01,0.01, @line[0]);
Liegt es vielleicht daran?
Und wieso übersetzt Delphi das eigentlich ohne Fehler?
  Mit Zitat antworten Zitat
alf.stefan

Registriert seit: 11. Apr 2003
88 Beiträge
 
Delphi 7 Professional
 
#14

Re: DLL Funktion(en) von openCV einbinden

  Alt 18. Feb 2010, 06:32
@Jaynder Wenn man das mit dem C Code vergleicht mache ich doch genau das gleiche in Bezug auf die 2 Einwände die Du machst!

1. Schrottige Daten: wenn ich die pSeq mit Punkten fülle und dann zur Kontrolle mit cvGetSeqElem genau den richtigen Daten Typ mit den richtigen Werten Lesen kann, dann können die Daten doch nicht so schrottig sein.

2. falscher Übergabe Typ: das ist auch genau wie in dem C-Beispiel! Es wird eine Sequenz vom Typ pCvSeq erzeugt und an cvFitLine übergeben
genau wie hier:
Delphi-Quellcode:
    var pLinkeEcke, ptmp1 : pIplImage;
           sc : cvScalar;
...
...
    ptmp1 := cvCreateImage(cvSize_(pLinkeEcke.Width, pLinkeEcke.Height), 8, 1);
    cvAddS(pLinkeEcke, sc, pTmp1, nil);

// definition von cvAddS in C
  void cvAddS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
in dem Beispiel übergebe ich ja auch ein pIplImage an eine routine die nur pCvArr nimmt und es funktioniert wunderbar.

Viel schlimmer finde ich es dass der Aufruf von cvCreateSeq
// CvSeq* cvCreateSeq( int seq_flags, int header_size,int elem_size, CvMemStorage* storage ); als seq_flag nur die 0 ohne Fehler nimmt! Und damit kann die Sequenz von cvFitLine nicht mehr richtig erkannt werden, was die angeblich schrottigen Daten erklären würde!
in der Doku steht dazu:
Zitat:
seq_flags
Flags of the created sequence. If the sequence is not passed to any function working with a specific type of sequences, the sequence value may be set to 0, otherwise the appropriate type must be selected from the list of predefined sequence types.
cvFitLine gehört scheinbar zu einer der "any" Funktionen die einen spezifischen Typ benötigen!

Ich bin ratlos! Trotzdem Danke!
Ich glaube es ist das beste mal das Entwicklerteam zu fragen ob die meine Fehler nachvollziehen können.

Gruß

Stefan
  Mit Zitat antworten Zitat
Benutzerbild von Jaynder
Jaynder

Registriert seit: 2. Dez 2004
Ort: Süderelbe
134 Beiträge
 
Delphi 10.4 Sydney
 
#15

Re: DLL Funktion(en) von openCV einbinden

  Alt 18. Feb 2010, 09:32
Das ist schon komisch, aber c-Beispiele können ja aucg Fehler enthalten.

Trotzdem nochmal die Frage: wieso übersetzt Delphi den cvFitLine-Call mit dem abweichenden Typen?
  Mit Zitat antworten Zitat
Benutzerbild von Jaynder
Jaynder

Registriert seit: 2. Dez 2004
Ort: Süderelbe
134 Beiträge
 
Delphi 10.4 Sydney
 
#16

Re: DLL Funktion(en) von openCV einbinden

  Alt 18. Feb 2010, 09:39
Nachtrag: ich habe im Netz cvlinefit.cpp gefunden, dort ist ein Call mit einem 2D-Array und einem Count. Vielleicht kannst du den direkt verwenden, ohne den "any"-Call benutzen zu müssen?

Code:
625   CV_IMPL void
626   cvFitLine2D( CvPoint2D32f * points, int count, CvDisType dist,
627                void *param, float reps, float aeps, float *line )
Jürgen
  Mit Zitat antworten Zitat
alf.stefan

Registriert seit: 11. Apr 2003
88 Beiträge
 
Delphi 7 Professional
 
#17

Re: DLL Funktion(en) von openCV einbinden

  Alt 18. Feb 2010, 11:12
Der Grund weshalb das compiliert wird ist die Deklaration von pCvArr!
Delphi-Quellcode:
    { CvArr* is used to pass arbitrary array-like data structures
    into the functions where the particular
     array type is recognized at runtime  }

    // CvArr = void;
  PCvArr = Pointer;
  P2PCvArr = ^PCvArr;
Deshalb wird man alles pointer ähnliches ohne Fehler übergeben können.
  Mit Zitat antworten Zitat
alf.stefan

Registriert seit: 11. Apr 2003
88 Beiträge
 
Delphi 7 Professional
 
#18

Re: DLL Funktion(en) von openCV einbinden

  Alt 18. Feb 2010, 11:19
Zu dem Nachtrag: In openCV 1.1 und auch 2.0a sind die beiden Routinen cvFitLine2D und auch cvFitLine3D in cvFitLine gekapselt oder so was in der Art.

Das heißt für die beiden 2D/3D routinen gibts gar keinen Einsprungpunkt. Also nur noch cvFitLine.

Version 0.97 (oder wars 0.98??) war ziemlich lange aktuell und viele Beispiele beziehen sich noch darauf ohne dass dazugeschrieben steht mit welcher Version von openCV gearbeitet wurde.
  Mit Zitat antworten Zitat
Benutzerbild von Jaynder
Jaynder

Registriert seit: 2. Dez 2004
Ort: Süderelbe
134 Beiträge
 
Delphi 10.4 Sydney
 
#19

Re: DLL Funktion(en) von openCV einbinden

  Alt 18. Feb 2010, 12:24
Ok, das mit dem nackten Pointer ist zwar übel, lässt aber wohl nicht vermeiden. Aber das Problem dann doch eindeutig beim cvCreateSeq, wie du schon erkannt hast.

Zitat:
Viel schlimmer finde ich es dass der Aufruf von cvCreateSeq
Delphi-Quellcode: markieren
// CvSeq* cvCreateSeq( int seq_flags, int header_size,int elem_size, CvMemStorage* storage );

als seq_flag nur die 0 ohne Fehler nimmt! Und damit kann die Sequenz von cvFitLine nicht mehr richtig erkannt werden, was die angeblich schrottigen Daten erklären würde!
in der Doku steht dazu:
Zitat:
seq_flag
Flags of the created sequence. If the sequence is not passed to any function working with a specific type of sequences, the sequence value may be set to 0, otherwise the appropriate type must be selected from the list of predefined sequence types.

cvFitLine gehört scheinbar zu einer der "any" Funktionen die einen spezifischen Typ benötigen!
Welcher Fehler kommt denn, wenn du das richtige seq_flags nimmst?
  Mit Zitat antworten Zitat
alf.stefan

Registriert seit: 11. Apr 2003
88 Beiträge
 
Delphi 7 Professional
 
#20

Re: DLL Funktion(en) von openCV einbinden

  Alt 18. Feb 2010, 14:08
Wenn ich cvCreateSeq mit dem Richtigen Parameter aufrufe bekomme ich einen Runtime Error.
Der "richtige" Parameter mit Namen CV_32F2 ist einfach die byte anzahl 32=4byte und das 2x wegen 2D sind 8 byte

Wenn ich cvCreateSeq mit 0 für den typ aufrufe wird flags $42990000
in meinem OpenCV_200.pas gibt es für die Bild/Matrizen/cvArr/Squenzen Magic Values
das sind

Delphi-Quellcode:
 
     CV_MAT_MAGIC_VAL = $42420000;
     CV_MATND_MAGIC_VAL = $42430000;
     CV_HIST_MAGIC_VAL = $42450000;
     CV_STORAGE_MAGIC_VAL = $42890000;
// dann auch
     CV_SEQ_MAGIC_VAL = $42990000; // wie zu erwarten war
dann habe ich mal in den C Sourcen nach den Konstanten gesucht und bin auf das gestoßen

Delphi-Quellcode:
#define CV_SEQ_MAGIC_VAL 0x42990000
#define CV_SET_MAGIC_VAL 0x42980000
#define CV_SEQ_ELTYPE_BITS 9
#define CV_SEQ_ELTYPE_MASK ((1 << CV_SEQ_ELTYPE_BITS) - 1)
#define CV_SEQ_ELTYPE_POINT CV_32SC2
#define CV_SEQ_ELTYPE_CODE CV_8UC1
#define CV_SEQ_ELTYPE_GENERIC 0
#define CV_SEQ_ELTYPE_PTR CV_USRTYPE1
#define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR
#define CV_SEQ_ELTYPE_INDEX CV_32SC1
#define CV_SEQ_ELTYPE_GRAPH_EDGE 0
#define CV_SEQ_ELTYPE_GRAPH_VERTEX 0
#define CV_SEQ_ELTYPE_TRIAN_ATR 0
#define CV_SEQ_ELTYPE_CONNECTED_COMP 0
#define CV_SEQ_ELTYPE_POINT3D CV_32FC3
#define CV_SEQ_KIND_BITS 3
#define CV_SEQ_KIND_MASK (((1 << CV_SEQ_KIND_BITS) - 1)<<CV_SEQ_ELTYPE_BITS)
#define CV_SEQ_KIND_GENERIC (0 << CV_SEQ_ELTYPE_BITS)
#define CV_SEQ_KIND_CURVE (1 << CV_SEQ_ELTYPE_BITS)
#define CV_SEQ_KIND_BIN_TREE (2 << CV_SEQ_ELTYPE_BITS)
#define CV_SEQ_KIND_GRAPH (3 << CV_SEQ_ELTYPE_BITS)
#define CV_SEQ_KIND_SUBDIV2D (4 << CV_SEQ_ELTYPE_BITS)
#define CV_SEQ_FLAG_SHIFT (CV_SEQ_KIND_BITS + CV_SEQ_ELTYPE_BITS)
#define CV_SEQ_FLAG_CLOSED (1 << CV_SEQ_FLAG_SHIFT)
#define CV_SEQ_FLAG_SIMPLE (2 << CV_SEQ_FLAG_SHIFT)
#define CV_SEQ_FLAG_CONVEX (4 << CV_SEQ_FLAG_SHIFT)
#define CV_SEQ_FLAG_HOLE (8 << CV_SEQ_FLAG_SHIFT)
#define CV_GRAPH_FLAG_ORIENTED (1 << CV_SEQ_FLAG_SHIFT)
#define CV_GRAPH CV_SEQ_KIND_GRAPH
#define CV_ORIENTED_GRAPH (CV_SEQ_KIND_GRAPH|CV_GRAPH_FLAG_ORIENTED)
#define CV_SEQ_POINT_SET (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT)
#define CV_SEQ_POINT3D_SET (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT3D)
#define CV_SEQ_POLYLINE (CV_SEQ_KIND_CURVE | CV_SEQ_ELTYPE_POINT)
#define CV_SEQ_POLYGON (CV_SEQ_FLAG_CLOSED | CV_SEQ_POLYLINE )
#define CV_SEQ_CONTOUR CV_SEQ_POLYGON
#define CV_SEQ_SIMPLE_POLYGON (CV_SEQ_FLAG_SIMPLE | CV_SEQ_POLYGON )
#define CV_SEQ_CHAIN (CV_SEQ_KIND_CURVE | CV_SEQ_ELTYPE_CODE)
#define CV_SEQ_CHAIN_CONTOUR (CV_SEQ_FLAG_CLOSED | CV_SEQ_CHAIN)
#define CV_SEQ_POLYGON_TREE (CV_SEQ_KIND_BIN_TREE | CV_SEQ_ELTYPE_TRIAN_ATR)
#define CV_SEQ_CONNECTED_COMP (CV_SEQ_KIND_GENERIC | CV_SEQ_ELTYPE_CONNECTED_COMP)
#define CV_SEQ_INDEX (CV_SEQ_KIND_GENERIC | CV_SEQ_ELTYPE_INDEX)
für mich sieht das aus als ob man mit diesen Konstanten also
MAGIC or typ or größe or weissNicht die flags haargenau so einstellen muss dass es halt passt!
Ich melde mich wieder wenn ich mehr weiß! Die Spur ist auf jeden Fall mal interessant!
Gruß und Ciao
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz