Reconeixament d'objectes utilitzant llibreries MIL

04-05-2007 > M.Casanovas


Mostrar o escribir comentarios (dudas) sobre este artículo

Temàtica de Visió per Computador
Programació en llenguatge C++
Utilització llibreries propietàries MIL.

 
La finalitat d'aquest document és fer una introducció a la visió per computador mitjançant les llibreries MIL (MATROX Imaging Library). Suposem que tenim una cadena de fabricació i volem contar les peces que passen per la cadena. Una manera de resoldre aquesta situació és muntar un petit sistema que capturi una imatge dels objectes que van passant per la cadena i llavors els mitjançant les llibreries MIL podem fer un reconeixement dels patrons dels objectes de la imatge per tal de identificar-los.
 
En el meu cas, he elaborat un petit algorisme que permet identificar i dir la seva ubicació de cargols, arandeles i femelles. Les peces poden ser de diferents tamany.
 
Suposem que tenim la següent imatge capturada de la cadena:


L'algorisme que identifica els objectes és:
> vim rct.cpp
#include <stdio.h>
#include <iostream.h>
#include <mil.h>
#define AMPLADA 384
#define ALCADA 288
#define LLINDAR 100
#define MAX_OBJECTES 5 
 
void main(int argc,char *argv[]){
 
/*Variables auxiliars*/
   char aux;
   int i;
/*Variables MIL*/
    MIL_ID
        MilApplication,        //Identificador de l'aplicació
        MilSystem,        //Identificador del sistema
        MilDisplay,        //Identificador de display
        MilImage,        //Identificador de l'imatge
        FeatureList,        //Identificador de FeatureList
        BlobResult;        //Identificador del resultat del Blob
    long TotalBlobs,        //Vectors per guardar informació de cada objecte de la imatge 
        CorX[MAX_OBJECTES],
        CorY[MAX_OBJECTES],
        Perimetre[MAX_OBJECTES],
        Forat[MAX_OBJECTES],
        min[MAX_OBJECTES],
        max[MAX_OBJECTES],
        Pd;
 
/*Informacio de parametres*/
    if (argc!=2){
        cout<<"Numero de parametres incorrecta!!! ";
        cout<<"La crida ha de ser del tipus: ";
        cout<<"prac4.exe nomfitxer.tif ";
    }
    else{
    /* Inicialització per treballar amb les MIL */
    MappAllocDefault (M_SETUP, &MilApplication, &MilSystem,
        M_NULL,M_NULL, M_NULL); 
    /* Inicialitzar display */
    MdispAlloc (MilSystem, M_DEV0, M_DISPLAY_SETUP,    M_DEFAULT, &MilDisplay);
 
    /* Inicialitzar buffer per la imatge */
    MbufAlloc2d (MilSystem, AMPLADA, ALCADA, 8+M_UNSIGNED, 
        M_IMAGE+M_PROC+M_DISP, &MilImage);
    /* Carreguem la imatge */
    MbufLoad (argv[1], MilImage);
 
    /* Esborrem el soroll amb un filtre passa baixes tipus SMOOTH */
    //MimConvolve (MilImage, MilImage, M_SMOOTH);
 
    /* Binaritzem la imatge a partir d'un llindar 128*/
    MimBinarize (MilImage, MilImage,M_LESS_OR_EQUAL, LLINDAR, M_NULL);
    MimDilate (MilImage, MilImage, 2,M_BINARY);
    MimErode (MilImage, MilImage, 2,M_BINARY);
 
    /* Associació del display amb la imatge, per visualitzar-la */ 
    MdispSelect (MilDisplay, MilImage);
    cout<<"Prem la tecla 'S' i 'ENTER' per continuar ";
    cin>>aux;
    /*MBLOB==FIGURA*/
    /* Inicialització del buffer per la FeatureList i pel resultat*/
    MblobAllocFeatureList(MilSystem,&FeatureList);
    MblobAllocResult(MilSystem,&BlobResult);
     
    /*Activem components de la FeatureList*/
    MblobSelectFeature(FeatureList,M_PERIMETER);
    MblobSelectFeature(FeatureList,M_NUMBER_OF_HOLES);
    MblobSelectFeature(FeatureList,M_CENTER_OF_GRAVITY_X);
    MblobSelectFeature(FeatureList,M_CENTER_OF_GRAVITY_Y);
    MblobSelectFeature(FeatureList,M_FERET_MIN_DIAMETER);
    MblobSelectFeature(FeatureList,M_FERET_MAX_DIAMETER);
 
    /*Calculem per cada figura les components activades*/
    MblobCalculate(MilImage,M_NULL,FeatureList,BlobResult);
 
    /*Obtenim el numero de figures i el seu centre de gravetat*/
    MblobGetNumber(BlobResult, &TotalBlobs);
    MblobGetResult(BlobResult,M_CENTER_OF_GRAVITY_X+M_TYPE_LONG,CorX);
    MblobGetResult(BlobResult,M_CENTER_OF_GRAVITY_Y+M_TYPE_LONG,CorY);
    MblobGetResult(BlobResult,M_PERIMETER+M_TYPE_LONG,Perimetre);
    MblobGetResult(BlobResult,M_NUMBER_OF_HOLES+M_TYPE_LONG,Forat);
    MblobGetResult(BlobResult,M_FERET_MIN_DIAMETER+M_TYPE_LONG,min);
    MblobGetResult(BlobResult,M_FERET_MAX_DIAMETER+M_TYPE_LONG,max);
    /*Mostrem el numero de Blobs i el centre de gravetat*/
    printf ("****************************************************** ");
    printf ("************Hi han %i objectes a la imatge************* ",TotalBlobs);
    for (i=0;i<TotalBlobs;i++){
        printf("****************************************************** ");
        printf("Figura numero:");
        printf("%d",i);
        printf(" Centre de gravetat--------> X=%i, Y=%i. ",CorX[i],CorY[i]);
        printf("Perimetre-----------------> P=%i. ",Perimetre[i]);
        printf("Numero de forats----------> F=%i. ",Forat[i]);
        printf("Diametre Min--------------> Di=%i. ",min[i]);
        printf("Diametre Max--------------> Da=%i. ",max[i]);
        printf("Interval de diametre------> Id=%i. ",(max[i]-min[i]));
        Pd=Perimetre[i]/max[i];
        printf("Perimetre / diamtre-------> Pd=%i. ",Pd);
        if (Forat[i]==0) printf("Aquest objecte es un CARGOL!! ");
        else{
            if (Pd<=4){
                if ((max[i]-min[i])>=3)    printf("Aquest objecte es una FAMELLA!! ");
                else printf("No es pot decidir que es aquest objecte ");
                }
            if (Pd>=5){
                if ((max[i]-min[i])<=2) printf("Aquest objecte es una ARANDELA!! ");
                else printf("No es pot decidir que es aquest objecte ");
                }
            }
    }
 
    /* Alliberament de la memòria i dels dispositius utilitzats */
    MdispFree (MilDisplay);
    MbufFree (MilImage);
    MappFreeDefault (MilApplication, MilSystem, M_NULL, M_NULL, M_NULL);
    MblobFree (FeatureList);
    MblobFree (BlobResult);
    }}

 
Es compila el programa (es pot utilitzar qualsevol compilador C++, com VisualC o g++) i fem l'execució:
> ./binari peces.tif

Mostrar o escribir comentarios (dudas) sobre este artículo