#include "header.h" #define TRACEM -1 #define TRACEN -1 /* Written by Justin Romberg, Waqas Akram, & Charles Gamiz, May 1997 */ /* OnEdge() takes a binary memberors map and two indices into the map. If the point corresponding to the indices is on an edge, then return true. */ int OnEdge(char **map, int m, int n) { /* debug */ if ((m == TRACEM) && (n == TRACEN)) { printf("%d %d %d\n",(int)map[m-1][n-1], (int)map[m-1][n],(int)map[m-1][n+1]); printf("%d * %d\n",(int)map[m][n-1],(int)map[m][n+1]); printf("%d %d %d\n",(int)map[m+1][n-1], (int)map[m+1][n],(int)map[m+1][n+1]); printf("\n"); } /* check for m well conditioned */ if (((m+1) < sizeI[0]) && ((m-1) >= 0)) { if (((n+1) < sizeI[1]) && ((n-1) >= 0)) { if (map[m+1][n+1] && map[m][n+1] && map[m-1][n+1] && map[m+1][n] && map[m-1][n] && map[m+1][n-1] && map[m][n-1] && map[m-1][n-1]) return 0; else return 1; } if ((n+1) >= sizeI[1]) { if (map[m+1][n] && map[m-1][n] && map[m+1][n-1] && map[m][n-1] && map[m-1][n-1]) return 0; else return 1; } if ((n-1) < 0) { if (map[m+1][n] && map[m-1][n] && map[m+1][n+1] && map[m][n+1] && map[m-1][n+1]) return 0; else return 1; } } /* check for m too far down */ if ((m+1) >= sizeI[0]) { if (((n+1) < sizeI[1]) && ((n-1) >= 0)) { if (map[m][n+1] && map[m][n-1] && map[m-1][n+1] && map[m-1][n] && map[m-1][n-1]) return 0; else return 1; } if ((n+1) >= sizeI[1]) { if (map[m][n-1] && map[m-1][n] && map[m-1][n-1]) return 0; else return 1; } if ((n-1) < 0) { if (map[m][n+1] && map[m-1][n+1] && map[m-1][n]) return 0; else return 1; } } /* check for m too far up */ if ((m-1) < 0) { if (((n+1) < sizeI[1]) && ((n-1) >= 0)) { if (map[m][n-1] && map[m][n+1] && map[m+1][n-1] && map[m+1][n] && map[m+1][n+1]) return 0; else return 1; } if ((n+1) >= sizeI[1]) { if (map[m][n-1] && map[m+1][n-1] && map[m+1][n]) return 0; else return 1; } if ((n-1) < 0) { if (map[m][n+1] && map[m+1][n+1] && map[m+1][n]) return 0; else return 1; } } return 1; } /* RemovePixel takes a pixel list and a pair of integers (which are indices). It finds the pixel in the list with these m,n values and removes it, deallocating its space. We know that mv, nv is not the first element in the list */ void RemovePixel(struct pixel *list, int mv, int nv) { struct pixel *temp, *temp2; temp = list; if ((mv == TRACEM) && (nv == TRACEN)) { printf("Removing %d, %d on pixel %d, %d.\n",TRACEM,TRACEN,list->m,list->n); } while ((temp != NULL)&&(!((temp->m == mv) && (temp->n == nv)))) { temp2 = temp; temp = temp->next; } /* remove the pixel from the list */ if (temp == NULL) return; temp2->next = temp->next; free(temp); } /* UpdateEdges look at every neighbor of the new pixel and sees if it is in the region. If it is, then it checks the neighbor to make sure that it is still on the edge. */ void UpdateEdges(struct region *reg, struct pixel *pix) { struct pixel *temp; struct pixel *newpix; /* add this pixel to the edge list */ if ((pix->m == TRACEM) && (pix->n == TRACEN)) printf("Adding %d, %d.\n", TRACEM, TRACEN); newpix = create_pixel(pix->m, pix->n); temp = reg->edge_list; reg->edge_list = newpix; newpix->next = temp; reg->num_edge++; /* check to the right */ if ((pix->n+1) < sizeI[1]) { /* right top */ if ((pix->m+1) < sizeI[0]) { if (reg->member[pix->m+1][pix->n+1]) { if (!OnEdge(reg->member, pix->m+1, pix->n+1)) RemovePixel(reg->edge_list, pix->m+1, pix->n+1); } } /* right middle */ if (reg->member[pix->m][pix->n+1]) { if (!OnEdge(reg->member, pix->m, pix->n+1)) RemovePixel(reg->edge_list, pix->m, pix->n+1); } /* right bottom */ if ((pix->m-1) >= 0) { if (reg->member[pix->m-1][pix->n+1]) { if (!OnEdge(reg->member, pix->m-1, pix->n+1)) RemovePixel(reg->edge_list, pix->m-1, pix->n+1); } } } /* check the middle */ /* middle top */ if ((pix->m+1) < sizeI[0]) { if (reg->member[pix->m+1][pix->n]) { if (!OnEdge(reg->member, pix->m+1, pix->n)) RemovePixel(reg->edge_list, pix->m+1, pix->n); } } /* middle bottom */ if ((pix->m-1) >= 0) { if (reg->member[pix->m-1][pix->n]) { if (!OnEdge(reg->member, pix->m-1, pix->n)) RemovePixel(reg->edge_list, pix->m-1, pix->n); } } /* check to the left */ if ((pix->n-1) >= 0) { /* left top */ if ((pix->m+1) < sizeI[0]) { if (reg->member[pix->m+1][pix->n-1]) { if (!OnEdge(reg->member, pix->m+1, pix->n-1)) RemovePixel(reg->edge_list, pix->m+1, pix->n-1); } } /* left middle */ if (reg->member[pix->m][pix->n-1]) { if (!OnEdge(reg->member, pix->m, pix->n-1)) RemovePixel(reg->edge_list, pix->m, pix->n-1); } /* left bottom */ if ((pix->m-1) >= 0) { if (reg->member[pix->m-1][pix->n-1]) { if (!OnEdge(reg->member, pix->m-1, pix->n-1)) RemovePixel(reg->edge_list, pix->m-1, pix->n-1); } } } } /* AddPixel() adds a pixel to the region. It also checks the pixels new * neighbors to see if they are edges. */ void AddPixel(struct region *reg, struct pixel *pix) { struct pixel *temp; double L; COUNT++; temp = reg->pixel_list; reg->pixel_list = pix; pix->next = temp; reg->num_pixels++; L = (double)reg->num_pixels; /* mark this spot in the members map */ reg->member[pix->m][pix->n] = 1; /* update the edge list. Add the new pixel and check neighbors */ UpdateEdges(reg,pix); /* calculate the mean and std */ reg->SumOfValues += (double)IMAGE[pix->m][pix->n]; reg->SumOfSquares += (double)(IMAGE[pix->m][pix->n] * IMAGE[pix->m][pix->n]); reg->mean = reg->SumOfValues/L; reg->std = sqrt((L*reg->SumOfSquares - (reg->SumOfValues*reg->SumOfValues))/ (L*(L-1))); } /* DumpRegion() is a debugging function that just dumps */ /* the pixel list to standard out. */ void DumpRegion(struct region *reg) { struct pixel *temp; printf("Total number of pixels is %d\n", reg->num_pixels); temp = reg->pixel_list; while(temp != NULL) { printf("%d %d\n", temp->m, temp->n); temp = temp->next; } }