Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] - Feature train orb #31

Draft
wants to merge 23 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/jsfeatES6cpp.js

Large diffs are not rendered by default.

38 changes: 19 additions & 19 deletions build/jsfeatES6cpp_debug.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/jsfeatcpp.js

Large diffs are not rendered by default.

38 changes: 19 additions & 19 deletions build/jsfeatcpp_debug.js

Large diffs are not rendered by default.

32 changes: 22 additions & 10 deletions emscripten/webarkitJsfeat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,15 @@ void train_orb_pattern_internal(const char* filename) {
}
webarkitLOGi("Image done!");

JSLOGi("Starting detection routine...");
JSLOGi("Starting detection routine...\n");

Orb orb;
Imgproc imgproc;
detectors::Detectors detectors;
std::unique_ptr<Matrix_t> lev0_img = std::make_unique<Matrix_t>(jpegImage->xsize, jpegImage->ysize, ComboTypes::U8C1_t);
std::unique_ptr<Matrix_t> lev_img = std::make_unique<Matrix_t>(jpegImage->xsize, jpegImage->ysize, ComboTypes::U8C1_t);
Array<std::unique_ptr<Matrix_t>> pattern_corners;
std::cout << "after orb" << std::endl;

auto sc0 = std::min(max_pattern_size / jpegImage->ysize, max_pattern_size / jpegImage->xsize);
new_width = (jpegImage->ysize * sc0) | 0;
Expand All @@ -168,14 +169,17 @@ void train_orb_pattern_internal(const char* filename) {
auto i_u8_size = jpegImage->xsize * jpegImage->ysize * jpegImage->nc;
Array<u_char> i_u8(jpegImage->image, jpegImage->image + i_u8_size);
std::unique_ptr<Matrix_t> img_u8 = std::make_unique<Matrix_t>(jpegImage->xsize, jpegImage->ysize, ComboTypes::U8C4_t, i_u8);

imgproc.resample(img_u8.get(), lev0_img.get(), new_width, new_height);


JSLOGi("Resampling image...");

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resampling is not needed in our case, because we provide our image with the right size. The code was taken by the jsfeat sample_orb example and in that case we simply resampled the image taken by the canvas(webcam) to a smaller size. Anyway the resample function has some issues, infact the log console "Image resampled, starting pyrmaid now..." can not be printed with this function enabled. (just comment out and recompile to test)

//imgproc.resample(img_u8.get(), lev0_img.get(), new_width, new_height);

JSLOGi("Image resampled, starting pyramid now...");
// prepare preview
std::unique_ptr<Matrix_t> pattern_preview = std::make_unique<Matrix_t>(jpegImage->xsize >> 1, jpegImage->ysize >> 1, ComboTypes::U8C1_t);
imgproc.pyrdown_internal(lev0_img.get(), pattern_preview.get());

Array<KeyPoints> lev_corners;
Array<KeyPoints*> lev_corners(4);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we should provide a array of pointers and pre init them.

Array<std::unique_ptr<Matrix_t>> pattern_descriptors;

for (lev = 0; lev < num_train_levels; ++lev) {
Expand All @@ -186,22 +190,30 @@ void train_orb_pattern_internal(const char* filename) {
// preallocate corners array
i = (new_width * new_height) >> lev;
while (--i >= 0) {
lev_corners[lev].set_size(i);
lev_corners[lev]->set_size(i);
lev_corners[lev]->allocate();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to set the size and allocate the entire set.

}
std::cout << "Num. of level: " << lev << std::endl;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this print 4 levels in the console:
Num. of level: 0 and so on...

pattern_descriptors.push_back(std::unique_ptr<Matrix_t>(new Matrix_t(32, max_per_level, ComboTypes::U8C1_t)));
}

imgproc.gaussian_blur_internal(lev0_img.get(), lev_img.get(), 5, 0.2); // this is more robust
//std::cout << "Size of first lev_corners: " << lev_corners[0]->kpoints.size() << std::endl;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not printed...


imgproc.gaussian_blur_internal(lev0_img.get(), lev_img.get(), 5, 2); // this is more robust

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ok , it is printed...

JSLOGi("After Gaussian blur");

corners_num = detectors.detect_keypoints(lev_img.get(), lev_corners[0], max_per_level);

// orb.describe(lev_img.get(), lev_corners[0], corners_num, lev_descr.get());
// This probablly will work in a near future
// orb.describe(lev_img.get(), lev_corners[0], corners_num, &pattern_descriptors[0]);
Copy link
Owner Author

@kalwalt kalwalt Nov 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

orb.describe can not be yet used here because it accept in the first parameter a uintptr_t and in the second parameter an emscripten::val can not be managed here. I should create a new method in the Orb class:
orb.describe_internal(Matrix_t* mat, Keypoints* kp, int num corners, Matix_t* descr)


// console.log("train " + lev_img.cols + "x" + lev_img.rows + " points: " + corners_num);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...continuning from below, These two printings instead do nothing. I will open an issue as reminder.

JSLOGi("Corners num: %i", corners_num);
JSLOGi("train %i x %i points: %i\n", lev_img.get()->get_cols(), lev_img.get()->get_rows(), corners_num);
std::cout << "train " << lev_img.get()->get_cols() << " x " << lev_img.get()->get_rows() << " points: " << corners_num << std::endl;
std::cout << "Corners num: " << (int)corners_num << std::endl;
//JSLOGi("Corners num: %i", corners_num);
//JSLOGi("train %i x %i points: %i\n", lev_img.get()->get_cols(), lev_img.get()->get_rows(), corners_num);
//std::cout << "train " << lev_img.get()->get_cols() << " x " << lev_img.get()->get_rows() << " points: " << corners_num << std::endl;
free(ext);
free(jpegImage);
};
Expand Down
12 changes: 8 additions & 4 deletions src/feature_detection/detectors.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,26 @@ class Detectors : public Yape06, public Math, public KeyPointsFilter {
Detectors() {}
~Detectors() {}

int detect_keypoints(Matrix_t* img, KeyPoints corners, int max_allowed) {
int detect_keypoints(Matrix_t* img, KeyPoints* corners, int max_allowed) {
// detect features
auto kpc = detect_internal(img, &corners, 17);
auto kpc = detect_internal(img, corners, 17);
auto count = kpc.count;
std::cout << "here" << std::endl;
//std::cout << count << std::endl;
// sort by score and reduce the count if needed
if (count > max_allowed) {
// qsort_internal<KeyPoint_t, bool>(corners.kpoints, 0, count - 1, [](KeyPoint_t i, KeyPoint_t j){return (i.score < j.score);});
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure of this, maybe it's better to use another small different approach. I'm looking to the OpenCV code in the Orb implementation and there is another possibility.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

retainBest is taken from OpenCV, but i need to figure out if this is correct.

retainBest(corners.kpoints, count);
retainBest(corners->kpoints, count);
count = max_allowed;
}

// calculate dominant orientation for each keypoint
for (auto i = 0; i < count; ++i) {
corners.kpoints[i].angle = ic_angle(img, corners.kpoints[i].x, corners.kpoints[i].y);
corners->kpoints[i].angle = ic_angle(img, corners->kpoints[i].x, corners->kpoints[i].y);
}

//std::cout << count << std::endl;

return count;
}

Expand Down
6 changes: 6 additions & 0 deletions src/keypoints/keypoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ class KeyPoints {
this->size = kp.size;
this->kpoints = kp.kpoints;
}

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added tha allocate function because if you initialize a KeyPoints with the default constructor it will not init the kpoints.

auto allocate() {
KeyPoint_t kpt(0, 0, 0, 0, -1);
kpoints.assign(this->size, kpt);
}

auto get_size() const {return size; };

auto set_size(int size) { this->size = size; };
Expand Down
1 change: 1 addition & 0 deletions src/yape06/yape06.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class Yape06 {
}
}
}
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this not printing anything...

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now it display some value: Count inside Yape06 detect_internal: 64192

std::cout << "count: " << ypts.count << std::endl;

return ypts;
}
Expand Down