Что такое шаблон OpenCV, соответствующий диапазону значений Max Min? Нужно использовать как theshold / c ++ / java

Я создаю простое приложение openCV, используя сопоставление с шаблоном, где мне нужно сравнить, найти маленькое изображение в большом изображении и вернуть результат как true (если совпадение найдено) или false (совпадения не найдено).

    Imgproc.matchTemplate(largeImage, smallImage, result, matchMethod);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());

MinMaxLocResult mmr = Core.minMaxLoc(result);

double minMaxValue = 1;
if (matchMethod== Imgproc.TM_SQDIFF || matchMethod== Imgproc.TM_SQDIFF_NORMED)
{
minMaxValue = mmr.minVal;
useMinThreshold = true;
}
else
{
minMaxValue = mmr.maxVal;
}

Теперь проблема заключается в принятии решения (true / false) с использованием этого minMaxValue. Я знаю, что два вышеупомянутых метода TM_SQDIFF и TM_SQDIFF_NORMED возвращают низкие значения, в то время как другие возвращают высокие значения, поэтому я могу иметь 2 разных порога и сравнить один из порогов (в зависимости от типа метода шаблона).

Поэтому было бы здорово, если бы кто-нибудь смог объяснить, что такое minVal и maxVal, которые возвращает MinMaxLocResult.

Это диапазон от 0 до 1?

Если да, то для метода шаблона типа Max значение 1 идеально подходит?

6

Решение

MinMaxLocResult не возвращается minVal а также maxVal спектр. minVal а также maxVal это только минимальные и максимальные баллы соответствия, которые можно увидеть в ссылка на сайт.

Структура MinMaxLocResult также имеет minLoc а также maxLoc свойства, которые имеют тип Point, давая соответствующие места. Учитывая, что вы используете TM_SQDIFF или же TM_SQDIFF_NORMED в качестве критерия соответствия наилучшим местом сопоставления будет mmr.minLoc,

Чтобы установить порог для обнаружения, вы можете объявить переменнуюdouble thresholdMatch и установить его значение экспериментально. если minVal < thresholdMatch, то можно сказать, что целевой объект обнаружен

9

Другие решения

Не нормализуйте результат, тогда он даст правильное значение, я имею в виду удалить эту строку

   Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
3

faithkОтвет превосходен, но вот некоторый реальный код, реализующий его по существу. Я добился хороших результатов с использованием 0.1 в качестве порога:

import lombok.val;
import org.opencv.core.*;
import org.springframework.core.io.ClassPathResource;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import static javax.imageio.ImageIO.read;
import static javax.imageio.ImageIO.write;
import static javax.swing.SwingUtilities.invokeAndWait;
import static org.opencv.core.CvType.CV_32FC1;
import static org.opencv.highgui.HighGui.imshow;
import static org.opencv.highgui.HighGui.waitKey;
import static org.opencv.imgcodecs.Imgcodecs.CV_LOAD_IMAGE_UNCHANGED;
import static org.opencv.imgcodecs.Imgcodecs.imdecode;
import static org.opencv.imgproc.Imgproc.*;

public class TemplateMatcher
{
static
{
// loadNativeOpenCVLibrary();
}

private static final int MATCH_METHOD = TM_SQDIFF_NORMED;

private static Mat BufferedImage2Mat(BufferedImage image) throws IOException
{
try (val byteArrayOutputStream = new ByteArrayOutputStream())
{
write(image, "jpg", byteArrayOutputStream);
byteArrayOutputStream.flush();
val matOfByte = new MatOfByte(byteArrayOutputStream.toByteArray());
return imdecode(matOfByte, CV_LOAD_IMAGE_UNCHANGED);
}
}

public static Point performTemplateMatching(BufferedImage bigImage, BufferedImage templateImage,
double detectionThreshold, boolean showMatch) throws IOException
{
val image = BufferedImage2Mat(bigImage);
val template = BufferedImage2Mat(templateImage);

// Create the result matrix
val result_cols = image.cols() - template.cols() + 1;
val result_rows = image.rows() - template.rows() + 1;
val result = new Mat(result_rows, result_cols, CV_32FC1);

// Do the matching
matchTemplate(image, template, result, MATCH_METHOD);

// Localize the best match
val minMaxLocResult = Core.minMaxLoc(result);

// / Show me what you got
val matchedLocation = minMaxLocResult.minLoc;
rectangle(image, matchedLocation, new Point(matchedLocation.x + template.cols(),
matchedLocation.y + template.rows()), new Scalar(0, 255, 0));

if (showMatch)
{
try
{
invokeAndWait(() -> imshow("Image Search", image));
} catch (InterruptedException | InvocationTargetException exception)
{
exception.printStackTrace();
}
waitKey();
}

// Determine whether this sub image has been found
val minVal = minMaxLocResult.minVal;
if (minVal < detectionThreshold)
{
return minMaxLocResult.maxLoc;
}

return null;
}

public static BufferedImage getBufferedImage(String classpathFile) throws IOException
{
val classPathResource = new ClassPathResource(classpathFile);
val filePath = classPathResource.getFile();
return read(filePath);
}
}
0
По вопросам рекламы [email protected]