int main(int argc, char **argv) { char out_name[BUF_SIZE], chan_str[BUF_SIZE]; Image im, desc, chan; SIFT3D sift3d; char *in_path, *out_path, *marker; size_t len; int c, marker_pos; /* Parse the GNU standard options */ switch (parse_gnu(argc, argv)) { case SIFT3D_HELP: puts(help_msg); return 0; case SIFT3D_VERSION: return 0; } /* Parse the arguments */ if (argc < 3) { err_msg("Not enough arguments."); return 1; } else if (argc > 3) { err_msg("Too many arguments."); return 1; } in_path = argv[1]; out_path = argv[2]; /* Initialize data */ init_im(&im); init_im(&desc); init_im(&chan); if (init_SIFT3D(&sift3d)) { err_msgu("Failed to initialize SIFT3D data."); return 1; } /* Read the image */ if (read_nii(in_path, &im)) { char msg[BUF_SIZE]; sprintf(msg, "Failed to read input image \"%s\".", in_path); err_msg(msg); return 1; } /* Ensure the output file name has a % character */ if ((marker = strrchr(out_path, '%')) == NULL) { err_msg("output filename must contain '%'."); return 1; } marker_pos = marker - out_path; /* Get the output file name length */ len = strlen(out_path) + (int) ceil(log10((double) im.nc)) - 1; if (len > BUF_SIZE) { char msg[BUF_SIZE]; sprintf(msg, "Ouput filename cannot exceed %d characters.", BUF_SIZE); err_msg(msg); return 1; } /* Extract the descriptors */ if (SIFT3D_extract_dense_descriptors(&sift3d, &im, &desc)) { err_msgu("Failed to extract descriptors."); return 1; } /* Write each channel as a separate image */ for (c = 0; c < desc.nc; c++) { /* Get the channel */ if (im_channel(&desc, &chan, c)) { err_msgu("Failed to extract the channel."); return 1; } /* Form the output file name */ out_name[0] = '\0'; sprintf(chan_str, "%d", c); strncat(out_name, out_path, marker_pos); strcat(out_name, chan_str); strcat(out_name, marker + 1); /* Write the channel */ if (write_nii(out_name, &chan)) { char msg[BUF_SIZE]; sprintf(msg, "Failed to write output image \"%s\".", out_name); err_msg(msg); return 1; } } return 0; }
int main(int argc, char *argv[]) { SIFT3D sift3d; Reg_SIFT3D reg; Image src, ref; Mat_rm match_src, match_ref; void *tform, *tform_arg; char *src_path, *ref_path, *warped_path, *match_path, *tform_path, *concat_path, *keys_path, *lines_path; tform_type type; double thresh; int num_args, c, have_match, have_tform; const struct option longopts[] = { {"matches", required_argument, NULL, MATCHES}, {"transform", required_argument, NULL, TRANSFORM}, {"warped", required_argument, NULL, WARPED}, {"concat", required_argument, NULL, CONCAT}, {"keys", required_argument, NULL, KEYS}, {"lines", required_argument, NULL, LINES}, {"thresh", required_argument, NULL, THRESH}, {"type", required_argument, NULL, TYPE}, {0, 0, 0, 0} }; const char str_affine[] = "affine"; SIFT3D_Descriptor_store *const desc_src = ®.desc_src; SIFT3D_Descriptor_store *const desc_ref = ®.desc_ref; // Parse the GNU standard options switch (parse_gnu(argc, argv)) { case SIFT3D_HELP: puts(help_msg); print_opts_SIFT3D(); return 0; case SIFT3D_VERSION: return 0; case SIFT3D_FALSE: break; default: err_msgu("Unexpected return from parse_gnu \n"); return 1; } // Initialize the data init_im(&src); init_im(&ref); init_Reg_SIFT3D(®); init_SIFT3D(&sift3d); if (init_Mat_rm(&match_src, 0, 0, DOUBLE, SIFT3D_FALSE) || init_Mat_rm(&match_ref, 0, 0, DOUBLE, SIFT3D_FALSE)) { err_msgu("Failed basic initialization."); return 1; } // Initialize parameters to defaults type = type_default; // Parse the SIFT3D options if ((argc = parse_args_SIFT3D(&sift3d, argc, argv, SIFT3D_FALSE)) < 0) return 1; set_SIFT3D_Reg_SIFT3D(®, &sift3d); // Parse the remaining options opterr = 1; have_match = have_tform = SIFT3D_FALSE; match_path = tform_path = warped_path = concat_path = keys_path = lines_path = NULL; while ((c = getopt_long(argc, argv, "", longopts, NULL)) != -1) { switch (c) { case MATCHES: match_path = optarg; have_match = SIFT3D_TRUE; break; case TRANSFORM: tform_path = optarg; have_tform = SIFT3D_TRUE; break; case WARPED: warped_path = optarg; have_tform = SIFT3D_TRUE; break; case CONCAT: concat_path = optarg; have_match = SIFT3D_TRUE; break; case KEYS: keys_path = optarg; have_match = SIFT3D_TRUE; break; case LINES: lines_path = optarg; have_match = SIFT3D_TRUE; break; case THRESH: thresh = atof(optarg); if (set_nn_thresh_Reg_SIFT3D(®, thresh)) { err_msg("Invalid value for thresh."); return 1; } break; case TYPE: if (!strcmp(optarg, str_affine)) { type = AFFINE; } else { char msg[1024]; sprintf(msg, "Unrecognized transformation " "type: %s\n", optarg); err_msg(msg); return 1; } break; case '?': default: return 1; } } // Ensure that at least one output was specified if (!have_match && !have_tform) { err_msg("No outputs were specified."); return 1; } // Parse the required arguments num_args = argc - optind; if (num_args < 2) { err_msg("Not enough arguments."); return 1; } else if (num_args > 2) { err_msg("Too many arguments."); return 1; } src_path = argv[optind]; ref_path = argv[optind + 1]; // Allocate memory for the transformation if ((tform = malloc(tform_type_get_size(type))) == NULL) { err_msg("Out of memory."); return 1; } // Initialize the transformation if (init_tform(tform, type)) return 1; // Read the images if (read_nii(src_path, &src)) { char msg[1024]; sprintf(msg, "Failed to read the source image \"%s\"", src_path); err_msg(msg); return 1; } if (read_nii(ref_path, &ref)) { char msg[1024]; sprintf(msg, "Failed to read the reference image \"%s\"", ref_path); err_msg(msg); return 1; } // Set the images if (set_src_Reg_SIFT3D(®, &src)) { err_msgu("Failed to set the source image."); return 1; } if (set_ref_Reg_SIFT3D(®, &ref)) { err_msgu("Failed to set the reference image."); return 1; } // Match the features, optionally registering the images tform_arg = have_tform ? tform : NULL; if (register_SIFT3D(®, tform_arg)) { err_msgu("Failed to register the images."); return 1; } // Convert the matches to matrices if (get_matches_Reg_SIFT3D(®, &match_src, &match_ref)) { err_msgu("Failed to convert matches to coordinates."); return 1; } // Write the outputs if (match_path != NULL) { Mat_rm matches; int i, j; // Initialize intermediates init_Mat_rm(&matches, 0, 0, DOUBLE, SIFT3D_FALSE); // Form a combined matrix for both sets of matches if (concat_Mat_rm(&match_src, &match_ref, &matches, 1)) { err_msgu("Failed to concatenate the matches."); return 1; } if (write_Mat_rm(match_path, &matches)) { char msg[1024]; sprintf(msg, "Failed to write the matches \"%s\"", match_path); err_msg(msg); return 1; } // Clean up cleanup_Mat_rm(&matches); } if (tform_path != NULL && write_tform(tform_path, tform)) { char msg[1024]; sprintf(msg, "Failed to write the transformation parameters " "\"%s\"", tform_path); err_msg(msg); return 1; } // Optionally warp the source image if (warped_path != NULL) { Image warped; // Initialize intermediates init_im(&warped); // Warp if (im_inv_transform(tform, &src, &warped, interp)) { err_msgu("Failed to warp the source image."); return 1; } // Write the warped image if (write_nii(warped_path, &warped)) { char msg[1024]; sprintf(msg, "Failed to write the warped image \"%s\"", warped_path); err_msg(msg); return 1; } // Clean up im_free(&warped); } // Optionally draw the matches if (concat_path != NULL || keys_path != NULL || lines_path != NULL) { Image concat, keys, lines; Mat_rm keys_src, keys_ref; Image *concat_arg, *keys_arg, *lines_arg; // Initialize intermediates init_im(&concat); init_im(&keys); init_im(&lines); if (init_Mat_rm(&keys_src, 0, 0, DOUBLE, SIFT3D_FALSE) || init_Mat_rm(&keys_ref, 0, 0, DOUBLE, SIFT3D_FALSE)) { err_msgu("Failed to initialize keypoint matrices."); return 1; } // Set up the pointers for the images concat_arg = concat_path == NULL ? NULL : &concat; keys_arg = keys_path == NULL ? NULL : &keys; lines_arg = lines_path == NULL ? NULL : &lines; // Convert the keypoints to matrices if (Keypoint_store_to_Mat_rm(®.kp_src, &keys_src) || Keypoint_store_to_Mat_rm(®.kp_ref, &keys_ref)) { err_msgu("Failed to convert the keypoints to " "matrices."); return 1; } // Draw the matches if (draw_matches(&src, &ref, &keys_src, &keys_ref, &match_src, &match_ref, concat_arg, keys_arg, lines_arg)) { err_msgu("Failed to draw the matches."); return 1; } // Optionally write a concatenated image if (concat_path != NULL && write_nii(concat_path, &concat)) { char msg[1024]; sprintf(msg, "Failed to write the concatenated image " "\"%s\"", concat_path); err_msg(msg); return 1; } // Optionally write the keypoints if (keys_path != NULL && write_nii(keys_path, &keys)) { char msg[1024]; sprintf(msg, "Failed to write the keypoint image " "\"%s\"", concat_path); err_msg(msg); return 1; } // Optionally write the matches if (lines_path != NULL && write_nii(lines_path, &lines)) { char msg[1024]; sprintf(msg, "Failed to write the line image " "\"%s\"", concat_path); err_msg(msg); return 1; } // Clean up im_free(&concat); im_free(&keys); im_free(&lines); } return 0; }
/* CLI for 3D SIFT */ int main(int argc, char *argv[]) { Image im; SIFT3D sift3d; Keypoint_store kp; SIFT3D_Descriptor_store desc; char *im_path, *keys_path, *desc_path, *draw_path; int c, num_args; const struct option longopts[] = { {"keys", required_argument, NULL, KEYS}, {"desc", required_argument, NULL, DESC}, {"draw", required_argument, NULL, DRAW}, {0, 0, 0, 0} }; // Parse the GNU standard options switch (parse_gnu(argc, argv)) { case SIFT3D_HELP: puts(help_msg); print_opts_SIFT3D(); return 0; case SIFT3D_VERSION: return 0; case SIFT3D_FALSE: break; default: err_msgu("Unexpected return from parse_gnu \n"); return 1; } // Initialize the SIFT data if (init_SIFT3D(&sift3d)) { err_msgu("Failed to initialize SIFT data."); return 1; } // Parse the SIFT3D options and increment the argument list if ((argc = parse_args_SIFT3D(&sift3d, argc, argv, SIFT3D_FALSE)) < 0) return 1; // Parse the kpSift3d options opterr = 1; keys_path = desc_path = draw_path = NULL; while ((c = getopt_long(argc, argv, "", longopts, NULL)) != -1) { switch (c) { case KEYS: keys_path = optarg; break; case DESC: desc_path = optarg; break; case DRAW: draw_path = optarg; break; case '?': default: return 1; } } // Ensure we have at least one output if (keys_path == NULL && desc_path == NULL && draw_path == NULL) { err_msg("No outputs specified."); return 1; } // Parse the required arguments num_args = argc - optind; if (num_args < 1) { err_msg("Not enough arguments."); return 1; } else if (num_args > 1) { err_msg("Too many arguments."); return 1; } im_path = argv[optind]; // Initialize data init_Keypoint_store(&kp); init_SIFT3D_Descriptor_store(&desc); init_im(&im); // Read the image if (im_read(im_path, &im)) { err_msg("Could not read image."); return 1; } // Extract keypoints if (SIFT3D_detect_keypoints(&sift3d, &im, &kp)) { err_msgu("Failed to detect keypoints."); return 1; } // Optionally write the keypoints if (keys_path != NULL && write_Keypoint_store(keys_path, &kp)) { char msg[BUF_SIZE]; snprintf(msg, BUF_SIZE, "Failed to write the keypoints to " "\"%s\"", keys_path); err_msg(msg); return 1; } // Optionally extract descriptors if (desc_path != NULL) { // Extract descriptors if (SIFT3D_extract_descriptors(&sift3d, &kp,&desc)) { err_msgu("Failed to extract descriptors."); return 1; } // Write the descriptors if (write_SIFT3D_Descriptor_store(desc_path, &desc)) { char msg[BUF_SIZE]; snprintf(msg, BUF_SIZE, "Failed to write the " "descriptors to \"%s\"", desc_path); err_msg(msg); return 1; } } // Optionally draw the keypoints if (draw_path != NULL) { Image draw; Mat_rm keys; // Initialize intermediates init_im(&draw); if (init_Mat_rm(&keys, 0, 0, DOUBLE, SIFT3D_FALSE)) err_msgu("Failed to initialize keys matrix"); // Convert to matrices if (Keypoint_store_to_Mat_rm(&kp, &keys)) { err_msgu("Failed to convert the keypoints to " "a matrix."); return 1; } // Draw the points if (draw_points(&keys, SIFT3D_IM_GET_DIMS(&im), 1, &draw)) { err_msgu("Failed to draw the points."); return 1; } // Write the output if (im_write(draw_path, &draw)) { char msg[BUF_SIZE]; snprintf(msg, BUF_SIZE, "Failed to draw the keypoints " "to \"%s\"", draw_path); err_msg(msg); return 1; } // Clean up im_free(&draw); } return 0; }