Je travaille toujours sur le dernier programme et bien que j'aie enfin trouvé comment résoudre le problème (sur comment filtrer le plus grand contour), j'ai maintenant une nouvelle question, ou plutôt un problème.
Comme vous pouvez le voir, j'utilise l'algorithme de Canny pour rechercher les bords dans la vidéo. Mais l'objet que j'utiliserai pour la détection n'a pas de couleur particulière, donc lorsque la couleur de l'objet est à peu près la même que celle de l'arrière-plan (par exemple si l'objet est argenté et l'arrière-plan est blanc), le bord de l'objet disparaîtra et je ne pourrai pas obtenir le contour de l'objet.
Pour le moment, je vais tester chaque algorithme de filtrage de bord disponible dans OpenCV mais pour abréger mon travail, j'ai besoin de votre aide pour recommander le meilleur (ou du moins meilleur) algorithme que Canny. J'ai déjà testé Sobel mais le résultat n'est pas meilleur que celui de Canny. Si possible, veuillez me fournir quelques bons exemples à titre de référence.
Le 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,"Impossible de trouver de caméra. \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("point central=(%.f, %.f), Surface = %.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( "Entrée", img );
cvShowImage( "Contours", src_gray );
cvClearMemStorage(storage);
if(cvWaitKey(33)>=0) break;
}
cvDestroyWindow("Contours");
cvDestroyWindow("Source");
cvReleaseCapture(&cam);
}
...et enfin, les images d'exemple tant attendues:
Premièrement, celle de qualité (mon portefeuille noir)
Deuxièmement, l'échec (une boîte orange)
Et enfin, un autre échec (une boîte blanche)
P.S., Quelques notes:
- L'objet n'a pas de forme, couleur ou taille particulière donc à mon avis, le mieux est de trouver le bord de l'objet plutôt que de le filtrer par couleur.
- Je tiendrai l'objet donc peut-être que mon doigt peut provoquer un changement ou une disparition du bord de l'objet.
- Je travaille sur un programme de traitement vidéo donc plus le temps de traitement est court et moins la puissance de traitement est nécessaire, mieux c'est.
- Mon programme filtrera le plus grand contour et le remplira de couleur rouge (voir la première image).
Merci d'avance. Cordialement