gpt4 book ai didi

java - OpenCV - C++ 到 Java - 模板匹配

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:34:14 29 4
gpt4 key购买 nike

正如我在此处询问 Detect Marker Position in 2D image 时,我正在尝试检测图像中的多个正方形(标记)

有人向我展示了一个 C++ 解决方案,这里是:

#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;
}

for 循环负责找到多个标记并检测它,我正在尝试使其适应我的 java 代码,但我得到了一个无限循环,这是我的代码:

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);

}

我注意到函数 minMaxLoc 在 C++ 中比在 Java 中有更多的参数,也许这就是问题所在?为什么我无法在 Java 中获得相同的行为,有人可以帮助我吗?

提前谢谢你

最佳答案

正如 cyriel 所说,您忘记为最大位置填充零,因此您得到了无限循环。可能是他忘了向你解释,

   for each iteration
find the max location
check if max value is greater than desired threshold
if true
show me what is max
else
break // not found anything that matches
make the existing max to be zero and continue to search for other max// you forgot this and hence infinite loop
end

要更深入地了解问题,你可以在c++代码中注释下面几行并运行它,你会遇到类似的问题。 (这里 cv::Scalar::all(0),-1 args 表示用 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);

希望对您有所帮助。

关于java - OpenCV - C++ 到 Java - 模板匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29851708/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com