I'm a beginner to OpenCV. I'm trying to do a sample android application to match a template image in a given image using OpenCV Template matching. I searched in the internet and I couldn't find a proper android or java code which satisfy my requirement. But I have C++ code. I dont know how to translate it. http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html
Can you please help me to find a proper java or android code. Or else please help me with translate this C++ code into java, which I can use inside android application.
Thank you in advance.
C++ code
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; /// Global Variables Mat img; Mat templ; Mat result; char* image_window = "Source Image"; char* result_window = "Result window"; int match_method; int max_Trackbar = 5; /// Function Headers void MatchingMethod( int, void* ); /** @function main */ int main( int argc, char** argv ) { /// Load image and template img = imread( argv[1], 1 ); templ = imread( argv[2], 1 ); /// Create windows namedWindow( image_window, CV_WINDOW_AUTOSIZE ); namedWindow( result_window, CV_WINDOW_AUTOSIZE ); /// Create Trackbar char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED"; createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod ); MatchingMethod( 0, 0 ); waitKey(0); return 0; } /** * @function MatchingMethod * @brief Trackbar callback */ void MatchingMethod( int, void* ) { /// Source image to display Mat img_display; img.copyTo( img_display ); /// Create the result matrix int result_cols = img.cols - templ.cols + 1; int result_rows = img.rows - templ.rows + 1; result.create( result_cols, result_rows, CV_32FC1 ); /// Do the Matching and Normalize matchTemplate( img, templ, result, match_method ); normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() ); /// Localizing the best match with minMaxLoc double minVal; double maxVal; Point minLoc; Point maxLoc; Point matchLoc; minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() ); /// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED ) { matchLoc = minLoc; } else { matchLoc = maxLoc; } /// Show me what you got rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 ); rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 ); imshow( image_window, img_display ); imshow( result_window, result ); return; }
OpenCV comes with a function cv. matchTemplate() for this purpose. It simply slides the template image over the input image (as in 2D convolution) and compares the template and patch of input image under the template image. Several comparison methods are implemented in OpenCV.
Template matching is a technique for finding areas of an image that match (are similar) to a template image (patch). While the patch must be a rectangle it may be that not all of the rectangle is relevant. In such a case, a mask can be used to isolate the portion of the patch that should be used to find the match.
Template matching is a technique in digital image processing for finding small parts of an image which match a template image. It can be used in manufacturing as a part of quality control, a way to navigate a mobile robot, or as a way to detect edges in images.
I was facing the same problem you did. No source in Java available. Some search in the JavaDoc and some hints for const values later, I wrote this, which is almost the sample code above written in Java:
package opencv; import org.opencv.core.Core; import org.opencv.core.Core.MinMaxLocResult; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.Point; import org.opencv.core.Scalar; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; class MatchingDemo { public void run(String inFile, String templateFile, String outFile, int match_method) { System.out.println("\nRunning Template Matching"); Mat img = Highgui.imread(inFile); Mat templ = Highgui.imread(templateFile); // / Create the result matrix int result_cols = img.cols() - templ.cols() + 1; int result_rows = img.rows() - templ.rows() + 1; Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1); // / Do the Matching and Normalize Imgproc.matchTemplate(img, templ, result, match_method); Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat()); // / Localizing the best match with minMaxLoc MinMaxLocResult mmr = Core.minMaxLoc(result); Point matchLoc; if (match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED) { matchLoc = mmr.minLoc; } else { matchLoc = mmr.maxLoc; } // / Show me what you got Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(), matchLoc.y + templ.rows()), new Scalar(0, 255, 0)); // Save the visualized detection. System.out.println("Writing "+ outFile); Highgui.imwrite(outFile, img); } } public class TemplateMatching { public static void main(String[] args) { System.loadLibrary("opencv_java246"); new MatchingDemo().run(args[0], args[1], args[2], Imgproc.TM_CCOEFF); } }
Now, run the program with the following options: lena.png template.png templatematch.png
and you should receive the same result I did. Make sure the files are accessible by your runtime and, of course, opencv 2.4.6 library is registered to your classpath.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With