mirror of
https://github.com/ruby-opencv/ruby-opencv
synced 2023-03-27 23:22:12 -04:00
added a sample of matching SURF feature points using kd-tree (example/match_kdtree.rb)
This commit is contained in:
parent
e5ec274a04
commit
02fa6b9554
3 changed files with 88 additions and 0 deletions
BIN
examples/lenna-rotated.jpg
Normal file
BIN
examples/lenna-rotated.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
examples/lenna.jpg
Normal file
BIN
examples/lenna.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
88
examples/match_kdtree.rb
Executable file
88
examples/match_kdtree.rb
Executable file
|
@ -0,0 +1,88 @@
|
|||
#!/usr/bin/env ruby
|
||||
# -*- mode: ruby; coding: utf-8-unix -*-
|
||||
|
||||
# A sample of matching SURF feature points using kd-tree
|
||||
# See http://tech.groups.yahoo.com/group/OpenCV/message/62318
|
||||
|
||||
require 'opencv'
|
||||
include OpenCV
|
||||
|
||||
USE_EXTENDED_DESCRIPTOR = true
|
||||
THRESHOLD = 1500
|
||||
DESCRIPTOR_SIZE = USE_EXTENDED_DESCRIPTOR ? 128 : 64
|
||||
|
||||
img1 = CvMat.load('lenna.jpg', CV_LOAD_IMAGE_GRAYSCALE)
|
||||
img2 = CvMat.load('lenna-rotated.jpg', CV_LOAD_IMAGE_GRAYSCALE)
|
||||
|
||||
puts 'Extracting features from img1 using SURF...'
|
||||
param = CvSURFParams.new(THRESHOLD, USE_EXTENDED_DESCRIPTOR)
|
||||
kp1, desc1 = img1.extract_surf(param)
|
||||
puts "found #{kp1.size} keypoints from img1"
|
||||
|
||||
puts 'Extracting features from img2 using SURF...'
|
||||
kp2, desc2 = img2.extract_surf(param)
|
||||
puts "found #{kp2.size} keypoints from img2"
|
||||
|
||||
puts 'Matching keypoints...'
|
||||
desc1mat = CvMat.new(kp1.size, DESCRIPTOR_SIZE, :cv32f, 1)
|
||||
desc2mat = CvMat.new(kp2.size, DESCRIPTOR_SIZE, :cv32f, 1)
|
||||
desc1.each_with_index { |desc, i|
|
||||
desc.each_with_index { |d, j|
|
||||
desc1mat[i, j] = CvScalar.new(d)
|
||||
}
|
||||
}
|
||||
desc2.each_with_index { |desc, i|
|
||||
desc.each_with_index { |d, j|
|
||||
desc2mat[i, j] = CvScalar.new(d)
|
||||
}
|
||||
}
|
||||
|
||||
feature_tree = CvFeatureTree.new(desc1mat)
|
||||
results, distances = feature_tree.find_features(desc2mat, 1, 250)
|
||||
|
||||
reverse_lookup = []
|
||||
reverse_lookup_dist = []
|
||||
kp1.size.times { |i|
|
||||
reverse_lookup << -1
|
||||
reverse_lookup_dist << Float::MAX
|
||||
}
|
||||
|
||||
match_count = 0
|
||||
kp2.size.times { |j|
|
||||
i = results[j][0].to_i
|
||||
d = distances[j][0]
|
||||
if (d < reverse_lookup_dist[i])
|
||||
match_count += 1 if reverse_lookup_dist[i] == Float::MAX
|
||||
reverse_lookup[i] = j
|
||||
reverse_lookup_dist[i] = d
|
||||
end
|
||||
}
|
||||
puts "found #{match_count} putative correspondences"
|
||||
|
||||
points1 = []
|
||||
points2 = []
|
||||
kp2.size.times { |j|
|
||||
i = results[j][0].to_i
|
||||
if (j == reverse_lookup[i])
|
||||
points1 << kp1[i].pt
|
||||
points2 << kp2[j].pt
|
||||
end
|
||||
}
|
||||
|
||||
width = img1.cols + img2.cols
|
||||
height = (img1.rows > img2.rows) ? img1.rows : img2.rows
|
||||
correspond = IplImage.new(width, height, :cv8u, 1);
|
||||
correspond.set_roi(CvRect.new(0, 0, img1.cols, img1.rows))
|
||||
img1.copy(correspond)
|
||||
correspond.set_roi(CvRect.new(img1.cols, 0, img1.cols + img2.cols, img2.rows))
|
||||
img2.copy(correspond)
|
||||
correspond.reset_roi
|
||||
|
||||
points1.zip(points2) { |pt1, pt2|
|
||||
pt2.x += img1.cols
|
||||
correspond.line!(pt1, pt2, :color => CvColor::White)
|
||||
}
|
||||
|
||||
GUI::Window.new('Object Correspond').show correspond
|
||||
GUI::wait_key
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue