/* * Segment a graph * * Returns a disjoint-set forest representing the segmentation. * * num_vertices: number of vertices in graph. * num_edges: number of edges in graph * edges: array of edges. * c: constant for treshold function. */ universe *segment_graph(int num_vertices, int num_edges, edge *edges, float c) { // sort edges by weight std::sort(edges, edges + num_edges); // make a disjoint-set forest universe *u = new universe(num_vertices); // init thresholds float *threshold = new float[num_vertices]; for (int i = 0; i < num_vertices; i++) threshold[i] = THRESHOLD(1,c); // for each edge, in non-decreasing weight order... for (int i = 0; i < num_edges; i++) { edge *pedge = &edges[i]; // components conected by this edge int a = u->find(pedge->a); int b = u->find(pedge->b); if (a != b) { if ((pedge->w <= threshold[a]) && (pedge->w <= threshold[b])) { u->join(a, b); a = u->find(a); threshold[a] = pedge->w + THRESHOLD(u->size(a), c); } } } // free up delete threshold; return u; }
static enumButton_t decodeLCDButton(uint16_t adcVal) { #define RATIO_0 /* RIGHT */ 0.0 #define RATIO_1 /* UP */ (330.0/(330.0+2000.0)) #define RATIO_2 /* DOWN */ ((330.0+620.0)/(330.0+620.0+2000.0)) #define RATIO_3 /* LEFT */ ((330.0+620.0+1000.0)/(330.0+620.0+1000.0+2000.0)) #define RATIO_4 /* SELECT */ ((330.0+620.0+1000.0+3300.0)/(330.0+620.0+1000.0+3300.0+2000.0)) #define RATIO_5 /* NONE */ 1.0 #define THRESHOLD(n,n1) (uint16_t)(((RATIO_##n1 + RATIO_##n) / 2.0) \ * ADC_NO_AVERAGED_SAMPLES * 0x0400ul) if(adcVal > THRESHOLD(4,5)) return btnNone; else if(adcVal > THRESHOLD(3,4)) return btnSelect; else if(adcVal > THRESHOLD(2,3)) return btnLeft; else if(adcVal > THRESHOLD(1,2)) return btnDown; else if(adcVal > THRESHOLD(0,1)) return btnUp; else return btnRight; #undef RATIO_0 #undef RATIO_1 #undef RATIO_2 #undef RATIO_3 #undef RATIO_4 #undef RATIO_5 #undef THRESHOLD } /* End of decodeLCDButton */
/* * Segment a graph * * Returns a disjoint-set forest representing the segmentation. * * num_vertices: number of vertices in graph. * num_edges: number of edges in graph * edges: array of edges. * c: constant for treshold function. */ void segment::segment_graph(universe &u, int num_vertices, int num_edges, std::vector<edge> edges, double c) { int i, a, b; // sort edges by weight std::sort(edges.begin(), edges.begin()+num_edges); // init thresholds std::vector<double> threshold; for (i = 0; i < num_vertices; i++) threshold.push_back( THRESHOLD(1,c) ); // for each edge, in non-decreasing weight order... for (i = 0; i < num_edges; i++) { edge *pedge = &edges[i]; // components conected by this edge a = u.find(pedge->a); b = u.find(pedge->b); if( a==b ) continue; if ((pedge->w <= threshold[a]) && (pedge->w <= threshold[b])) { u.join(a, b); a = u.find(a); threshold[a] = pedge->w + THRESHOLD(u.size(a), c); } } }
Map* map_create(size_t initial_capacity, uint64_t(*hash)(void*), bool(*equals)(void*,void*), void* pool) { if(!equals) equals = map_uint64_equals; if(!hash) hash = map_uint64_hash; size_t capacity = 1; while(capacity < initial_capacity) capacity <<= 1; Map* map = __malloc(sizeof(Map), pool); if(!map) return NULL; map->table = __malloc(sizeof(List*) * capacity, pool); if(!map->table) { __free(map, pool); return NULL; } memset(map->table, 0x0, sizeof(List*) * capacity); map->capacity = capacity; map->threshold = THRESHOLD(capacity); map->size = 0; map->hash = hash; map->equals = equals; map->pool = pool; return map; }
int hm_set ( hashmap_t *hm, char *key, void *value ) { int hashed; int count = 0; int rtn; bucket_t *b_ptr; entry_t *e_ptr; if ( ( hm->size + 1 ) >= THRESHOLD ( hm->capacity ) ) rehash ( hm ); hashed = hashstr ( hm, key ); if ( hm->buckets[ hashed ] == NULL ) { /* No bucket. */ b_ptr = malloc ( sizeof ( bucket_t ) ); e_ptr = b_ptr->entries; } else if ( b_ptr != NULL ) { /* Bucket exists. */ if ( b_ptr->numentries >= BUCKETTHOLD ) rehash ( hm ); for ( ; ( e_ptr = b_ptr->entries->next ) != NULL ; ) { if ( strcmp ( e_ptr->key, key ) != 0 ) return 1; } e_ptr = e_ptr->next; } e_ptr = calloc ( 1, sizeof ( entry_t ) ); if ( e_ptr == NULL ) return 2; e_ptr->key = calloc ( strlen( key ) + 1, sizeof( char * ) ); if ( e_ptr->key == NULL ) return 3; strncpy( e_ptr->key, key, strlen( key ) ); e_ptr->value = value; b_ptr->numentries++; b_ptr->entries = e_ptr; hm->buckets[ hashed ] = b_ptr; hm->size++; }
// Roberts edge detector // inputs: // float *input - pointer to input image // int w, int h - width and height of input image // float threshold - threshold of edge detection // int padding_method - padding method for convolution // output: // float * - pointer to output image float *edges_roberts(float *im, int w, int h, float threshold, int padding_method) { // Define operators // 3x3 operators are used (although it is unnecessary) in order to // simplify the convolution application, and also to unify the three // detectors of the first family. float roberts_1[9] = {-1, 0, 0, 0, 1, 0, 0, 0, 0}; // ROBERTS float roberts_2[9] = { 0,-1, 0, 1, 0, 0, 0, 0, 0}; // OPERATORS for(int z=0; z<9; z++) { // normalization roberts_1[z] /= 2.0; roberts_2[z] /= 2.0; } // Convolution with operators float *Gx = conv2d(im, w, h, roberts_1, 3, padding_method); float *Gy = conv2d(im, w, h, roberts_2, 3, padding_method); // Allocate memory for output image float *im_roberts = xmalloc(w*h*sizeof(float)); // Two images are obtained (one for each operator). Then the gradient // magnitude image is constructed using sqrt(g_x^2+g_y^2). Also // the absolute maximum value of the constructed images is computed float max = 0.0; for(int i=0; i<w; i++) { for(int j=0; j<h; j++) { float gx = Gx[i+1 + (j+1)*(w+2)]; // Gx and Gy are (w+2) x (h+2) float gy = Gy[i+1 + (j+1)*(w+2)]; // there is an (+1,+1) offset im_roberts[i+j*w] = sqrt(gx*gx + gy*gy); max = MAX(max, im_roberts[i+j*w]); } } // Threshold for(int i=0; i<w*h; i++) { im_roberts[i] = THRESHOLD(im_roberts[i], threshold*max); } // Free memory free(Gx); free(Gy); return im_roberts; }
// Sobel edge detector // inputs: // float *input - pointer to input image // int w, int h - width and height of input image // float threshold - threshold of edge detection // int padding_method - padding method for convolution // output: // float * - pointer to output image float *edges_sobel(float *im, int w, int h, float threshold, int padding_method) { // Define operators float sobel_1[9] = {-1,-2,-1, 0, 0, 0, 1, 2, 1}; // SOBEL float sobel_2[9] = {-1, 0, 1,-2, 0, 2,-1, 0, 1}; // OPERATORS for(int z=0; z<9; z++) { // normalization sobel_1[z] /= 8.0; sobel_2[z] /= 8.0; } // Convolution with operators float *Gx = conv2d(im, w, h, sobel_1, 3, padding_method); float *Gy = conv2d(im, w, h, sobel_2, 3, padding_method); // Allocate memory for output image float *im_sobel = xmalloc(w*h*sizeof(float)); // Two images are obtained (one for each operator). Then the gradient // magnitude image is constructed using sqrt(g_x^2+g_y^2). Also // the absolute maximum value of the constructed images is computed float max = 0.0; for(int i=0; i<w; i++) { for(int j=0; j<h; j++) { float gx = Gx[i+1 + (j+1)*(w+2)]; // Gx and Gy are (w+2) x (h+2) float gy = Gy[i+1 + (j+1)*(w+2)]; // there is an (+1,+1) offset im_sobel[i+j*w] = sqrt(gx*gx + gy*gy); max = MAX(max, im_sobel[i+j*w]); } } // Threshold for(int i=0; i<w*h; i++) { im_sobel[i] = THRESHOLD(im_sobel[i], threshold*max); } // Free memory free(Gx); free(Gy); return im_sobel; }
bool map_put(Map* map, void* key, void* data) { if(map->size + 1 > map->threshold) { // Create new map Map map2; size_t capacity = map->capacity * 2; map2.table = __malloc(sizeof(List*) * capacity, map->pool); if(!map2.table) return false; memset(map2.table, 0x0, sizeof(List*) * capacity); map2.capacity = capacity; map2.threshold = THRESHOLD(capacity); map2.size = 0; map2.hash = map->hash; map2.equals = map->equals; map2.pool = map->pool; // Copy MapIterator iter; map_iterator_init(&iter, map); while(map_iterator_has_next(&iter)) { MapEntry* entry = map_iterator_next(&iter); if(!map_put(&map2, entry->key, entry->data)) { destroy(&map2); return false; } } // Destory destroy(map); // Paste memcpy(map, &map2, sizeof(Map)); } size_t index = map->hash(key) % map->capacity; if(!map->table[index]) { map->table[index] = list_create(map->pool); if(!map->table[index]) return false; } else { size_t size = list_size(map->table[index]); for(size_t i = 0; i < size; i++) { MapEntry* entry = list_get(map->table[index], i); if(map->equals(entry->key, key)) return false; } } MapEntry* entry = __malloc(sizeof(MapEntry), map->pool); if(!entry) { if(list_is_empty(map->table[index])) { list_destroy(map->table[index]); map->table[index] = NULL; } return false; } entry->key = key; entry->data = data; if(!list_add(map->table[index], entry)) { __free(entry, map->pool); if(list_is_empty(map->table[index])) { list_destroy(map->table[index]); map->table[index] = NULL; } return false; } map->size++; return true; }
// Software Guide : BeginLatex // \vspace{0.5cm} // \Large{Main function} \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet int main(int argc, char *argv[]) { // Software Guide : EndCodeSnippet if (argc != 4) { printf("Usage: %s input_image threshold padding_method\n", argv[0]); } else { // Execution time: double start = (double)clock(); // Load input image (using iio) // Software Guide : BeginLatex // Load input image (using \textit{iio}): \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet int w, h, pixeldim; float *im_orig = iio_read_image_float_vec(argv[1], &w, &h, &pixeldim); // Software Guide : EndCodeSnippet fprintf(stderr, "Input image loaded:\t %dx%d image with %d channel(s).\n", w, h, pixeldim); // Grayscale conversion (if necessary) // Software Guide : BeginLatex // Grayscale conversion (if necessary): explained in \ref{sec:grayscale}. \\ \\ // Software Guide : EndLatex double *im = malloc(w*h*sizeof(double)); if (im == NULL){ fprintf(stderr, "Out of memory...\n"); exit(EXIT_FAILURE); } // allocate memory for the grayscale image <im>, output of the grayscale conversion // and correct allocation check. int z; // <z> is just an integer used as array index. int zmax = w*h; // number of elements of <im> if (pixeldim==3){ // if the image is color (RGB, three channels)... for(z=0;z<zmax;z++){ // for each pixel in the image <im>, calculate the gray // value according to the expression: // I = ( 6968*R + 23434*G + 2366*B ) / 32768. im[z] = (double)(6968*im_orig[3*z] + 23434*im_orig[3*z + 1] + 2366*im_orig[3*z + 2])/32768; } fprintf(stderr, "images converted to grayscale\n"); } else { // the image was originally grayscale... for(z=0;z<zmax;z++){ im[z] = (double)im_orig[z]; // only assign the value of im_orig to im, casting to double. } fprintf(stderr, "images are already in grayscale\n"); } // Define operators: // Software Guide : BeginLatex // Define the normalized Roberts, Prewitt and Sobel operators: \\ // (We use $3\times 3$ operators) // \begin{itemize} // \item Roberts: // $$ // R_1 = \begin{bmatrix} -1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 0 \end{bmatrix} // $$ // $$ // R_2 = \begin{bmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 0 \end{bmatrix} // $$ // \item Prewitt: // $$ // P_1 = \begin{bmatrix} \frac{-1}{6} & \frac{-1}{6} & \frac{-1}{6} \\ 0 & 0 & 0 \\ \frac{1}{6} & \frac{1}{6} & \frac{1}{6} \end{bmatrix} // $$ // $$ // P_2 = \begin{bmatrix} \frac{-1}{6} & 0 & \frac{1}{6} \\ \frac{-1}{6} & 0 & \frac{1}{6} \\ \frac{-1}{6} & 0 & \frac{1}{6} \end{bmatrix} // $$ // \item Sobel: // $$ // S_1 = \begin{bmatrix} \frac{-1}{8} & \frac{-1}{4} & \frac{-1}{8} \\ 0 & 0 & 0 \\ \frac{1}{8} & \frac{1}{4} & \frac{1}{8} \end{bmatrix} // $$ // $$ // S_2 = \begin{bmatrix} \frac{-1}{8} & 0 & \frac{1}{8} \\ \frac{-1}{4} & 0 & \frac{1}{4} \\ \frac{-1}{8} & 0 & \frac{1}{8} \end{bmatrix} // $$ // \end{itemize} // Software Guide : EndLatex // Software Guide : BeginCodeSnippet double roberts_1[9] = {-1, 0, 0, 0, 1, 0, 0, 0, 0}; // ROBERTS double roberts_2[9] = { 0,-1, 0, 1, 0, 0, 0, 0, 0}; // OPERATORS //--------------------------------------------------------------------------------- double prewitt_1[9] = {-1,-1,-1, 0, 0, 0, 1, 1, 1}; // PREWITT double prewitt_2[9] = {-1, 0, 1,-1, 0, 1,-1, 0, 1}; // OPERATORS //--------------------------------------------------------------------------------- double sobel_1[9] = {-1,-2,-1, 0, 0, 0, 1, 2, 1}; // SOBEL double sobel_2[9] = {-1, 0, 1,-2, 0, 2,-1, 0, 1}; // OPERATORS //--------------------------------------------------------------------------------- for (z=0;z<9;z++) { // NORMALIZATION //roberts_1[z] /= 1; //roberts_2[z] /= 1; prewitt_1[z] /= 6; prewitt_2[z] /= 6; sobel_1[z] /= 8; sobel_2[z] /= 8; } // Software Guide : EndCodeSnippet // Convolve images: // Software Guide : BeginLatex // The input image is convolved with the defined operatos, using the \texttt{conv2d} function in \texttt{2dconvolution.c}: // Software Guide : EndLatex // Software Guide : BeginCodeSnippet int padding_method = atoi(argv[3]); double *im_r1 = conv2d(im, w, h, roberts_1, 3, padding_method); double *im_r2 = conv2d(im, w, h, roberts_2, 3, padding_method); double *im_p1 = conv2d(im, w, h, prewitt_1, 3, padding_method); double *im_p2 = conv2d(im, w, h, prewitt_2, 3, padding_method); double *im_s1 = conv2d(im, w, h, sobel_1, 3, padding_method); double *im_s2 = conv2d(im, w, h, sobel_2, 3, padding_method); // Software Guide : EndCodeSnippet // Allocate memory for final images: // Software Guide : BeginLatex // Allocate memory for final images: // Software Guide : EndLatex // Software Guide : BeginCodeSnippet float *im_roberts = malloc(w*h*sizeof(float)); float *im_prewitt = malloc(w*h*sizeof(float)); float *im_sobel = malloc(w*h*sizeof(float)); // Software Guide : EndCodeSnippet // Software Guide : BeginLatex // For each method, two images are obtained (one for each operator). Then the gradient magnitude image is constructed using $M=\sqrt{g_x^2+g_y^2}$. \\ // Also the absolute maximum value of the constructed images is computed, for each method. \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet int i,j, fila, col; double max_r = 0; double max_p = 0; double max_s = 0; int imax = w*h; for (i=0;i<imax;i++){ fila = (int)(i/w); col = i - w*fila + 1; fila += 1; j = col + (w+2)*fila; // Max in each case im_roberts[i] = sqrt(im_r1[j]*im_r1[j] + im_r2[j]*im_r2[j]); im_prewitt[i] = sqrt(im_p1[j]*im_p1[j] + im_p2[j]*im_p2[j]); im_sobel[i] = sqrt(im_s1[j]*im_s1[j] + im_s2[j]*im_s2[j]); // Absolute max max_r = MAX(max_r,im_roberts[i]); max_p = MAX(max_p,im_prewitt[i]); max_s = MAX(max_s,im_sobel[i]); } // Software Guide : EndCodeSnippet // Thresholding // Software Guide : BeginLatex // Thresholded images of each method are created, using the THRESHOLD macro: \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet float th = atof(argv[2]); for (i=0;i<imax;i++){ im_roberts[i] = THRESHOLD(im_roberts[i],th*max_r); im_prewitt[i] = THRESHOLD(im_prewitt[i],th*max_p); im_sobel[i] = THRESHOLD(im_sobel[i],th*max_s); } // Software Guide : EndCodeSnippet // Save outout images // Software Guide : BeginLatex // Save output image (using \textit{iio}): \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet iio_save_image_float_vec("roberts.png", im_roberts, w, h, 1); iio_save_image_float_vec("prewitt.png", im_prewitt, w, h, 1); iio_save_image_float_vec("sobel.png", im_sobel, w, h, 1); // Software Guide : EndCodeSnippet fprintf(stderr, "Roberts image saved to roberts.png.\n"); fprintf(stderr, "Prewitt image saved to prewitt.png.\n"); fprintf(stderr, "Sobel image saved to sobel.png.\n"); // Free memory: free(im_orig); free(im); free(im_r1); free(im_r2); free(im_p1); free(im_p2); free(im_s1); free(im_s2); free(im_roberts); free(im_prewitt); free(im_sobel); fprintf(stderr, "Edge detection algorithms based on first derivative computation done.\n"); // Execution time: double finish = (double)clock(); double exectime = (finish - start)/CLOCKS_PER_SEC; fprintf(stderr, "execution time: %1.3f s.\n", exectime); return 0; } // else (argc) } // end of the program