I have downloaded and successfully run the example provided in opencv4android sdk.
I am able to simply display the camera frames without any processing,
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
return inputFrame.rgba();
}
I want to process live frame with some predefined image template to recognize that template. I have taken reference from this post and implemented accordingly. But I get black screen only.
private Mat mCameraMat = new Mat();
private Mat mTemplateMat;
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mCameraMat = inputFrame.rgba();
initialize();
int match_method = Imgproc.TM_SQDIFF;
// Create the result matrix
int result_cols = mCameraMat.cols() - mTemplateMat.cols() + 1;
int result_rows = mCameraMat.rows() - mTemplateMat.rows() + 1;
Log.d(TAG, " mCameraMat cols "+mCameraMat.cols());
Log.d(TAG, " mCameraMat rows "+mCameraMat.rows());
Log.d(TAG, " mTemplateMat cols "+mTemplateMat.cols());
Log.d(TAG, " mTemplateMat rows "+mTemplateMat.rows());
Mat result = new Mat(result_rows, result_cols, CvType.CV_32F);
// Do the Matching and Normalize
Imgproc.matchTemplate(mCameraMat, mTemplateMat, 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;
}
Rect roi = new Rect((int) matchLoc.x, (int) matchLoc.y, mTemplateMat.cols(), mTemplateMat.rows());
Core.rectangle(mCameraMat, new Point(roi.x, roi.y), new Point(roi.width - 2, roi.height - 2), new Scalar(255, 0, 0, 255), 2);
return result;
}
public void initialize(){
try {
if (mCameraMat.empty())
return;
if(mTemplateMat == null){
Mat temp = Utils.loadResource(Tutorial1Activity.this, R.drawable.icon);
mTemplateMat = new Mat(temp.size(), CvType.CV_32F);
Imgproc.cvtColor(temp, mTemplateMat, Imgproc.COLOR_BGR2RGBA);
Log.d(TAG, "initialize mTemplateMat cols "+mTemplateMat.cols());
Log.d(TAG, "initialize mTemplateMat rows "+mTemplateMat.rows());
}
} catch (IOException e) {
e.printStackTrace();
}
}
Note:
My ultimate goal is to recognize the playing cards from live camera. Kindly suggest best approach. Should I use image templates or any other thing to make things faster?
This is how I want to recognize multiple cards from live camera:
Result should be: ♠A ♠K ♠Q ♠J ♠10 when camera preview seems like below
onCameraFrame
has tworeturn
statements, am I wrong? – Sagermanresult
will be1
after the call toCore.normalize
, am I right? If yes, then on the range 0=black and 255=white you will have thatresult
is almost black. Furthermoreresult
is of typeCV_32F
while maybe you need a 3 channel image (R, G, B as you wrote in your first code snippet which you say it is working fine). And yourCore.rectangle
will draw on the imagemCameraMat
but you do not returnmCameraMat
... – SagermanCore.normalize(result, result, 0, 255, Core.NORM_MINMAX, -1, new Mat());
? – Sagerman