Ich versuche, mehr als ein Quadrat (Marker) in meinem Bild zu erfassen, wie ich hier fragen Detect Marker Position in 2D imageOpenCV - C++ zu Java - Template Match
Es gibt einen Mann, der mir in C eine Lösung zeigte ++, ist es hier :
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//See: http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html
//See: http://answers.opencv.org/question/60382/detect-markers-position-in-2d-images/
int main() {
cv::Mat img, templateImg, result;
cv::VideoCapture capture("http://answers.opencv.org/upfiles/14297307634571599.png");
if(capture.isOpened()) {
capture >> img;
} else {
return -1;
}
capture = cv::VideoCapture("http://answers.opencv.org/upfiles/14297308125543022.png");
if(capture.isOpened()) {
capture >> templateImg;
} else {
return -1;
}
/// Reduce the size of the image to display it on my screen
cv::resize(img, img, cv::Size(), 0.5, 0.5);
/// Reduce the size of the template image
/// (first to fit the size used to create the image test, second to fit the size of the reduced image)
cv::resize(templateImg, templateImg, cv::Size(), 0.25, 0.25);
cv::Mat img_display;
img.copyTo(img_display);
// Create the result matrix
int result_cols = img.cols - templateImg.cols + 1;
int result_rows = img.rows - templateImg.rows + 1;
result.create(result_rows, result_cols, CV_32FC1);
/// Do the Matching and Normalize
cv::matchTemplate(img, templateImg, result, CV_TM_CCORR_NORMED);
cv::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
/// Localizing the best match with minMaxLoc
double minVal; double maxVal; cv::Point minLoc; cv::Point maxLoc;
cv::Point matchLoc;
for(;;) {
cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat());
matchLoc = maxLoc;
std::cout << "Max correlation=" << maxVal << std::endl;
if(maxVal < 0.8) {
break;
}
/// Show me what you got
cv::rectangle(img_display, matchLoc, cv::Point(matchLoc.x + templateImg.cols , matchLoc.y + templateImg.rows),
cv::Scalar::all(0), 2, 8, 0);
cv::rectangle(result, cv::Point(matchLoc.x - templateImg.cols/2 , matchLoc.y - templateImg.rows/2),
cv::Point(matchLoc.x + templateImg.cols/2 , matchLoc.y + templateImg.rows/2), cv::Scalar::all(0), 2, 8, 0);
cv::imshow("result", result);
cv::waitKey(0);
/// Fill the detected location with a rectangle of zero
cv::rectangle(result, cv::Point(matchLoc.x - templateImg.cols/2 , matchLoc.y - templateImg.rows/2),
cv::Point(matchLoc.x + templateImg.cols/2 , matchLoc.y + templateImg.rows/2), cv::Scalar::all(0), -1);
} while (maxVal > 0.9);
cv::imshow("result", result);
cv::imshow("img_display", img_display);
cv::waitKey(0);
return 0;
}
Die for-Schleife ist verantwortlich mehr als ein Marker zu finden und erkennen, ist es, ich versuche, es zu meinem Java-Code anzupassen, und ich bin immer eine Endlosschleife hier ist mein Code:
public void run(String inFile, String templateFile, String outFile, int match_method) {
System.out.println("\nRunning Template Matching");
Mat img = Highgui.imread(inFile);
Mat templ = Highgui.imread(templateFile);
///Create the result matrix
int result_cols = img.cols() - templ.cols() + 1;
int result_rows = img.rows() - templ.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
///Do the Matching and Normalize
Imgproc.matchTemplate(img, templ, result, match_method);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
Point matchLoc;
Point maxLoc;
Point minLoc;
MinMaxLocResult mmr;
boolean iterate = true;
while(iterate){
///Localizing the best match with minMaxLoc
mmr = Core.minMaxLoc(result);
matchLoc = mmr.maxLoc;
if(mmr.maxVal < 0.8)
{
iterate = false;
}
///Show me what you got
Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),
matchLoc.y + templ.rows()), new Scalar(0, 255, 0));
}
// Save the visualized detection.
System.out.println("Writing "+ outFile);
Highgui.imwrite(outFile, img);
}
I n otice, dass die Funktion minMaxLoc mehr Argumente in C++ als in Java hat, vielleicht ist das das Problem? Warum kann ich in Java nicht dasselbe Verhalten erreichen? Kann mir jemand helfen?
Vielen Dank im Voraus
Es half sehr, ich änderte den Code, den ich in Java hatte und jetzt funktioniert, hier ist es: http://pastebin.com/HXP9JaMN Vielen Dank! ;) – TiagoM
Ich merke, dass die Vorlage nicht funktioniert, um meine schwarzen Quadrate zu erkennen, ich muss mit @RobAu Lösung gehen ... – TiagoM
Das ist in Ordnung. Ihre Frage scheint eher das Problem der Endlosschleife mit dem Titel Opencv C++ zu Java - Template match zu lösen. Sie können hier im stackoverflow nach weiteren Fragen suchen, die mit der Übereinstimmung von Vorlagen oder dem Suchen von Quadraten oder Objekten in Bildern zusammenhängen. – sriram