Besserer Algorithmus für Kantenfilter in der Videoprogrammierung

Ich arbeite immer noch an derletztes Programm und obwohl ich endlich herausgefunden habe, wie man das problem löst (wie man die größte kontur filtert), habe ich jetzt eine neue frage oder eher ein problem.

Wie Sie sehen können, verwende ich den Canny-Algorithmus zum Suchen der Kanten im Video. Das Objekt, das ich für die Erkennung verwenden werde, hat jedoch keine bestimmte Farbe. Wenn die Farbe des Objekts in etwa mit der Farbe der Umgebung übereinstimmt (z. B. wenn das Objekt silberfarben und der Hintergrund weiß ist), verschwindet der Rand des Objekts und ich kann den nicht erkennen Objektkontur.

Im Moment werde ich jeden in OpenCV verfügbaren Kantenfilteralgorithmus testen, aber um meine Arbeit zu verkürzen, brauche ich Ihre Hilfe, um sie zu empfehlender beste (oder zumindest bessere) Algorithmus als canny. Jetzt habe ich Sobel getestet, aber das Ergebnis ist nicht besser als das von Canny. Wenn möglich, verlinken Sie mich bitte zu Referenzzwecken mit einem guten Beispiel.

Der Code:

int main( int argc, char** argv )
{
CvCapture *cam;
CvMoments moments;
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contours = NULL;
CvSeq* contours2 = NULL;
CvPoint2D32f center;
int i;

cam=cvCaptureFromCAM(0);
if(cam==NULL){
    fprintf(stderr,"Cannot find any camera. \n");
    return -1;
}
while(1){
    IplImage *img=cvQueryFrame(cam);
    if(img==NULL){return -1;}
    IplImage *src_gray= cvCreateImage( cvSize(img->width,img->height), 8, 1);
    cvCvtColor( img, src_gray, CV_BGR2GRAY );
    cvSmooth( src_gray,  src_gray, CV_GAUSSIAN, 5, 11);
    cvCanny(src_gray, src_gray, 70, 200, 3);

    cvFindContours( src_gray, storage, &contours, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
    if(contours==NULL){ contours=contours2;}
    contours2=contours;
    CvSeq* current_contour = contours;
    double largestArea = 0;
    CvSeq* largest_contour = NULL;
    while (current_contour != NULL){
        double area = fabs(cvContourArea(current_contour,CV_WHOLE_SEQ, false));       
        if(area > largestArea){
            largestArea = area;
            largest_contour = current_contour;
        }
        current_contour = current_contour->h_next;
    }

    cvMoments(largest_contour, &moments, 1);

    double m_00 = cvGetSpatialMoment( &moments, 0, 0 );
    double m_10 = cvGetSpatialMoment( &moments, 1, 0 );
    double m_01 = cvGetSpatialMoment( &moments, 0, 1 );
    float gravityX = (m_10 / m_00)-150;
    float gravityY = (m_01 / m_00)-150;
    if(gravityY>=0&&gravityX>=0&&m_00>=3000){
        printf("center point=(%.f, %.f), Area = %.f \n",gravityX,gravityY,m_00); }


    if(m_00>=3000){
        CvScalar color = CV_RGB(250,0,0);
        cvDrawContours(img,largest_contour,color,color,-1,-1, 8, cvPoint(0,0));
    }

    cvShowImage( "Input", img );
    cvShowImage( "Contours", src_gray );
    cvClearMemStorage(storage);
    if(cvWaitKey(33)>=0) break;
}
cvDestroyWindow("Contours");
cvDestroyWindow("Source");
cvReleaseCapture(&cam);
}

... und zum Schluss die lang erwarteten Beispielbilder:

Zuerst die Gute (meine schwarze Brieftasche)

Zweitens ist das Scheitern (ein orangefarbenes Kästchen)

Und zuletzt ein weiterer Fehler (eine weiße Box)

Einige Anmerkungen:

Das Objekt hat keine bestimmte Form, Farbe oder Größe. Daher ist es meiner Meinung nach am besten, den Rand des Objekts zu finden, anstatt es nach Farben zu filtern.Ich halte das Objekt, damit sich die Kante des Objekts mit meinem Finger möglicherweise ändert oder verschwindet.Ich arbeite an einem Videoverarbeitungsprogramm. Je kürzer die Verarbeitungszeit und je geringer die benötigte Verarbeitungsleistung, desto besser.Mein Programm filtert die größte Kontur heraus und füllt sie mit roter Farbe (siehe erstes Bild).

Danke im Voraus. Prost

Antworten auf die Frage(1)

Ihre Antwort auf die Frage