/* * prealign.c * * Rough initial alignment of images * * (c) 2007 Thomas White * * dtr - Diffraction Tomography Reconstruction * */ #include #include #include #include #include "control.h" #include "imagedisplay.h" #include "main.h" typedef struct { int n; ControlContext *ctx; ImageDisplay *id; } PreAlignBlock; static gint prealign_clicked(GtkWidget *widget, GdkEventButton *event, PreAlignBlock *pb) { double xoffs, yoffs, scale; double x, y; x = event->x; y = event->y; xoffs = (pb->id->drawingarea_width - pb->id->view_width) / 2; yoffs = (pb->id->drawingarea_height - pb->id->view_height) / 2; scale = (double)pb->id->view_width/pb->id->imagerecord.width; x -= xoffs; y -= yoffs; x /= scale; y /= scale; y = pb->id->imagerecord.height - y; pb->ctx->images[pb->n].x_centre = x; pb->ctx->images[pb->n].y_centre = y; pb->n++; if ( pb->n >= pb->ctx->n_images ) { /* Finished */ imagedisplay_close(pb->id); main_do_reconstruction(pb->ctx); free(pb); } else { /* Display the next pattern */ imagedisplay_put_data(pb->id, pb->ctx->images[pb->n]); } return 0; } /* No peak-detection nor 3D mapping has been done yet. Ask the user to give a rough idea (i.e. as accurately as possible...) of the centre of each image. */ void prealign_do_series(ControlContext *ctx) { PreAlignBlock *pb; ctx->have_centres = 1; /* Inhibit "centre-finding by stacking" */ pb = malloc(sizeof(PreAlignBlock)); pb->n = 0; pb->ctx = ctx; pb->id = imagedisplay_open_with_message(ctx->images[pb->n], "Image Pre-alignment", "Click the centre of the zero-order beam as accurately as you can.", IMAGEDISPLAY_QUIT_IF_CLOSED, G_CALLBACK(prealign_clicked), pb); } void prealign_sum_stack(ControlContext *ctx) { int twidth, theight; int mnorth, msouth, mwest, meast; int x, y, i; uint16_t *image_total; ImageDisplay *sum_id; ImageRecord total_record; /* Determine maximum size of image to accommodate, and allocate memory */ mnorth = 0; msouth = 0; mwest = 0; meast = 0; for ( i=0; in_images; i++ ) { if ( ctx->images[i].width-ctx->images[i].x_centre > meast ) meast = ctx->images[i].width-ctx->images[i].x_centre; if ( ctx->images[i].x_centre > mwest ) mwest = ctx->images[i].x_centre; if ( ctx->images[i].height-ctx->images[i].y_centre > mnorth ) mnorth = ctx->images[i].height-ctx->images[i].y_centre; if ( ctx->images[i].y_centre > msouth ) msouth = ctx->images[i].y_centre; } twidth = mwest + meast; theight = mnorth + msouth; image_total = malloc(twidth * theight * sizeof(uint16_t)); memset(image_total, 0, twidth * theight * sizeof(uint16_t)); /* Add the image stack together */ if ( !ctx->have_centres ) { int max_x, max_y; uint16_t max_val; for ( i=0; in_images; i++ ) { int xoffs, yoffs; xoffs = (twidth - ctx->images[i].width)/2; yoffs = (theight - ctx->images[i].height)/2; for ( y=0; yimages[i].height; y++ ) { for ( x=0; ximages[i].width; x++ ) { assert(x+xoffs < twidth); assert(y+yoffs < theight); assert(x+xoffs >= 0); assert(y+yoffs >= 0); image_total[(x+xoffs) + twidth*(y+yoffs)] += ctx->images[i].image[x + ctx->images[i].width*y]/ctx->n_images; } } } /* Locate the highest point */ max_val = 0; max_x = 0; max_y = 0; for ( y=0; y max_val ) { max_val = image_total[x + twidth*y]; max_x = x; max_y = y; } } } /* Record this measurement on all images */ for ( i=0; in_images; i++ ) { ctx->images[i].x_centre = max_x; ctx->images[i].y_centre = max_y; } total_record.x_centre = max_x; total_record.y_centre = max_y; } else { for ( i=0; in_images; i++ ) { int xoffs, yoffs; xoffs = mwest - ctx->images[i].x_centre; yoffs = msouth - ctx->images[i].y_centre; for ( y=0; yimages[i].height; y++ ) { for ( x=0; ximages[i].width; x++ ) { assert(x+xoffs < twidth); assert(y+yoffs < theight); assert(x+xoffs >= 0); assert(y+yoffs >= 0); image_total[(x+xoffs) + twidth*(y+yoffs)] += ctx->images[i].image[x + ctx->images[i].width*y]/ctx->n_images; } } } total_record.x_centre = mwest; total_record.y_centre = msouth; } /* Display */ total_record.image = image_total; total_record.width = twidth; total_record.height = theight; total_record.omega = ctx->omega; sum_id = imagedisplay_open(total_record, "Sum of All Images", IMAGEDISPLAY_SHOW_CENTRE | IMAGEDISPLAY_SHOW_TILT_AXIS); }