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:
mResult
size is smaller than mImage
despite already declared that mResult
size is based on mImage
size?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
?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 resize
the 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());