Operador Prewitt y Roberts

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 17

Operador

Prewitt y
Roberts

Benemerita Universidad Autonoma de Puebla


Lic. en ingenieria en ciencias de la
computación
CCOS608
NRC: 48136
Procesamiento digital de imagenes
Primavera 2023
Alumno: Misael Daniel Justo Silvestre
Docente: Hilario Salazar Martines
14 de abril del 2023
Código Fuente
1. Demo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "PGM.c"

#define MAX_ROWS 500


#define MAX_COLS 500

/* Variables globales. Para que pasarlas de funci�n a funci�n! */


int Largo, Alto;

/* * * * * Obtiene la copia de una imagen * * * * */


void Copia(unsigned char **Original, unsigned char **Salida){
int x, y;

for (x = 0; x < Largo; x++)


for (y = 0; y < Alto; y++)
Salida[x][y] = Original[x][y];

}
/* * * * * Obtiene el negativo de una imagen * * * * */
void Inverso(unsigned char **Original, unsigned char **Salida){
int x, y;

/* Resta el valor m�ximo (255) del valor actual de la imagen.


El resultado: el negativo de la imagen. */
/* Las matrices se accesan con los �ndices (x,y) */

for (x = 0; x < Largo; x++)


for (y = 0; y < Alto; y++)
Salida[x][y] = 255-Original[x][y];

}
void Umbral(unsigned char **Original, unsigned char **Salida, int p){
int x, y;

for (x = 0; x < Largo; x++)


for (y = 0; y < Alto; y++)
Salida[x][y] = (Original[x][y] == p ? 0 : 255);
}
void IntervaloUmbralBinario(unsigned char **Original, unsigned char
**Salida, int p1, int p2){
int x, y;

for (x = 0; x < Largo; x++)


for (y = 0; y < Alto; y++)
Salida[x][y] = (Original[x][y] <= p1 || Original[x][y] >= p2) ?
355 : 0;
}
void IntervaloUmbralBinarioInvertido(unsigned char **Original,
unsigned char **Salida, int p1, int p2){
int x, y;
for (x = 0; x < Largo; x++)
for (y = 0; y < Alto; y++)
Salida[x][y] = (Original[x][y] <= p1 || Original[x][y] >= p2) ?
0 : 255;
}
void IntervaloUmbralGrises(unsigned char **Original, unsigned char
**Salida, int p1, int p2){
int x, y;

for (x = 0; x < Largo; x++)


for (y = 0; y < Alto; y++)
Salida[x][y] = (Original[x][y] <= p1 || Original[x][y] >= p2) ?
255 : Original[x][y];
}
void IntervaloUmbralGrisesInvertido(unsigned char **Original, unsigned
char **Salida, int p1, int p2){
int x, y;

for (x = 0; x < Largo; x++)


for (y = 0; y < Alto; y++)
Salida[x][y] = (Original[x][y] <= p1 || Original[x][y] >= p2) ?
255 : 255-Original[x][y];
}
void Extension(unsigned char **Original, unsigned char **Salida, int
p1, int p2){
int x, y;

for (x = 0; x < Largo; x++)


for (y = 0; y < Alto; y++)
Salida[x][y] = (Original[x][y] <= p1 || Original[x][y] >= p2) ?
0 : ((Original[x][y]-p1)*((255)/p2-Original[x][y]));
}
void ReduccionNivelGris(unsigned char **Original, unsigned char
**Salida, int p1, int p2, int p3, int p4){
int x, y, p;

for (x = 0; x < Largo; x++)


for (y = 0; y < Alto; y++)
//Original[x][y] = (Salida[x][y] <= p1 || Salida[x][y] >= p2) ?
0 : ((p-p1)*((255)/p2-p));
if(Original[x][y] <= p1){
Salida[x][y] = 0;
}else if(p1 < Original[x][y] && Original[x][y] <=p2){
Salida[x][y] = p1;
}else if(p2 < Original[x][y] && Original[x][y] <=p3){
Salida[x][y] = p2;
}else if(p3 < Original[x][y] && Original[x][y] <=p4){
Salida[x][y] = p3;
}else{
Salida[x][y] = p4;
}
}
void histograma(unsigned char **Original){
int x, y, p;

for (x = 0; x < Largo; x++){


for (y = 0; y < Alto; y++){
printf("{%d}", Original[x][y]);
}
printf("\n");
}
}
void etiquetas(unsigned char **Original) {
int etiqueta = 1;
int etiquetas[MAX_ROWS * MAX_COLS] = {0}; // to keep track of
labels
int filas = Largo;
int cols = Alto;
for (int i = 0; i < filas; i++) {
for (int j = 0; j < cols; j++) {
if (Original[i][j] == 255) {
// check if any neighboring elements have been labeled
int top = (i == 0) ? 0 : Original[i-1][j];
int left = (j == 0) ? 0 : Original[i][j-1];
if (top == 0 && left == 0) {
// ni los elementos de arriba ni los de la
izquierda han sido etiquetados
Original[i][j] = etiqueta;
etiquetas[etiqueta] = etiqueta; // agregar
etiqueta a la lista de etiquetas
etiqueta++;
} else if (top > 0 && left == 0) {
// el elemento superior ha sido etiquetado, pero
el elemento izquierdo no
Original[i][j] = top;
} else if (top == 0 && left > 0) {
// el elemento izquierdo ha sido etiquetado, pero
el elemento superior no
Original[i][j] = left;
} else if (top > 0 && left > 0 && top != left) {
// ambos elementos, superior e izquierdo, han sido
etiquetados con diferentes etiquetas
// fusionar etiquetas
int min_label = (top < left) ? top : left;
int max_label = (top > left) ? top : left;
Original[i][j] = min_label;
etiquetas[max_label] = min_label;
} else {
// ambos elementos superior e izquierdo han sido
etiquetados con la misma etiqueta
Original[i][j] = top;
}
}
}
}

// relabel elements with minimum labels


for (int i = 0; i < filas; i++) {
for (int j = 0; j < cols; j++) {
if (Original[i][j] > 0) {
int min_label = etiquetas[Original[i][j]];
Original[i][j] = min_label;
}
}
}

for (int i = 0; i < Largo; i++) {


for (int j = 0; j < Alto; j++) {
printf("%d ", Original[i][j]);
}
printf("\n");
}
}
void suavizado(unsigned char **Original, unsigned char **Salida){
int submatriz[3][3]; // Declaración de la submatriz de 3x3
int sum = 0;

for (int i = 0; i < Largo - 2; i++) { // Recorrido de filas


for (int j = 0; j < Alto - 2; j++) { // Recorrido de columnas
// Construcción de la submatriz
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
submatriz[k][l] = Original[i+k][j+l];
}
}

// Cálculo de la suma de los valores de la submatriz


sum = 0;
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
sum += submatriz[k][l];
}
}

