2

I am trying to run the ezsift library example. The example has name "image_match.cpp".

Here is the code

image_match.cpp

#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include "../ezsift.h"

using namespace std;

#define USE_FIX_FILENAME 0
int main(int argc, char ** argv)
{
#if USE_FIX_FILENAME
    char * file1 = "img1.pgm";
    char * file2 = "img2.pgm";
#else
    if (argc != 3)
    {
        printf("Please input two image filenames.\n");
        printf("usage: image_match img1 img2\n");
        return -1;
    }
    char file1[255];
    char file2[255];
    memcpy(file1, argv[1], sizeof(char) * strlen(argv[1]));
    file1[strlen(argv[1])] = 0;
    memcpy(file2, argv[2], sizeof(char) * strlen(argv[2]));
    file2[strlen(argv[2])] = 0;
#endif

    // Read two input images
    ImageObj<uchar> image1, image2;
    if(image1.read_pgm(file1) != 0)
    {
        printf("Failed to open input image1!\n");
        return -1;
    }

    if(image2.read_pgm(file2) != 0)
    {
        printf("Failed to open input image2!\n");
        return -1;
    }
    printf("Image 1 loaded. Image size: %d x %d\n", image1.w, image1.h);
    printf("Image 2 loaded. Image size: %d x %d\n", image2.w, image2.h);

    // Double the original image as the first octive.
    double_original_image(true);

    // Detect keypoints
    list<SiftKeypoint> kpt_list1, kpt_list2;
    printf("\nSIFT detection on image 1 ...\n");
    sift_cpu(image1, kpt_list1, true);
    printf("# keypoints in image1: %d\n", kpt_list1.size());

    printf("\nSIFT detection on image 2 ...\n");
    sift_cpu(image2, kpt_list2, true);
    printf("# keypoints in image2: %d\n", kpt_list2.size());

    // Save keypoint list, and draw keypoints on images.
    char filename[255];
    sprintf(filename, "s_A_keypoints.ppm");
    draw_keypoints_to_ppm_file(filename, image1, kpt_list1);
    export_kpt_list_to_file("s_A_keypoints.key", kpt_list1, true);

    sprintf(filename, "s_B_keypoints.ppm");
    draw_keypoints_to_ppm_file(filename, image2, kpt_list2);
    export_kpt_list_to_file("s_B_keypoints.key", kpt_list2, true);

    // Match keypoints.
    list<MatchPair> match_list;
    match_keypoints(kpt_list1, kpt_list2, match_list);

    // Draw result image.
    sprintf(filename, "s_A_B_matching.ppm");
    draw_match_lines_to_ppm_file(filename, image1, image2, match_list);
    printf("# of matched keypoints: %d\n", match_list.size());

    return 0;
}

ezsift.h

#ifndef EZSIFT_H
#define EZSIFT_H

#include "util/image.h"
#include "util/img_io.h"
#include <vector>
#include <list>
.
.
.
#endif

#define DEGREE_OF_DESCRIPTORS (128)
// Enable doubling of original image.
void double_original_image(bool doubleFirstOctave);

// Detect keypoints and extract descriptor.
int sift_cpu(
    const ImageObj<uchar> &image, 
    std::list<SiftKeypoint> & kpt_list, 
    bool bExtractDescriptors);

// Match keypoints from two keypoint lists.
int match_keypoints(
    std::list<SiftKeypoint> & kpt_list1,
    std::list<SiftKeypoint> & kpt_list2,
    std::list<MatchPair> & match_list);

.
.
.
#endif

(I will not include all the code here, I just wanted to give an idea. It is ease to download the source and see the files that I am talking about)

Also there is a "ezsift.cpp" file with more files in the "util" folder

I'm trying to run it from the terminal. I go to the directory and type "gcc image_match.cpp" but is says that double_original_image, sift_cpu (and all other functions in the header file) are not defined.

more specifically is gives this error:

image_match.cpp:(.text+0x1c7): undefined reference to `double_original_image(bool)'
image_match.cpp:(.text+0x20d): undefined reference to `sift_cpu(ImageObj<unsigned char> const&, std::list<_SiftKeypoint, std::allocator<_SiftKeypoint> >&, bool)'

(these are not the only error of course. It gives same error for all the functions)

I then tried "gcc ../ezsift.cpp image_match.cpp" but the same error.

What am I doing wrong?? I am running ubuntu 14.04.

Metalzero2
  • 531
  • 2
  • 6
  • 17
  • Why are you using `memcpy`+`strlen`? Why not just `strcpy`? – Drew McGowen Oct 07 '14 at 14:54
  • 9
    You need to link against the library! Otherwise sure, the compiler knows about all the function because they're declared in the header, but their actual definitions (which the linker has to make your function calls point to) are unknown. – Cameron Oct 07 '14 at 14:55
  • The functions are only *declared* in the header file, not *defined*. You need to link with the actual library for the definitions. – Some programmer dude Oct 07 '14 at 15:01
  • @Cameron could you tell me how to do that? What else do I need to add when running the "gcc" command? – Metalzero2 Oct 07 '14 at 15:08
  • See http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix/12574400#12574400 – sth Oct 07 '14 at 15:09
  • 1
    @Dimitris: Having had a peek at the library in question, it seems it doesn't come with a pre-compiled binary to link against (as is customary in the linux world). You'll have to either: 1) Build a library yourself, and then link against it, or 2) Compile the ezsift .cpp files along with your own (`g++ ../ezsift.cpp image_match.cpp`). I see you already tried the second option, which should work -- but you're compiling the code as if it was C, not C++: use `g++` not `gcc`. – Cameron Oct 07 '14 at 15:31

1 Answers1

1

(expending Cameron's comment into a tested answer)

You need to compile both ezsift.cpp and img_io.cpp with your program (image_match.cpp), while providing the location of the header files (-I\path\to\directory). Here is a working snippet, assuming you are in the examples directory:

g++ image_match.cpp  ../ezsift.cpp ../util/img_io.cpp -I.. -o image_match
Jealie
  • 6,157
  • 2
  • 33
  • 36