1

So I'm doing the template matching for specific region from input image using OpenCVCameraView. Below is what my code looks like.

Mat input;
Rect bigRect = ...; //specific size

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    input = inputFrame.rgba();
    ...
}

public void Template(View view) {
    Mat mImage = input.submat(bigRect);
    Mat mTemplate = Utils.loadResource(this, R.id.sample, Highgui.CV_LOAD_IMAGE_COLOR);
    Mat mResult = new Mat(mImage.rows(), mImage.cols(), CvType.CV_32FC1); // I use the same size as mImage because mImage's size is already smaller than inputFrame

    Imgproc.cvtColor(mImage, mImage, Imgproc.COLOR_RGBA2RGB); //convert is needed to make mImage and mTemplate to be the same type

    Imgproc.matchTemplate(mImage, mTemplate, mResult, match_method);        
    Core.normalize(mResult, mResult, 0, 1, Core.NORM_MINMAX, -1, new Mat());

    mResult.convertTo(mResult, CvType.CV_8UC1); // I convert the matrix because I need to show it to imageview via bitmap

    Bitmap bmResult1 = Bitmap.createBitmap(mImage.width(), mImage.height(), Bitmap.Config.RGB_565);
    Bitmap bmResult2 = Bitmap.createBitmap(mResult.width(), mResult.height(), Bitmap.Config.RGB_565);
    Utils.matToBitmap(mImage, bmResult1);
    Utils.matToBitmap(mResult, bmResult2);
    ImageView1.setImageBitmap(bmResult1);
    ImageView2.setImageBitmap(bmResult2);
}

The I try to output the matrix using toString() and got these results:

mImage: Mat [250*178*CV_8UC3, isCont=true, isSubmat=false, ...]
mResult: Mat [180*94*CV_8UC1, isCont=true, usSubmat=false, ...]

And my questions are:

  1. Why the mResult size is smaller than mImage despite already declared that mResult size is based on mImage size?
  2. Turns out that by using CV_8UC1 type, the content is only available in black or white, while mResult is supposed to have floating value, but Utils.matToBitmap method doesn't support mat types other than CV_8UC1, CV_8UC3, and CV_8UC4. Is there any way to show CV_32FC1 to Bitmap that it shows the real grayscale of mResult?
Affan Widyan
  • 77
  • 1
  • 10
  • opencv documentation says: `result – Map of comparison results. It must be single-channel 32-bit floating-point. If image is W \times H and templ is w \times h , then result is (W-w+1) \times (H-h+1) .` so I guess your template has size of [69, 83] ?? – Micka May 18 '15 at 07:31

1 Answers1

1

Why the mResult size is smaller than mImage despite already declared that mResult size is based on mImage size?

As template matching is basically a spatial convolution, when performed with images of height H and h, the result will be H-h+1. Same with result width (W-w+1). But you can still resizethe result back to (mImage.rows(), mImage.cols()) after template matching.

Turns out that by using CV_8UC1 type, the content is only available in black or white, while mResult is supposed to have floating value, but Utils.matToBitmap method doesn't support mat types other than CV_8UC1, CV_8UC3, and CV_8UC4. Is there any way to show CV_32FC1 to Bitmap that it shows the real grayscale of mResult?

The key is in these two lines, I think:

Core.normalize(mResult, mResult, 0, 1, Core.NORM_MINMAX, -1, new Mat());
mResult.convertTo(mResult, CvType.CV_8UC1); // I convert the matrix because I need to show it to imageview via bitmap

Can't you just normalize it to take values between 0 and 255?

Core.normalize(mResult, mResult, 0, 255, Core.NORM_MINMAX, -1, new Mat());
Яois
  • 3,838
  • 4
  • 28
  • 50
  • resizing the result is probably dangerous for interpretation if the results. Except you know exactly why you wanted to do that. – Micka May 18 '15 at 07:33
  • 1
    Representation maybe? I don't know. It's probably not recommended, as you say, but if the OP wants it to be of that size, I just pointed out how to do it. – Яois May 18 '15 at 07:40
  • 1
    I looked at OpenCV tutorial [here](http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html#results) and it looks like the result Mat has the same dimension as image Mat so I thought it looks better for representation. – Affan Widyan May 22 '15 at 04:14
  • @AffanWidyan look at *point 7* of that tutorial: `int result_cols = img.cols - templ.cols + 1; int result_rows = img.rows - templ.rows + 1;` ;) – Яois May 22 '15 at 07:39