// Cálculo del promedio


Salida[i+1][j+1] = sum / 9;

// Impresión del promedio


//printf("El promedio de la submatriz de (%d,%d) a (%d,%d) es:
%f\n", i, j, i+2, j+2, promedios[m]);
}
}
}
void gx(unsigned char **Original, unsigned char **Salida){
int z[3][3]; // Declaración de la submatriz de 3x3

int sum = 0;

for (int i = 0; i < Largo - 2; i++) { // Recorrido de filas


for (int j = 0; j < Alto - 2; j++) { // Recorrido de columnas

// Construcción de la submatriz
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
z[k][l] = Original[i+k][j+l];
}
}

Salida[i+1][j+1] = (z[0][2] + 2*z[1][2] + z[2][2]) - (z[0][0] +


2*z[1][0] + z[2][0]);

// Impresión del promedio


//printf("El promedio de la submatriz de (%d,%d) a (%d,%d) es:
%f\n", i, j, i+2, j+2, promedios[m]);
}
}
}
void gy(unsigned char **Original, unsigned char **Salida){
int z[3][3]; // Declaración de la submatriz de 3x3

int sum = 0;

for (int i = 0; i < Largo - 2; i++) { // Recorrido de filas


for (int j = 0; j < Alto - 2; j++) { // Recorrido de columnas

// Construcción de la submatriz
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
z[k][l] = Original[i+k][j+l];
}
}
Salida[i+1][j+1] = (z[2][0] + 2*z[2][1] + z[2][2]) - (z[0][1] +
2*z[0][2] + z[0][3]);

// Impresión del promedio


//printf("El promedio de la submatriz de (%d,%d) a (%d,%d) es:
%f\n", i, j, i+2, j+2, promedios[m]);
}
}
}
void g(unsigned char **Original, unsigned char **Salida){
int z[3][3]; // Declaración de la submatriz de 3x3
int gx, gy;
int sum = 0;
for (int i = 0; i < Largo - 2; i++) { // Recorrido de filas
for (int j = 0; j < Alto - 2; j++) { // Recorrido de columnas

// Construcción de la submatriz
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
z[k][l] = Original[i+k][j+l];
}
}
gx = (z[0][2] + 2*z[1][2] + z[2][2]) - (z[0][0] + 2*z[1][0] +
z[2][0]);
gy = (z[2][0] + 2*z[2][1] + z[2][2]) - (z[0][1] + 2*z[0][2] +
z[0][3]);
Salida[i+1][j+1] = abs(gx) + abs(gy);

// Impresión del promedio


//printf("El promedio de la submatriz de (%d,%d) a (%d,%d) es:
%f\n", i, j, i+2, j+2, promedios[m]);
}
}
}

