Ejemplo n.º 1
0
Archivo: io.c Proyecto: Almamu/portalDS
void writeRectangle(rectangle_struct* rec, FILE* f)
{
	if(!rec || !f)return;

	writeVect(rec->position,f);
	writeVect(rec->size,f);
	writeVect(rec->normal,f);
	
	fwrite(&rec->portalable,sizeof(bool),1,f);

	u16 mid=getMaterialID(rec->material);
	
	fwrite(&mid,sizeof(u16),1,f);
}
Ejemplo n.º 2
0
Archivo: io.c Proyecto: Almamu/portalDS
void writeLightingData(lightingData_struct* ld, FILE* f)
{
	if(!ld || !f)return;

	switch(ld->type)
	{
		case LIGHTMAP_DATA:
			writeVect(ld->data.lightMap.lmSize, f);
			fwrite(ld->data.lightMap.buffer, sizeof(u8), ld->data.lightMap.lmSize.x*ld->data.lightMap.lmSize.y, f);
			fwrite(ld->data.lightMap.coords, sizeof(lightMapCoordinates_struct), ld->size, f);
			break;
		default:
			{
				int i;
				for(i=0;i<ld->size;i++)writeVertexLightingData(&ld->data.vertexLighting[i],f);
			}
			break;
	}
}
Ejemplo n.º 3
0
int main(int argc, char *argv[]) {
    // Début compteur
    clock_t d_start, d_stop;
    d_start = clock();

    ImageGS *car = NULL;
    if(argc > 2) {
        string arg(argv[1]);

        if(arg.compare("-pgm") == 0)
            car = new ImageGS(argv[2]);
        else if(arg.compare("-ppm") == 0)
            car = new ImageGS(ImageRGB(argv[2]));
        else
            std::cout << "Usage: " << argv[0] << " [-ppm|-pgm] FILE\n";
    } else {
        car = new ImageGS("../data/991211-001");
        //car = new ImageGS(ImageRGB("../data/0003"));
        //car = new ImageGS("../data/99122-2");
    }

    // mesure de la variance (indicatif)
#ifdef _DEBUG_
    std::cout << "Variance de l'image : " << car->computeVariance() << std::endl;
#endif

#ifdef GAUSS_PRE_FILTER
    // filtrage gaussien
    ImageGS in(*car);
    in.gaussianFilter(0.5f);
    in.writePGM("0_gauss_filter");
#else
    ImageGS in = *car;
#endif

    /* Calcule du gradient en x */
    ImageGS *grad = in.computeHorizontalGradient();
    grad->recal();
#ifdef _DEBUG_
    grad->writePGM("0_grad");
#endif

    /* Projection horizontal */
    float* vect;
    vect = grad->computeHorizontalProjection();
#ifdef _DEBUG_
    writeVect(vect, grad->getHeight(), "data_h_brut.dat");
#endif

    // Filtre gaussien sur le vecteur de projection
    gaussianFilter(vect, grad->getHeight(), 6, 0.05f, 1);
#ifdef _DEBUG_
    writeVect(vect, grad->getHeight(), "data_h_filter.dat");
#endif

    /* Seuillage 'vertical' on ne garde que les ligne qui on une projection supérieur a un seuil */
    // averaging
    float avg = 0.f;
    for (unsigned i = 0; i < grad->getHeight(); ++i)
        avg += vect[i];
    avg /= grad->getHeight();

    // seuillage vertical
    for (unsigned i = 0; i < grad->getHeight(); ++i) {
        // si la projection de cette ligne est sous le seuil on la supprime
        if( vect[i] < PROJ_HORIZONTAL*avg ) {
            for (unsigned j = 0; j < grad->getWidth(); ++j) {
                (*grad)(i, j) = 0.f;
            }
        }
    }
    delete[] vect; // free
#ifdef _DEBUG_
    grad->writePGM("1_vertical_filter");
#endif

#if 0
    /* Projection verticale */
    vect = grad->computeVerticalProjection();
#ifdef _DEBUG_
    writeVect(vect, grad->getWidth(), "data_v_brut.dat");
#endif

    // Filtrage gaussien
    gaussianFilter(vect, grad->getWidth(), 6, 0.05f, 0);
#ifdef _DEBUG_
    writeVect(vect, grad->getWidth(), "data_v_filter.dat");
#endif

    /* Seuillage 'vertical' on ne garde que les ligne qui on une projection supérieur a T */
    // averaging
    avg = 0.f;
    for (unsigned i = 0; i < grad->getWidth(); ++i)
        avg += vect[i];
    avg /= grad->getWidth();

    // seuillage horizontal
    for (unsigned j = 0; j < grad->getWidth(); ++j) {
        // si la projection de cette ligne est sous le seuil on la supprime
        if( vect[j] < PROJ_VERTICAL*avg ) {
            for (unsigned i = 0; i < grad->getHeight(); ++i) {
                (*grad)(i, j) = 0.f;
            }
        }
    }

    delete[] vect; // free
#ifdef _DEBUG_
    grad->writePGM("1_horizontal_filter");
#endif

#endif

    /* binarisation par seuillage global */
    grad->thresholdingSmart(T_BIN);
#ifdef _DEBUG_
    grad->writePGM("2_bin_filter");
#endif

    /* Opération morphologique pour éliminer le bruit, etc..*/
    int width, height;
    float** mask;

#if 1 // Fermeture
    width=20; height=3;
    mask = new float*[height];
    for (int i = 0; i < height; ++i) {
        mask[i] = new float[width];
        for (int j = 0; j < width; ++j)
            mask[i][j] = 255.f;
    }
    grad->closing(mask, width, height);
#ifdef _DEBUG_
    grad->writePGM("3_2_close_grad");
#endif
#endif

#if 1 // Ouverture
    width=1; height=5;
    mask = new float*[height];
    for (int i = 0; i < height; ++i) {
        mask[i] = new float[width];
        for (int j = 0; j < width; ++j)
            mask[i][j] = 255.f;
    }
    grad->opening(mask, width, height);
#ifdef _DEBUG_
    grad->writePGM("4_open_grad");
#endif
#endif

    // On applique les rectangle sur l'image de base pour visualiser
    // les zone detectées comme potentiellement des plaques d'immatriculation
    ImageRGB *car_detect = new ImageRGB(*car);
    std::vector<int*> *listPlate = foundConnectedComponents(*grad, car_detect,
                                                            RATIO_MIN, RATIO_MAX,
                                                            WIDTH_MIN, WIDTH_MAX,
                                                        HEIGHT_MIN, HEIGHT_MAX);
#ifdef _DEBUG_
    car_detect->writePPM("5_plate_detect");
#endif
    delete grad; // free

    // On construit la liste des (potentiels) plaque extraites de l'image
    std::cout << "\n>> Analyse des zone retenues\n";
    std::vector<ImageGS*> *listImgPlate = new std::vector<ImageGS*>();
    char filename[100]; // Chaine de caractère pour la sauvergarde des images
    for (unsigned n = 0; n < listPlate->size(); ++n) {
        //  on fixe si possible une marge de quelques pixel (pour eviter le crop)
        int x1 = max((*listPlate)[n][0]-MARGIN_W, 0),
            y1 = max((*listPlate)[n][1]-MARGIN_H, 0),
            x2 = min((*listPlate)[n][2]+MARGIN_W, (int)car->getWidth()),
            y2 = min((*listPlate)[n][3]+MARGIN_H, (int)car->getHeight());
        delete[] (*listPlate)[n]; // free

        unsigned w = x2-x1, h = y2-y1;

        // On crée la miniature
        ImageGS *img = new ImageGS(w, h);
        for (unsigned i = 0; i < h; ++i)
        for (unsigned j = 0; j < w; ++j)
            (*img)(i, j) = (*car)(i+y1, j+x1);

        // On effectué un derniere verification basé sur les edge de la plaque
        ImageGS *plate = new ImageGS(*img);
        plate->inverse();

#ifdef _DEBUG_
        std::cout << "Variacance: " << plate->computeVariance() << std::endl;
#endif

        // Seuillage automatique
        plate->thresholdingOstu();

#if 0
        width=1; height=3;
        mask = new float*[height];
        for (int i = 0; i < height; ++i) {
            mask[i] = new float[width];
            for (int j = 0; j < width; ++j)
                mask[i][j] = 255.f;
        }
        plate->opening(mask, width, height);
#endif

        /* Erostion / Disatation extraire les contours */
        ImageGS erode(*plate);
#if 1
        width=2; height=2;
        mask = new float*[height];
        for (int i = 0; i < height; ++i) {
            mask[i] = new float[width];
            for (int j = 0; j < width; ++j)
                mask[i][j] = 255.f;
        }
        erode.erosion(mask, width, height);
#endif
#if 1
        width=1; height=3;
        mask = new float*[height];
        for (int i = 0; i < height; ++i) {
            mask[i] = new float[width];
            for (int j = 0; j < width; ++j)
                mask[i][j] = 255.f;
        }
        plate->dilatation(mask, width, height);
#endif

        // on soustrait l'érodé au dilaté pour garder que les contours
        (*plate) -= erode;

#ifdef _DEBUG_
        // Save
        sprintf(filename, "t_plate_%d", n);
        plate->writePGM(filename);
#endif

        float var=0, var_cpt=0;
        for (unsigned j = 1; j < w; ++j) {
            // on compte le nombre de variation
            var_cpt = 0;
            if((*plate)(h/3, j) != (*plate)(h/3, j-1))
                ++var_cpt;
            if((*plate)(h/2, j) != (*plate)(h/2, j-1))
                ++var_cpt;
            if((*plate)(h-h/3, j) != (*plate)(h-h/3, j-1))
                ++var_cpt;

            // On pondère le résultat suivant le nombre variations simultanées
            if(var_cpt == 3)
                var += 2.f;
            else if(var_cpt == 2)
                var += 1.f;
            else if(var_cpt == 1)
                var += .5f;
        }

        float varRatio = var/(float)(plate->getWidth()+plate->getHeight());
#ifdef _DEBUG_
        std::cout << "Variations (seuil 1: "<< T_1_PLATE << " - seuil 2: " << T_2_PLATE <<
                     ") - Variations: " << var <<
                     " Ratio de variation: " << varRatio <<
                     "\n" << std::endl;
#endif

        /*
         * On Compare d'abord les seuils classiques (variation minimal et maximal)
         * Puis on regarde si le ratio 'var/taille de la zone' est respecté.
         *
         * Si le premier teste n'est pas valide on regarde seulement si le ratio
         * est suppérieur a un autre seuil. C'est une "sorte" de seuillage par hystéresis.
         */
        if(var > T_1_PLATE && var < T_2_PLATE && varRatio > T_R2_PLATE)
            listImgPlate->push_back(img);
        else if(varRatio > T_R1_PLATE)
            listImgPlate->push_back(img);

        delete plate; // free
    }
    delete listPlate;

    // Sauvegarde des plaques reconnues
    for (unsigned n = 0; n < listImgPlate->size(); ++n) {
        sprintf(filename, "plate_%d", n);
        (*listImgPlate)[n]->writePGM(filename);
        sprintf(filename, "display plate_%d.pgm&", n);
        system(filename);
        delete (*listImgPlate)[n]; // free
    }

    std::cout << "\n>> Programme terminé : " << listImgPlate->size() << " plaques ont/a été reconnue(s).\n";

    // free
    if(car != NULL) {
        delete listImgPlate;
        delete car;
        delete car_detect;
        delete[] mask;
    }

    // Fin compteur
    d_stop = clock();
    double duration = d_stop-d_start;
    std::cout << "Temps d'éxecution total : " << duration / (double)CLOCKS_PER_SEC << "s\n";

    return 0;
}
Ejemplo n.º 4
0
Archivo: io.c Proyecto: Almamu/portalDS
bool writeEntity(entity_struct* e, FILE* f)
{
	if(!e || !f || !e->used || !e->type)return false;

	fwrite(&e->type->id,sizeof(u8),1,f);
	writeVect(e->position, f);
	fwrite(&e->direction, sizeof(u8), 1, f);

	switch(e->type->id)
	{
		case 0:
			//energy ball catcher
			{
				s16 target=(e->target)?(e->target->writeID):(-1);
				writeVect(adaptVector(e->position, e->direction), f);
				fwrite(&target, sizeof(s16), 1, f);
			}
			return true;
		case 1:
			//energy ball launcher
			writeVect(adaptVector(e->position, e->direction), f);
			return true;
		case 2:
			//timed button
			{
				s16 target=(e->target)?(e->target->writeID):(-1);
				writeVect(adaptVector(e->position, e->direction), f);
				fwrite(&e->orientation, sizeof(u8), 1, f);
				fwrite(&target, sizeof(s16), 1, f);
			}
			return true;
		case 3:
			//pressure button
			{
				s16 target=(e->target)?(e->target->writeID):(-1);
				writeVect(adaptVector(e->position, e->direction), f);
				fwrite(&target, sizeof(s16), 1, f);
			}
			return true;
		case 4:
			//turret
			{
				writeVect(adaptVector(e->position, 6), f);
				fwrite(&e->orientation, sizeof(u8), 1, f);
			}
			return true;
		case 5: case 6: case 7:
			//cubes and dispenser
			{
				s16 target=(e->target)?(e->target->writeID):(-1);
				writeVect(adaptVector(e->position, e->direction), f);
				fwrite(&target, sizeof(s16), 1, f);
			}
			return true;
		case 8:
			//emancipation grid
			{
				int32 l=getGridLength(e);
				// NOGBA("L %d",l);
				fwrite(&l,sizeof(int32),1,f);
				writeVect(adaptVector(e->position, e->direction), f);
			}
			return true;
		case 9:
			//platform
			{
				s16 target=(e->target)?(e->target->writeID):(-1);
				vect3D tp=e->position;
				writeVect(vect(e->position.x*BLOCKMULTX+BLOCKMULTX/2,e->position.y*BLOCKMULTY,e->position.z*BLOCKMULTZ+BLOCKMULTZ/2), f);
				if(e->target)tp=e->target->position;
				writeVect(vect(tp.x*BLOCKMULTX+BLOCKMULTX/2,tp.y*BLOCKMULTY,tp.z*BLOCKMULTZ+BLOCKMULTZ/2), f);
				fwrite(&target, sizeof(s16), 1, f);
			}
			return true;
		case 10:
			//door
			{
				writeVect(vect(e->position.x*BLOCKMULTX+BLOCKMULTX/2,e->position.y*BLOCKMULTY,e->position.z*BLOCKMULTZ+BLOCKMULTZ/2), f);
				fwrite(&e->orientation, sizeof(u8), 1, f);
			}
			return true;
		case 11:
			//light
			writeVect(vect(e->position.x*BLOCKMULTX+BLOCKMULTX/2,e->position.y*BLOCKMULTY-BLOCKMULTY/2,e->position.z*BLOCKMULTZ+BLOCKMULTZ/2), f);
			return true;
		case 12:
			//platform target
			{
				s16 target=(e->target)?(e->target->writeID):(-1);
				fwrite(&target, sizeof(s16), 1, f);
			}
			return true;
		case 13:
			//wall door (start)
			{
				writeVect(adaptVector(e->position, e->direction), f);
				fwrite(&e->direction,sizeof(u8),1,f);
			}
			return true;
		case 14:
			//wall door (exit)
			{
				writeVect(adaptVector(e->position, e->direction), f);
				fwrite(&e->direction,sizeof(u8),1,f);
			}
			return true;
		default:
			return true;
	}
}
Ejemplo n.º 5
0
Archivo: io.c Proyecto: Almamu/portalDS
void writeTranslatedVect(vect3D v, FILE* f)
{
	writeVect(vectDifference(v,vect((ROOMARRAYSIZEX/2)*BLOCKMULTX,(ROOMARRAYSIZEY/2)*BLOCKMULTY,(ROOMARRAYSIZEZ/2)*BLOCKMULTZ)),f);
}