All pastes #943524 Raw Edit

Unnamed

public cpp v1 · immutable
·published 2008-03-15 11:02 UTC
rendered paste body
/* images_processing.cpp */#include <iostream>#include "images_processing.h"using namespace std;struct Pixel {	int R, G, B;};/* Fonction qui applique un filtre linéaire à l'image. Elle prend en paramètre l'adresse du pointeur vers le tableau, la matrice deconvolution, la longueur et la largeur du tableau */struct Pixel ** apply_linear_filter(Pixel ** array, float mat_convol[7][7], int width, int height) {	int i, j;	float new_pixel_val_R, new_pixel_val_G, new_pixel_val_B;	// On crée un nouveau tableau de la même taille que le précédent pour y stocker les nouvelles valeurs des pixels	Pixel **array_ter = new Pixel *[height];	for(i = 0; i < height; i++) {		array_ter[i] = new Pixel [width];	}	// On parcourt tout le tableau	for(i = 0; i < height; i++) {		for(j = 0; j < width; j++) {			// On met les valeurs des nouveaux pixels à zéros			new_pixel_val_R = 0.0;			new_pixel_val_G = 0.0;			new_pixel_val_B = 0.0;			// On parcourt la matrice de convolution ainsi que les éléments du tableau qui seront affectés par la matrice			// Voir schéma n° x			for(int i_1 = -3; i_1 <= 3; i_1++) {				for(int j_1 = -3; j_1 <= 3; j_1++) {					if(i + i_1 >= 0 && i + i_1 < height && j + j_1 >= 0 && j + j_1 < width) {						new_pixel_val_R += mat_convol[3 + i_1][3 + j_1] * float(array[i + i_1][j + j_1].R);						new_pixel_val_G += mat_convol[3 + i_1][3 + j_1] * float(array[i + i_1][j + j_1].G);						new_pixel_val_B += mat_convol[3 + i_1][3 + j_1] * float(array[i + i_1][j + j_1].B);					}				}			}			// On vérifie que la valeur des pixels n'est pas négative ou positive auxquels cas, on rectifie			if(new_pixel_val_R > 255)				new_pixel_val_R = 255;			else if(new_pixel_val_R < 0)				new_pixel_val_R = 0;			if(new_pixel_val_G > 255)				new_pixel_val_G = 255;			else if(new_pixel_val_G < 0)				new_pixel_val_G = 0;			if(new_pixel_val_B > 255)				new_pixel_val_B = 255;			else if(new_pixel_val_B < 0)				new_pixel_val_B = 0;			// On ajoute ces valeurs arrondies à l'entier inférieur dans la nouvelle matrice			array_ter[i][j].R = int(new_pixel_val_R);			array_ter[i][j].G = int(new_pixel_val_G);			array_ter[i][j].B = int(new_pixel_val_B);		}	}	// On supprime l'ancien tableau devenu inutile	for(i = 0; i < height; i++) {		delete[] array[i];	}	delete[] array;	// On renvoie l'adresse du nouveau tableau pour faire pointer le pointeur défini dans main dessus	return array_ter;}// Fonction de tri par sélectionvoid selection_sort(int array_sort[], const int length) {	int i, j, max, max_pos, tmp;	for(i = length - 1; i >= 0; i--) {		max = array_sort[0];		max_pos = 0;		for(j = 1; j < i; j++) {			if(max < array_sort[j]) {				max = array_sort[j];				max_pos = j;			}		}		tmp = array_sort[i];		array_sort[i] = max;		array_sort[max_pos] = tmp;	}}/* Fonction qui applique un filtre non-linéaire à l'image. Elle prend en paramètre l'adresse du pointeur vers le tableau, la longueur et la largeur du tableau */struct Pixel ** apply_non_linear_filter(Pixel ** array, int width, int height) {	int i, j, i_1, j_1, k;	// On crée un nouveau tableau de la même taille que le précédent pour y stocker les nouvelles valeurs des pixels	Pixel **array_ter = new Pixel *[height];	for(i = 0; i < height; i++) {		array_ter[i] = new Pixel [width];	}	// On parcourt tout le tableau	for(i = 0; i < height; i++) {		for(j = 0; j < width; j++) {			int array_2_sort_R[9], array_2_sort_G[9], array_2_sort_B[9];			k = 0;			/* Ici on use d'une astuce qui simule une sorte de matrice carrée centrée sur l'élément courant pour parcourir			tous les éléments autour. De plus, on use de l'effet miroir, c-à-d qu'au lieu de considére les pixels au-delà du			bord comme étant égaux à 0, on fait une symétrie centrale par rapport à l'élement courant */			for(i_1 = -1; i_1 <= 1; i_1++) {				for(j_1 = -1; j_1 <= 1; j_1++) {					if(i + i_1 < 0 || i + i_1 > height - 1) {						if(j + j_1 < 0 || j + j_1 > width - 1) {							array_2_sort_R[k] = array[i - i_1][j - j_1].R;							array_2_sort_G[k] = array[i - i_1][j - j_1].G;							array_2_sort_B[k] = array[i - i_1][j - j_1].B;						} else {							array_2_sort_R[k] = array[i - i_1][j + j_1].R;							array_2_sort_G[k] = array[i - i_1][j + j_1].G;							array_2_sort_B[k] = array[i - i_1][j + j_1].B;						}					} else {						if(j + j_1 < 0 || j + j_1 > width - 1) {							array_2_sort_R[k] = array[i + i_1][j - j_1].R;							array_2_sort_G[k] = array[i + i_1][j - j_1].G;							array_2_sort_B[k] = array[i + i_1][j - j_1].B;						} else {							array_2_sort_R[k] = array[i + i_1][j + j_1].R;							array_2_sort_G[k] = array[i + i_1][j + j_1].G;							array_2_sort_B[k] = array[i + i_1][j + j_1].B;						}					}					k++;				}			}			// On trie le tableau qui contient l'ensemble des pixels autour du pixel central			selection_sort(array_2_sort_R, 9);			selection_sort(array_2_sort_G, 9);			selection_sort(array_2_sort_B, 9);			// On prend l'élément du milieu			array_ter[i][j].R = array_2_sort_R[4];			array_ter[i][j].G = array_2_sort_G[4];			array_ter[i][j].B = array_2_sort_B[4];		}	}	// On supprime l'ancien tableau devenu inutile	for(i = 0; i < height; i++) {		delete[] array[i];	}	delete[] array;	// On renvoie l'adresse du nouveau tableau pour faire pointer le pointeur défini dans main dessus	return array_ter;}/* Fonction qui réduit une image. Elle prend en paramètre l'adresse du pointeur vers le tableau, la longueur et la largeur du tableau et lepourcentage de réduction.L'idée est de faire la moyenne d'un certain nombre de pixels (calculé en fonction du pourcentage de réduction) et de stocker cette valeurdans un nouveau pixel */struct Pixel ** shrink_image(Pixel ** array, int & width, int & height, float percent) {	/* Liste des variables entières:	new_width est la nouvelle largeur du tableau arrondie à l'unité inférieure	new_height est la nouvelle hauteur du tableau arrondie à l'unité inférieure	height_inc est l'incrémentation de hauteur, c-à-d le nombre d'éléments en hauteur qui vont être "compressés" dans un seul pixel	width_inc est l'incrémentation de largeur, c-à-d le nombre d'éléments en largeur qui vont être "compressés" dans un seul pixel	i parcourt les lignes du tableau	j parcourt les colonnes du tableau	i_1 parcourt les lignes de la zone à "compresser"	j_1 parcourt les colonnes de la zone à "compresser"	count compte le nombre d'éléments pour la division dans le calcul de la moyenne (par ex: sum_R / count)	cur_new_i représente l'indice de ligne du pixel vers lequel sera "compressée" la zone courante	cur_new_j représente l'indice de colonne du pixel vers lequel sera "compressée" la zone courante */	int new_width = int(float(1.0 * width * percent)), new_height = int(float(1.0 * height * percent)), height_inc, width_inc;	int i, j, i_1, j_1, count, cur_new_i = 0, cur_new_j = 0, pixels_left_height, pixels_left_width;	/* Liste des variables float:	ratio_height contient le quotient de la hauteur originale et de la nouvelle hauteur pour pouvoir calculer la hauteur de la zone à		compresser	ratio_width contient le quotient de la largeur originale et de la nouvelle largeur pour pouvoir calculer la largeur de la zone à		compresser	sum_R contient la somme des valeurs des pixels rouges pour le calcul de la moyenne (sum_R / count)	sum_G contient la somme des valeurs des pixels verts pour le calcul de la moyenne (sum_R / count)	sum_B contient la somme des valeurs des pixels bleus pour le calcul de la moyenne (sum_R / count) */	float ratio_height = 1.0 * height / new_height, ratio_width = 1.0 * width / new_width, sum_R, sum_G, sum_B;	// On crée un nouveau tableau de la nouvelle taille pour y stocker les nouvelles valeurs des pixels	Pixel **array_ter = new Pixel *[new_height];	for(i = 0; i < new_height; i++) {		array_ter[i] = new Pixel [new_width];	}	height_inc = int(ratio_height);	width_inc = int(ratio_width);	pixels_left_height = height - (new_height * height_inc);	pixels_left_width = width - (new_width * width_inc);	int * height_inc_array = new int [new_height + 1];	int * width_inc_array = new int [new_width + 1];	for(i = 0; i < new_height; i++) {		height_inc_array[i] = height_inc;		if(pixels_left_height > 0) {			height_inc_array[i]++;			pixels_left_height--;		}		if(i == new_height - 1 && pixels_left_height > 0) {			i = -1;		}	}	height_inc_array[new_height] = 100;	for(j = 0; j < new_width; j++) {		width_inc_array[j] = width_inc;		if(pixels_left_width > 0) {			width_inc_array[j]++;			pixels_left_width--;		}		if(j == new_width - 1 && pixels_left_width > 0) {			j = -1;		}	}	width_inc_array[new_width] = 100;	// On parcourt tout le tableau	for(i = 0; i < height; i = i + height_inc_array[cur_new_i - 1]) {		cur_new_j = 0;		for(j = 0; j < width; j = j + width_inc_array[cur_new_j - 1]) {			sum_R = 0.0;			sum_G = 0.0;			sum_B = 0.0;			count = 0;			for(i_1 = 0; i_1 <= height_inc_array[cur_new_i]; i_1++) {				for(j_1 = 0; j_1 <= width_inc_array[cur_new_j]; j_1++) {					if(i + i_1 >= 0 && i + i_1 < height && j + j_1 >= 0 && j + j_1 < width) {						sum_R += array[i + i_1][j + j_1].R;						sum_G += array[i + i_1][j + j_1].G;						sum_B += array[i + i_1][j + j_1].B;							count++;					}				}			}			array_ter[cur_new_i][cur_new_j].R = int(sum_R / count);			array_ter[cur_new_i][cur_new_j].G = int(sum_G / count);			array_ter[cur_new_i][cur_new_j].B = int(sum_B / count);			cur_new_j++;		}		cur_new_i++;	}	for(i = 0; i < height; i++) {		delete[] array[i];	}	delete[] array;	width = new_width;	height = new_height;	return array_ter;}