void prewitt(unsigned char **Original, unsigned char **Salida) {


int i, j, x, y, gx, gy;
int prewitt_x[3][3] = {{-1, 0, 1},{-1, 0, 1},{-1, 0, 1}};
int prewitt_y[3][3] = {{-1, -1, -1},{ 0, 0, 0},{ 1, 1, 1}};

for (i = 1; i < Largo - 1; i++) {


for (j = 1; j < Alto - 1; j++) {
gx = (prewitt_x[0][0] * Original[i-1][j-1]) +
(prewitt_x[0][1] * Original[i-1][j]) + (prewitt_x[0][2] * Original[i-
1][j+1]) + (prewitt_x[1][0] * Original[i][j-1]) + (prewitt_x[1][1] *
Original[i][j]) + (prewitt_x[1][2] * Original[i][j+1]) +
(prewitt_x[2][0] * Original[i+1][j-1]) + (prewitt_x[2][1] *
Original[i+1][j]) + (prewitt_x[2][2] * Original[i+1][j+1]);
gy = (prewitt_y[0][0] * Original[i-1][j-1]) +
(prewitt_y[0][1] * Original[i-1][j]) + (prewitt_y[0][2] * Original[i-
1][j+1]) + (prewitt_y[1][0] * Original[i][j-1]) + (prewitt_y[1][1] *
Original[i][j]) + (prewitt_y[1][2] * Original[i][j+1]) +
(prewitt_y[2][0] * Original[i+1][j-1]) + (prewitt_y[2][1] *
Original[i+1][j]) + (prewitt_y[2][2] * Original[i+1][j+1]);

Salida[i][j] = sqrt(gx * gx + gy * gy);


}
}
}

