use of com.seleniumtests.customexception.ImageSearchException in project seleniumRobot by bhecquet.
the class ImageDetector method detectExactZoneWithScale.
public void detectExactZoneWithScale(boolean scaleImage) {
Mat sceneImageMat = Imgcodecs.imread(sceneImage.getAbsolutePath(), Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
Mat objectImageMat = Imgcodecs.imread(objectImage.getAbsolutePath(), Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
List<TemplateMatchProperties> matches = Collections.synchronizedList(new ArrayList<>());
Map<Integer, Double> scaleSteps = new LinkedHashMap<>();
if (scaleImage) {
scaleSteps.put(100, Math.max(0.1, 0.6 - detectionThreshold));
scaleSteps.put(50, Math.max(0.1, 0.7 - detectionThreshold));
scaleSteps.put(25, Math.max(0.1, 0.8 - detectionThreshold));
} else {
scaleSteps.put(100, Math.max(0.1, 0.8 - detectionThreshold));
}
int currentStep = 100;
Set<Integer> computedScales = new HashSet<>();
while (currentStep >= 25) {
final double currentThreshold = scaleSteps.get(currentStep);
// first loop
Set<Integer> localScales = Collections.synchronizedSet(new HashSet<>());
if (currentStep == 100 && scaleImage) {
for (int scale = 200; scale < 1200; scale += currentStep) {
localScales.add(scale);
}
// no scaling requested, keep only 100%
} else if (currentStep == 100) {
localScales.add(1000);
} else {
if (matches.isEmpty()) {
throw new ImageSearchException("no matches");
}
for (TemplateMatchProperties tmpM : matches) {
if (tmpM.isActive()) {
localScales.add(tmpM.getMatchScale() - currentStep);
localScales.add(tmpM.getMatchScale() + currentStep);
}
}
}
// extract the matching from images, for each scale
extractMatching(sceneImageMat, objectImageMat, matches, computedScales, currentThreshold, localScales);
// shortcut if we find a very good match
double cleanThreshold = currentThreshold;
matches.sort((TemplateMatchProperties t1, TemplateMatchProperties t2) -> t1.getMatchValue().compareTo(t2.getMatchValue()));
// reverse the list as we want the first element to be the best match
Collections.reverse(matches);
if (!matches.isEmpty() && matches.get(0).getMatchValue() > 0.9) {
cleanThreshold = 0.9;
currentStep = Math.min(currentStep, 50);
}
currentStep = currentStep / 2;
// clean matches from too low matching values
for (TemplateMatchProperties t : matches) {
if (t.getMatchValue() < cleanThreshold) {
t.setActive(false);
}
}
// if scaling is not requested, stop here
if (!scaleImage) {
break;
}
}
// get the best match
matches.sort((TemplateMatchProperties t1, TemplateMatchProperties t2) -> t1.getMatchValue().compareTo(t2.getMatchValue()));
// reverse the list as we want the first element to be the best match
Collections.reverse(matches);
if (!matches.isEmpty()) {
TemplateMatchProperties bestMatch = matches.get(0);
if (bestMatch.getMatchValue() < 1 - detectionThreshold) {
throw new ImageSearchException(String.format("No match found for threshold %.2f, match found with value %.2f", 1 - detectionThreshold, bestMatch.getMatchValue()));
}
detectedRectangle = new Rectangle((int) (bestMatch.getMatchLoc().x / bestMatch.getDoubleScale()), (int) (bestMatch.getMatchLoc().y / bestMatch.getDoubleScale()), (int) (objectImageMat.rows() / bestMatch.getDoubleScale()), (int) (objectImageMat.cols() / bestMatch.getDoubleScale()));
if (debug) {
try {
Imgproc.rectangle(sceneImageMat, new Point(detectedRectangle.x, detectedRectangle.y), new Point(detectedRectangle.x + detectedRectangle.width, detectedRectangle.y + detectedRectangle.height), new Scalar(0, 255, 0));
showResultingPicture(sceneImageMat);
} catch (IOException e) {
}
}
rotationAngle = 0;
sizeRatio = detectedRectangle.width / (double) objectImageMat.cols();
} else {
throw new ImageSearchException("no matching has been found");
}
}
use of com.seleniumtests.customexception.ImageSearchException in project seleniumRobot by bhecquet.
the class ImageDetector method detectExactZone2.
/**
* This method uses template matching for exact comparison
* It means that no resizing or rotation can be detected
* @throws IOException
*/
private TemplateMatchProperties detectExactZone2(Mat sceneImageMat, Mat objectImageMat, int scale, double threshold) {
// with this match method, higher value is better. TM_SQDIFF would imply lower as better
int matchMethod = Imgproc.TM_CCOEFF_NORMED;
MinMaxLocResult mmr = getBestTemplateMatching(matchMethod, sceneImageMat, objectImageMat);
if (mmr.maxVal < threshold) {
throw new ImageSearchException("match not found");
}
return new TemplateMatchProperties(mmr.maxLoc, mmr.maxVal, scale);
}
use of com.seleniumtests.customexception.ImageSearchException in project seleniumRobot by bhecquet.
the class ImageDetector method extractMatching.
/**
* Extract matching in parallel
* @param sceneImageMat
* @param objectImageMat
* @param matches
* @param computedScales
* @param currentThreshold
* @param localScales
*/
private void extractMatching(Mat sceneImageMat, Mat objectImageMat, List<TemplateMatchProperties> matches, Set<Integer> computedScales, final double currentThreshold, Set<Integer> localScales) {
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
for (int scale : localScales) {
if (computedScales.contains(scale)) {
continue;
}
computedScales.add(scale);
// resize to scale factor
final int localScale = scale;
Size sz = new Size(sceneImageMat.cols() * scale / 1000.0, sceneImageMat.rows() * localScale / 1000.0);
// skip if resized image is smaller than object
if (sz.width < objectImageMat.cols() || sz.height < objectImageMat.rows()) {
continue;
}
executorService.submit(() -> {
Mat resizeSceneImageMat = new Mat();
Imgproc.resize(sceneImageMat, resizeSceneImageMat, sz);
try {
TemplateMatchProperties match = detectExactZone2(resizeSceneImageMat, objectImageMat, localScale, currentThreshold);
matches.add(match);
} catch (ImageSearchException e) {
// no match found
}
});
}
executorService.shutdown();
try {
executorService.awaitTermination(10, TimeUnit.SECONDS);
} catch (Exception e) {
logger.info("Could not compute scale within 10 seconds", e);
Thread.currentThread().interrupt();
}
}
use of com.seleniumtests.customexception.ImageSearchException in project seleniumRobot by bhecquet.
the class TestPictureElement method testDoubleClickOnPicture.
public void testDoubleClickOnPicture() {
try {
DriverTestPageWithoutFixedPattern.picture.doubleClickAt(0, -20);
} catch (ImageSearchException e) {
throw new SkipException("Image not found, we may be on screenless slave", e);
}
// in case of browser slowness
WaitHelper.waitForMilliSeconds(500);
Assert.assertEquals(DriverTestPageWithoutFixedPattern.logoText.getValue(), "double click ff logo");
}
use of com.seleniumtests.customexception.ImageSearchException in project seleniumRobot by bhecquet.
the class TestPictureElement method testClickOnGooglePictureFromFile.
/**
* test correction of issue #134 by clicking on element defined by a File object
*/
public void testClickOnGooglePictureFromFile() {
try {
DriverTestPageWithoutFixedPattern.googlePictureWithFile.click();
} catch (ImageSearchException e) {
throw new SkipException("Image not found, we may be on screenless slave", e);
}
// in case of browser slowness
WaitHelper.waitForMilliSeconds(500);
Assert.assertEquals(DriverTestPageWithoutFixedPattern.textElement.getValue(), "image");
}
Aggregations