问题
I want to create an android application. Program steps are below
- Open camera
- Get frames
- Select a frame by touch screen
- Load template image under drawable folder
- Apply template matching
- Show result
The mat object of template image is not empty. I check it. When I run this code, I get below error message.
Code :
public void onCameraViewStarted(int width, int height) {
mRgba = new Mat(height, width, CvType.CV_8UC4);
temp = new Mat(height, width, CvType.CV_8UC4);
}
public boolean onTouch(View v, MotionEvent event) {
int cols = mRgba.cols();
int rows = mRgba.rows();
int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;
int x = (int)event.getX() - xOffset;
int y = (int)event.getY() - yOffset;
Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
mIsColorSelected = true;
return true; // don't need subsequent touch events
}
private static Mat readInputStreamIntoMat(InputStream inputStream) throws IOException {
// Read into byte-array
byte[] temporaryImageInMemory = readStream(inputStream);
// Decode into mat. Use any IMREAD_ option that describes your image appropriately
Mat outputImage = Highgui.imdecode(new MatOfByte(temporaryImageInMemory), Highgui.IMREAD_GRAYSCALE);
return outputImage;
}
private static byte[] readStream(InputStream stream) throws IOException {
// Copy content of the image to byte-array
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = stream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
byte[] temporaryImageInMemory = buffer.toByteArray();
buffer.close();
stream.close();
return temporaryImageInMemory;
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
if(mIsColorSelected) {
InputStream inpT = getResources().openRawResource(R.drawable.imgt);
Mat mTemp;
try {
mRgba.copyTo(temp);
mTemp = readInputStreamIntoMat(inpT);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// / Create the result matrix
int result_cols = temp.cols() - mTemp.cols() + 1;
int result_rows = temp.rows() - mTemp.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
int match_method = 4;
// / Do the Matching and Normalize
Imgproc.matchTemplate(temp, mTemp, 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(temp, matchLoc, new Point(matchLoc.x + mTemp.cols(),
matchLoc.y + mTemp.rows()), new Scalar(0, 255, 0));*/
return temp;
}
else {
mRgba = inputFrame.rgba();
}
return mRgba;
}
回答1:
For template matching , both source image and template image must be of same data type(1). Here your template image(mTemp
) is a gray scale image and source image( mRgba
/ temp
) is a color image with alpha channel.
So, lets change both source and template images to be gray scale images
temp = new Mat(height, width, CvType.CV_8UC1);
and replace mRgba.copyTo(temp)
with
Imgproc.cvtColor(mRgba, temp, Imgproc.COLOR_RGBA2GRAY);
来源:https://stackoverflow.com/questions/29238433/android-template-matching