void roberts(unsigned char **Original, unsigned char **Salida) {


int i, j, x, y, sumx, sumy;
int roberts_x[2][2] = {{ 1, 0},{ 0, -1}};
int roberts_y[2][2] = {{ 0, 1},{-1, 0}};
for (i = 1; i < Largo - 1; i++) {
for (j = 1; j < Alto - 1; j++) {
sumx = 0;
sumy = 0;
for (y = 0; y <= 1; y++) {
for (x = 0; x <= 1; x++) {
sumx += Original[i + y][j + x] * roberts_x[y][x];
sumy += Original[i + y][j + x] * roberts_y[y][x];
}
}
Salida[i][j] = (unsigned char) sqrt(sumx * sumx + sumy *
sumy);
}
}
}
int menu(){
int op;
printf("\t.:Menu:.\n");
printf("1. Operador identidad (copia)\n");
printf("2. Operador inverso o negativo\n");
printf("3. Operador umbral\n");
printf("4. Operador intervalo de umbral binario\n");
printf("5. Operador intervalo de umbral invertido\n");
printf("6. Operador de umbral escala de grises\n");
printf("7. Operador umbral de escala de grises invertido\n");
printf("8. Operador de extension\n");
printf("9. Operador reduccion de nivel de gris\n");
printf("10. Histograma\n");
printf("11. formas\n");
printf("12. Suavizado de una imagen\n");
printf("13. Sobel\n");
printf("14. Prewitt\n");
printf("15. Roberts\n");
printf("-1. Salir\n");
printf("Opcion : ");
scanf("%d", &op);
return op;
}

