i have been working on basic gesture control algorithm. have set of reference images (commands) , sample images (drawn user). want compare sample image reference images , see command has user tried enter (assuming draw/ try draw provided gestures).
however, unable generate concrete matching algorithm. have tried matchshapes opencv library , correlation function well. far, correlation function has provided decent results.
here code
#include<iostream> #include<opencv2/highgui.hpp> #include<opencv2/imgproc.hpp> #include<opencv2/core.hpp> using namespace std; using namespace cv; void cannythreshold(mat* src, mat* detect) { blur(*src, *detect, size(3, 3)); canny(*detect, *detect, 5, 15, 3); } double correlation(cv::mat &image_1, cv::mat &image_2) { // convert data-type "float" cv::mat im_float_1; image_1.convertto(im_float_1, cv_32f); cv::mat im_float_2; image_2.convertto(im_float_2, cv_32f); int n_pixels = im_float_1.rows * im_float_1.cols; // compute mean , standard deviation of both images cv::scalar im1_mean, im1_std, im2_mean, im2_std; meanstddev(im_float_1, im1_mean, im1_std); meanstddev(im_float_2, im2_mean, im2_std); assert(im_float_1.size() == im_float_2.size()); // compute covariance , correlation coefficient double covar = (im_float_1 - im1_mean).dot(im_float_2 - im2_mean) / n_pixels; //cout << "correl function conversion \n"; double correl = covar / (im1_std[0] * im2_std[0]); return correl; } int main() { mat src_a, src_b; src_a = imread("../data/ref_sq.png", 0); src_b = imread("../data/drawn_sq.png", 0); assert( !(src_a.empty() || src_b.empty() ) ); namedwindow("ref", window_autosize); namedwindow("drawn", window_autosize); mat mata, matb; rect boundrecta, boundrectb; cannythreshold(&src_a, &mata); cannythreshold(&src_b, &matb); //draw rectangles around gesture (seperate black bkg) boundrecta = boundingrect(mata); boundrectb = boundingrect(matb); rectangle(mata, boundrecta, scalar(255, 0, 0)); rectangle(matb, boundrectb, scalar(255, 0, 0)); mat cropa, cropb; //resize gesture images same size cropa = mata(boundrecta); cropb = matb(boundrectb); resize(cropa, mata, size(300, 300)); resize(cropb, matb, size(300, 300)); imshow("ref", mata); imshow("drawn", matb); double d = correlation(mata, matb); float variance = matchshapes(mata, matb, cv_tm_ccorr, 0.0); cout << "variance = " << variance << "\n"; cout << "correlation : " << d << "\n"; waitkey(0); return 0; }
i have tried combinations of : square , triangle , circle far. here results these combinations variation = 0 100% match , correlation = 1 100% match.
reference_triangle , drawn_circle variance : 0.117478 correlation : 0.450111 reference_triangle , drawn_triangle variance : 0.146981 correlation : 0.506216 reference_triangle , drawn_square variance : 0.133144 correlation : 0.449743 reference_square , drawn_circle variance : 0.0244948 correlation : 0.478725 reference_square , drawn_triangle variance : 0.00500868 correlation : 0.410928 reference_square , drawn_square variance : 0.00882819 correlation : 0.512346 reference_circle , drawn_circle variance : 0.0298134 correlation : 0.543662 reference_circle , drawn_triangle variance : 0.00030983 correlation : 0.402365 reference_circle , drawn_square variance : 0.0141467 correlation : 0.473818
so wondering, there other way matching images should try? appreciated.
Comments
Post a Comment