Hi all, I'm trying to subtract two Mat instances to obtain a result that represents a person's signature. Unfortunately, my resulting Mat seems to show noise along the top edge. Here are the source images and output:
The templateToMatch: C:\fakepath\template.png
The original source from which the ROI will be extracted, referred to as "formImage" in the code:C:\fakepath\sep-ira-completed-handwritten-p5.png
The ROI extracted via matchTemplate and Rect:C:\fakepath\signed.png
The result of running subtract on the template and extracted ROI: C:\fakepath\difference.png
As you can see, difference.png shows noise creeping down over the actual signature.
Can someone have a look at my implementation and tell me what I may be doing wrong? Is there a way I can mitigate this, if not avoid it altogether?
Here's where the subtraction takes place:
cv::Mat extractSignatureFromRegion(cv::Mat & templateToMatch, cv::Mat & formImage, bool* sigFound) {
Mat signature;
Mat result;
bool hasSignature = false;
Mat sigRegion = getSignatureRegion(templateToMatch, formImage);
subtract(templateToMatch, sigRegion, signature);
cvtColor(signature, signature, CV_BGR2GRAY);
if (countNonZero(signature) > 0) {
hasSignature = true;
}
*sigFound = hasSignature;
return signature;
}
Here's the getSignatureRegion that uses template matching to extract the potentially signed region in the source doc:
cv::Mat getSignatureRegion(cv::Mat & templateToMatch, cv::Mat & formImage) {
//Create result matrix from template and original source
Mat resultImg;
Mat resultMatrix;
Mat regionMatchingTemplate;
Mat result;
double minVal;
double maxVal;
Point minLoc;
Point maxLoc;
Point matchLoc;
int resultColumns = formImage.cols - templateToMatch.cols + 1;
int resultRows = formImage.rows - templateToMatch.rows + 1;
resultMatrix.create(resultColumns, resultRows, CV_32FC1);
// Match template and normalize
matchTemplate(formImage, templateToMatch, resultMatrix, CV_TM_SQDIFF);
normalize(resultMatrix, resultMatrix, 0, 1, NORM_MINMAX, -1, Mat());
minMaxLoc(resultMatrix, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
matchLoc = minLoc;
regionMatchingTemplate = formImage(Rect(matchLoc.x, matchLoc.y, templateToMatch.cols, templateToMatch.rows));
regionMatchingTemplate.copyTo(result);
return result;
}