/* * * * * * * * * * * * * * * * * * * */
int main(int argc, char *argv[]){
unsigned char **Original = (unsigned char **)pgmread(argv[1],
&Largo, &Alto);
unsigned char **Salida = (unsigned char **)Matriz(Largo, Alto,
sizeof(unsigned char));
unsigned char **Salida2 = (unsigned char **)Matriz(Largo+2, Alto+1,
sizeof(unsigned char));
int c;
int p, p1, p2, p3, p4;

system("clear");
switch (menu()){
case -1:
exit(1);
break;
case 1:
printf(" Salida->Copia de la imagen \n \n");
Copia(Original, Salida);
break;
case 2:
printf(" Salida->inverso de la imagen \n \n");
Inverso(Original, Salida);
break;
case 3:
printf("Escriba el valor de p: ");
scanf("%d",&p);
printf(" Salida->umbral de la imagen \n \n");
Umbral(Original, Salida, p);
break;
case 4:
printf("Escriba el valor de p1: ");
scanf("%d",&p1);
printf("Escriba el valor de p2: ");
scanf("%d",&p2);
printf(" Salida->umbral binario de la imagen \n \n");
IntervaloUmbralBinario(Original, Salida, p1,p2);
break;
case 5:
printf("Escriba el valor de p1: ");
scanf("%d",&p1);
printf("Escriba el valor de p2: ");
scanf("%d",&p2);
printf(" Salida->umbral invertido de la imagen \n \n");
IntervaloUmbralBinarioInvertido(Original, Salida, p1,p2);
break;
case 6:
printf("Escriba el valor de p1: ");
scanf("%d",&p1);
printf("Escriba el valor de p2: ");
scanf("%d",&p2);
printf(" Salida->umbral escala de grises de la imagen \n
\n");
IntervaloUmbralGrises(Original, Salida, p1, p2);
break;
case 7:
printf("Escriba el valor de p1: ");
scanf("%d",&p1);
printf("Escriba el valor de p2: ");
scanf("%d",&p2);
printf(" Salida->umbral escala de grises invertido de la
imagen \n \n");
IntervaloUmbralGrisesInvertido(Original, Salida, p1, p2);
break;
case 8:
printf("Escriba el valor de p1: ");
scanf("%d",&p1);
printf("Escriba el valor de p2: ");
scanf("%d",&p2);
printf(" Salida->extension de la imagen \n \n");
Extension(Original, Salida, p1, p2);
break;
case 9:
printf("Escriba el valor de p1: ");
scanf("%d",&p1);
printf("Escriba el valor de p2: ");
scanf("%d",&p2);
printf("Escriba el valor de p3: ");
scanf("%d",&p3);
printf("Escriba el valor de p4: ");
scanf("%d",&p4);
printf(" Salida->reduccion de nivel de gris de la imagen
\n \n");
ReduccionNivelGris(Original, Salida, p1, p2, p3, p4);
break;
case 10:
printf(" Salida->histograma de la imagen \n \n");
histograma(Original);
break;
case 11:
printf(" Salida->matriz xD \n \n");
etiquetas(Original);
break;
case 12:
printf(" Salida->suavizado de imagen");
suavizado(Original,Salida);
break;
case 13:
printf(" Salida->bordes de imagen");
gx(Original,Salida);
pgmwrite(Salida, "gx.pgm", Largo, Alto);
gy(Original,Salida);
pgmwrite(Salida, "gy.pgm", Largo, Alto);
g(Original,Salida);
pgmwrite(Salida, "g.pgm", Largo, Alto);
break;
case 14:
printf(" Salida->operador prewitt");
prewitt(Original,Salida);
break;
case 15:
printf(" Salida->operador de roberts");
roberts(Original,Salida);
break;
default:
printf("Ups... algo salio mal");
break;
}
pgmwrite(Salida, "imagen.pgm", Largo, Alto);
exit(0);
}

2. PGM
#include <stdlib.h>
#include <stdio.h>
/* Funciones:
float **Imagen = pgmread("imagen.pgm", &Largo, &Alto);

int pgmwrite(float **Imagen, "archivo.pgm", Largo, Alto);

float **Matriz(int, int, int);

float *Vector(int, int);


*/

extern int Largo, Alto;


unsigned char **pgmread();
float *Vector();
void **Matriz(int, int, int);
int pgmwrite();
int getint(FILE *);

void **Matriz(rows, columns, elem_size)


int rows; /* number of rows */
int columns; /* number of columns */
int elem_size; /* element size */
{
int row;
void **array = (void **)malloc(rows * sizeof(void *));

if (array == NULL)
printf("Error al asignar lineas a la matriz\n"), exit(0);

for (row = 0; row < rows; row++) {


array[row] = (void *)calloc(columns, elem_size);
if (array == NULL)
printf("Error al asignar columnas a la matriz\n"), exit(0);
}

return array;
}

float *Vector(int i0,int i1){


float *v ;
if ((v = (float *)calloc(i1-i0+1,sizeof (float))) == NULL)
printf("Error al asignar memoria al vector\n") ;
return v-i0 ;
}
int getint(FILE *fd){
int c, i;
char dummy[10000];

c = getc(fd);
while (1) /* find next integer */
{
if (c=='#') /* Descartar los comentarios */
fgets(dummy,9000,fd);
if (c==EOF){
return 0;
}
if (c>='0' && c<='9')
break; /* found what we were looking for */
c = getc(fd);
}

/* we're at the start of a number, continue until we hit a non-


number */
i = 0;
while (1) {
i = (i*10) + (c - '0');
c = getc(fd);
if (c==EOF) return (i);
if (c<'0' || c>'9') break;
}

return (i);
}

void Free(array, rows)


void **array; /* the two-dimensional array */
int rows; /* number of rows */
{
int row;
for (row = 0; row < rows; row++) {
free(array[row]);
}
}

unsigned char **pgmread(char *filename, int *x_size, int *y_size){


FILE *fd;
char header[100];
int tmp;
int x, y,c2, Contador=0;
unsigned char **Imagen;

if ((fd=fopen(filename,"rb")) == NULL){
printf("No puedo abrir %s para lectura!\n", filename);
exit(0);
}

/* Leyendo el encabezado */
header[0]=fgetc(fd);
header[1]=fgetc(fd);
if(!(header[0]=='P' && header[1]=='5')){
printf("Error al leer el archivo\nLa imagen %s no es un
PGM!\n",filename);
fclose(fd);
exit(0);
}

*x_size = getint(fd);
*y_size = getint(fd);
tmp = getint(fd);

Imagen = (unsigned char **)Matriz(*x_size, *y_size, sizeof(unsigned


char));

/* Toma la imagen del archivo */


for (y=0; y<*y_size; y++)
for (x=0; x<*x_size; x++, Contador++)
Imagen[x][y]=(unsigned char)fgetc(fd);

/* Verifico que se leyeron todos los bytes */


if (Contador != (*x_size * *y_size)){
printf("Archivo con longitud incorrecta!\n");
return 0;
}

fclose(fd);
printf("Cargando imagen %s\n", filename);
return Imagen;
}

int pgmwrite(unsigned char **Imagen, char *filename, int Largo, int


Alto){
FILE *Out;
int x, y, Contador=0;

if ((Out=fopen(filename,"wb")) == NULL){
printf("No puedo escribir la imagen!\n");
return 0;
}

/* Ponemos el encabezado de los PGM */


fprintf(Out,"P5\n");
fprintf(Out,"%d %d\n", Largo, Alto);
fprintf(Out,"255\n");

/* Vacio la imagen al archivo */


printf("****************************************************");
for (y=0; y<Alto; y++)
for (x=0; x<Largo; x++, Contador++)
putc(Imagen[x][y], Out);
/* Verifico que se escriban todos los bytes */
if (Contador != (Largo*Alto)){
printf("Archivo con longitud incorrecta!\n");
return 0;
}

fclose(Out);

printf("\nSalvando %s PGM de %ix%i\n", filename, Largo, Alto);


return 1;
}

3. Prewitt
import cv2

# Cargar la imagen
img = cv2.imread("h.jpg")

# Convertir a escala de grises


gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Aplicar umbralización para binarizar la imagen


_, binary = cv2.threshold(gray, 70, 255, cv2.THRESH_BINARY)

# Aplicar el filtro de Prewitt en las direcciones x e y


prewittx = cv2.Sobel(binary, cv2.CV_64F, 1, 0, ksize=3)
prewitty = cv2.Sobel(binary, cv2.CV_64F, 0, 1, ksize=3)

# Obtener la magnitud y dirección del gradiente


magnitude = cv2.magnitude(prewittx, prewitty)
direction = cv2.phase(prewittx, prewitty, angleInDegrees=True)

# Mostrar la imagen resultante


cv2.imshow("Prewitt", magnitude)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. Roberts
import cv2
import numpy as np

# Leer la imagen
img = cv2.imread("xd.jpg")

# Convertir a escala de grises


gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Binarizar la imagen con umbral T=70


T = 70
_, bin_img = cv2.threshold(gray, T, 255, cv2.THRESH_BINARY)

# Calcular los filtros de Roberts


robertsx = cv2.filter2D(bin_img, -1, np.array([[1, 0], [0, -1]]))
robertsy = cv2.filter2D(bin_img, -1, np.array([[0, 1], [-1, 0]]))

# Calcular la magnitud
magnitude = cv2.magnitude(robertsx.astype(np.float32),
robertsy.astype(np.float32))

# Mostrar la imagen resultante


cv2.imshow("Roberts", magnitude)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. Reconocimiento de matricular vehiculares.

Capturas de pantalla
1. Programas en C
PREWITT

ROBERTS
2. Programas en Python
PREWITT

ROBERTS
Referencias
http://mmartin.cs.buap.mx/notas/PDI-MM-Rev.2013.pdf
https://pythoneyes.wordpress.com/2017/07/28/filtros-para-la-deteccion-de-bordes-de-una-
imagen-con-python-3-parte-2/
https://www.boletin.upiita.ipn.mx/index.php/ciencia/669-cyt-numero-55/1293-extraccion-de-
bordes-operadores-sobel-prewitt-y-roberts
https://programmerclick.com/article/4091430424/
https://www.researchgate.net/profile/Noureddine-
Alaa/publication/349811111_Image_Processing_with_Python_An_Introduction/links/604213a4a6
fdcc9c78124c67/Image-Processing-with-Python-An-Introduction.pdf pag 62-66 recomendado

Video
https://youtu.be/ZhWV7hRbbMw

También podría gustarte