Exemplo n.º 1
0
/* Wrapper to set the options for the Reg_SIFT3D struct. The argument mx shall
 * be a struct with the following fields:
 *   -numIter
 *   -errThresh
 *   -nnThresh
 *
 * Any other fields are ignored. Empty fields are replaced with the defaults.
 *
 * Returns SIFT3D_SUCCESS on success, SIFT3D_FAILURE otherwise. */
int mex_set_opts_Reg_SIFT3D(const mxArray *const mx) {

        Ransac ran;
        const mxArray *mxNumIter, *mxErrThresh, *mxNnThresh;
        double nn_thresh;

        // Verify inputs
        if (mxIsEmpty(mx) || !mxIsStruct(mx))
                return SIFT3D_FAILURE;
        
        // Initialize options to the defaults
        nn_thresh = SIFT3D_nn_thresh_default;
        init_Ransac(&ran);

        // Get the option arrays
        if ((mxNumIter = mxGetField(mx, 0, "numIter")) == NULL ||
                (mxErrThresh = mxGetField(mx, 0, "errThresh")) == NULL ||
                (mxNnThresh = mxGetField(mx, 0, "nnThresh")) == NULL)
                return SIFT3D_FAILURE;

        // Get the non-empty options 
        if (!mxIsEmpty(mxNumIter) &&
                set_num_iter_Ransac(&ran, (int) mxGetScalar(mxNumIter))) {
                return SIFT3D_FAILURE;
        } 
        if (!mxIsEmpty(mxErrThresh) && 
                set_err_thresh_Ransac(&ran, mxGetScalar(mxErrThresh))) {
                return SIFT3D_FAILURE;
        } 
        if (!mxIsEmpty(mxNnThresh)) {
                nn_thresh = mxGetScalar(mxNnThresh);
        }

        // Set the options
        return set_Ransac_Reg_SIFT3D(&reg, &ran) ||
            set_nn_thresh_Reg_SIFT3D(&reg, nn_thresh);
}
Exemplo n.º 2
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 = &reg.desc_src;
        SIFT3D_Descriptor_store *const desc_ref = &reg.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(&reg);
        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(&reg, &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(&reg, 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(&reg, &src)) {
                err_msgu("Failed to set the source image.");
                return 1;
        }
        if (set_ref_Reg_SIFT3D(&reg, &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(&reg, tform_arg)) {
                err_msgu("Failed to register the images.");
                return 1;
        }

        // Convert the matches to matrices
        if (get_matches_Reg_SIFT3D(&reg, &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(&reg.kp_src, &keys_src) ||
                    Keypoint_store_to_Mat_rm(&reg.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;
}